@ningboyz/vcomponent
Advanced tools
| <script setup lang="ts"> | ||
| import { nextTick, ref } from "vue"; | ||
| import { VxeGrid, VxeGridDefines, VxeGridInstance, VxeGridPropTypes } from "vxe-table"; | ||
| import { VxeModal, VxeButton, VxeInputDefines } from "vxe-pc-ui"; | ||
| import { ICustomK8kmProps, ICustomK8kmRef } from "./types"; | ||
| import { IPzptK8kmResponse } from "@ningboyz/types/src/pzpt"; | ||
| import _ from "lodash"; | ||
| import { AssertUtil } from "@ningboyz/utils"; | ||
| import MessageUtil from "../../messageUtil/MessageUtil"; | ||
| import K8kmTreeUtil from "./K8kmTreeUtil"; | ||
| const props = defineProps<ICustomK8kmProps>(); | ||
| const gridRef = ref<VxeGridInstance>(); | ||
| const emits = defineEmits<{ | ||
| (e: "ok", k8km: IPzptK8kmResponse): void; | ||
| }>(); | ||
| const width = ref<number>(620); | ||
| const height = ref<number>(window.innerHeight * 0.7); | ||
| const searchText = ref<string>(""); | ||
| const visible = ref<boolean>(false); | ||
| const getColumns = () => { | ||
| const columns: VxeGridPropTypes.Columns<IPzptK8kmResponse> = []; | ||
| const k8kmKmmc: VxeGridPropTypes.Column = { | ||
| title: "科目名称", | ||
| field: "label", | ||
| treeNode: true | ||
| }; | ||
| columns.push(k8kmKmmc); | ||
| return columns; | ||
| }; | ||
| /** | ||
| * 全部展开 | ||
| * 全部收缩 | ||
| */ | ||
| const handleAllExpandClick = (expand: boolean) => { | ||
| const $grid = gridRef.value; | ||
| if (_.isNil($grid)) { | ||
| return; | ||
| } | ||
| $grid.setAllTreeExpand(expand); | ||
| }; | ||
| /** | ||
| * 搜索框进行搜索 | ||
| */ | ||
| const handleSearchTextChange = (_event: VxeInputDefines.ChangeEventParams) => {}; | ||
| /** | ||
| * 确定按钮点击 | ||
| */ | ||
| const handleOkClick = async () => { | ||
| try { | ||
| const $grid = AssertUtil.core.checkNotNil(gridRef.value, "请选择科目"); | ||
| const recrod = $grid.getCurrentRecord() as IPzptK8kmResponse | undefined | null; | ||
| const k8km = AssertUtil.core.checkNotNil(recrod, "请选择科目"); | ||
| //判断是否为最底级科目 | ||
| if (!_.isNil(k8km.children) && _.isArray(k8km.children) && k8km.children.length > 0) { | ||
| throw new Error(`科目【${k8km.k8kmKmmc}】不是明细科目,不允许选择!`); | ||
| } | ||
| //清除选择的科目 | ||
| await $grid.clearCurrentRow(); | ||
| visible.value = false; | ||
| emits("ok", k8km); | ||
| } catch (e: any) { | ||
| MessageUtil.showError(e.message); | ||
| } | ||
| }; | ||
| const handleEnterDown = () => { | ||
| try { | ||
| const record = gridRef.value?.getCurrentRecord(); | ||
| debugger | ||
| if (!_.isNil(record) && (_.isNil(record.children) || record.children === 0)) { | ||
| visible.value = false; | ||
| emits("ok", record as IPzptK8kmResponse); | ||
| } | ||
| } catch (e: any) { | ||
| MessageUtil.showError(e.message); | ||
| } | ||
| }; | ||
| const handleKeyDown = (e: VxeGridDefines.KeydownEventParams) => { | ||
| //@ts-ignore | ||
| switch (e.$event.key) { | ||
| case "Enter": | ||
| handleEnterDown(); | ||
| break; | ||
| default: | ||
| break; | ||
| } | ||
| }; | ||
| /** | ||
| * model打开 | ||
| */ | ||
| const open = async (k8kmKmbm?: string) => { | ||
| visible.value = true; | ||
| await nextTick(); | ||
| await gridRef.value?.focus(); | ||
| if (_.isNil(k8kmKmbm) || _.isEmpty(k8kmKmbm) || props.listK8km.length === 0 || props.treeK8km.length === 0) { | ||
| return; | ||
| } | ||
| nextTick(() => { | ||
| const treeUtil = new K8kmTreeUtil(props.listK8km, props.treeK8km); | ||
| const a = treeUtil.findByBm(k8kmKmbm); | ||
| if(!_.isNil(a)){ | ||
| gridRef.value?.setCurrentRow(a); | ||
| } | ||
| }); | ||
| }; | ||
| defineExpose<ICustomK8kmRef>({ | ||
| open | ||
| }); | ||
| </script> | ||
| <template> | ||
| <vxe-modal :id="props.id" v-model="visible" :width="width" :height="height" show-footer resize remember :mask="false" show-maximize dblclick-zoom :esc-closable="false"> | ||
| <template #title>科目选择</template> | ||
| <template #default> | ||
| <vxe-grid | ||
| ref="gridRef" | ||
| border="none" | ||
| height="auto" | ||
| show-overflow | ||
| :show-header="false" | ||
| :data="props.treeK8km" | ||
| :columns="getColumns()" | ||
| cell-class-name="pzpt-k8km-select-cell" | ||
| :tree-config="{ | ||
| rowField: 'k8kmKmid', | ||
| parentField: 'parentID', | ||
| childrenField: 'children', | ||
| indent: 32, | ||
| trigger: 'row' | ||
| }" | ||
| :row-config="{ | ||
| isHover: true, | ||
| isCurrent: true, | ||
| keyField: 'k8kmKmid', | ||
| height: 32 | ||
| }" | ||
| :keyboard-config="{ | ||
| isArrow: true, | ||
| isEnter: true, | ||
| isBack: true | ||
| }" | ||
| @keydown="handleKeyDown"> | ||
| <template #toolbar> | ||
| <vxe-input v-model="searchText" placeholder="请输入科目编码或科目名称" type="search" clearable style="width: 100%" @change="handleSearchTextChange"></vxe-input> | ||
| </template> | ||
| </vxe-grid> | ||
| </template> | ||
| <template #footer> | ||
| <div style="display: flex; justify-content: space-between"> | ||
| <div> | ||
| <vxe-button | ||
| size="mini" | ||
| content="展开" | ||
| status="primary" | ||
| icon="vxe-icon-arrows-down" | ||
| @click=" | ||
| () => { | ||
| handleAllExpandClick(true); | ||
| } | ||
| "></vxe-button> | ||
| <vxe-button | ||
| size="mini" | ||
| content="收缩" | ||
| status="primary" | ||
| icon="vxe-icon-arrow-right" | ||
| @click=" | ||
| () => { | ||
| handleAllExpandClick(false); | ||
| } | ||
| "></vxe-button> | ||
| <vxe-button size="mini" status="primary" content="新增" icon="vxe-icon-add"></vxe-button> | ||
| <vxe-button size="mini" status="warning" content="修改" icon="vxe-icon-edit"></vxe-button> | ||
| <vxe-button size="mini" status="error" content="删除" icon="vxe-icon-delete"></vxe-button> | ||
| </div> | ||
| <div> | ||
| <vxe-button size="mini" status="primary" content="确定" icon="vxe-icon-save" @click="handleOkClick"></vxe-button> | ||
| <vxe-button size="mini" content="取消" icon="vxe-icon-warning-circle"></vxe-button> | ||
| </div> | ||
| </div> | ||
| </template> | ||
| </vxe-modal> | ||
| </template> | ||
| <style scoped lang="scss"></style> | ||
| <style lang="scss"> | ||
| .pzpt-k8km-select-cell { | ||
| cursor: pointer; | ||
| } | ||
| </style> |
| import { IPzptK8kmResponse } from "@ningboyz/types/src/pzpt"; | ||
| import _ from "lodash"; | ||
| class K8kmTreeUtil { | ||
| private listData: IPzptK8kmResponse[]; | ||
| private treeData: IPzptK8kmResponse[]; | ||
| constructor(listData: IPzptK8kmResponse[], treeData: IPzptK8kmResponse[]) { | ||
| console.log(listData); | ||
| console.log(treeData); | ||
| this.listData = listData; | ||
| this.treeData = treeData; | ||
| console.log(this.treeData); | ||
| } | ||
| /** | ||
| * 根据k8kmKmid查找 | ||
| * @param k8kmKmid | ||
| * @returns | ||
| */ | ||
| public findById(k8kmKmid: number) { | ||
| for (let i = 0; i < this.listData.length; i++) { | ||
| const data = this.listData[i]; | ||
| if (data.k8kmKmid === k8kmKmid) { | ||
| return data; | ||
| } | ||
| } | ||
| } | ||
| /** | ||
| * 根据k8kmKmbm查找 | ||
| * @param k8kmKmid | ||
| * @returns | ||
| */ | ||
| public findByBm(k8kmKmbm: string) { | ||
| for (let i = 0; i < this.listData.length; i++) { | ||
| const data = this.listData[i]; | ||
| if (data.k8kmKmbm === k8kmKmbm) { | ||
| return data; | ||
| } | ||
| } | ||
| } | ||
| /** | ||
| * 根据k8kmKmid查找所有父级 | ||
| * @param k8kmKmid | ||
| */ | ||
| public findParentsById(k8kmKmid: number) { | ||
| // const result: IPzptK8kmResponse[] = []; | ||
| const k8km = this.findById(k8kmKmid); | ||
| if (_.isNil(k8km)) { | ||
| return; | ||
| } | ||
| const parent = this.findById(k8km.parentID); | ||
| if (!_.isNil(parent)) { | ||
| } | ||
| } | ||
| public findParentsByK8kmObj(k8km: IPzptK8kmResponse) { | ||
| return this.findParentsById(k8km.k8kmKmid); | ||
| } | ||
| } | ||
| export default K8kmTreeUtil; |
| import { IPzptK8kmResponse } from "@ningboyz/types/src/pzpt"; | ||
| export interface ICustomK8kmProps { | ||
| id: string; | ||
| listK8km: IPzptK8kmResponse[]; | ||
| treeK8km: IPzptK8kmResponse[]; | ||
| } | ||
| export interface ICustomK8kmRef { | ||
| open: (k8kmKmmb?: string) => void; | ||
| } |
| <script setup lang="ts"> | ||
| import { onMounted, reactive, ref } from "vue"; | ||
| import { VxeModal } from "vxe-pc-ui"; | ||
| const visible = defineModel<boolean>("visible", { required: true, type: Boolean, default: false }); | ||
| </script> | ||
| <template> | ||
| <vxe-modal title="凭证"></vxe-modal> | ||
| </template> | ||
| <style scoped lang="scss"></style> |
| <script setup lang="ts"> | ||
| import { VxeInput, VxeInputDefines } from "vxe-pc-ui"; | ||
| import { ICustomNumberProps } from "./types"; | ||
| import { TEditMode } from "@ningboyz/types/src/enums"; | ||
| import { NumberUtil } from "@ningboyz/utils"; | ||
| import { computed } from "vue"; | ||
| import _ from "lodash"; | ||
| const props = defineProps<ICustomNumberProps>(); | ||
| const money = defineModel<string>("money", { required: false, type: String, default: "" }); | ||
| const emits = defineEmits<{ | ||
| (e: "change", value: string): void; | ||
| }>(); | ||
| const text = computed(() => { | ||
| if (_.isNil(money.value)) { | ||
| return ""; | ||
| } | ||
| const value = NumberUtil.createBN(money.value); | ||
| if (value.isNaN()) { | ||
| return ""; | ||
| } | ||
| return value.toFormat(2); | ||
| }); | ||
| /** | ||
| * 金额改变 | ||
| */ | ||
| const handleChange = (event: VxeInputDefines.ChangeEventParams) => { | ||
| emits("change", event.value); | ||
| }; | ||
| </script> | ||
| <template> | ||
| <vxe-input | ||
| v-if="props.editMode === TEditMode.emInsert" | ||
| class-name="pzpt-custom-number" | ||
| v-model="money" | ||
| :placeholder="props.placeholder" | ||
| type="float" | ||
| digits="2" | ||
| :controls="false" | ||
| align="right" | ||
| @change="handleChange"></vxe-input> | ||
| <div v-if="props.editMode === TEditMode.emBrowse" class="pzpt-custom-number pzpt-custom-number-div">{{ text }}</div> | ||
| </template> | ||
| <style scoped lang="scss"> | ||
| .pzpt-custom-number { | ||
| width: 100% !important; | ||
| height: 100% !important; | ||
| box-sizing: border-box !important; | ||
| border-radius: 0px !important; | ||
| border: 1px solid transparent !important; | ||
| } | ||
| .pzpt-custom-number-div { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: flex-end; | ||
| padding-right: 8px; | ||
| } | ||
| .is--active { | ||
| border: 1px solid #409eff !important; | ||
| } | ||
| </style> |
| <!-- 摘要组件 --> | ||
| <script setup lang="ts"> | ||
| import { VxeTextarea } from "vxe-pc-ui"; | ||
| import { ICustomPrecisProps } from "./types"; | ||
| import { TEditMode } from "@ningboyz/types/src/enums"; | ||
| const props = defineProps<ICustomPrecisProps>(); | ||
| const precis = defineModel<string | undefined>("precis", { required: true, type: String, default: "" }); | ||
| </script> | ||
| <template> | ||
| <vxe-textarea v-if="props.editMode === TEditMode.emInsert" v-model="precis" placeholder="摘要" resize="none" class-name="custom_pzpt_percis_textarea"></vxe-textarea> | ||
| <div v-if="props.editMode === TEditMode.emBrowse" class="custom_pzpt_percis_div">{{ precis }}</div> | ||
| </template> | ||
| <style scoped lang="scss"></style> | ||
| <style lang="scss"> | ||
| .custom_pzpt_percis_textarea { | ||
| width: 100% !important; | ||
| height: 100% !important; | ||
| box-sizing: border-box !important; | ||
| > textarea { | ||
| border-radius: 0px !important; | ||
| border: 1px solid transparent; | ||
| } | ||
| } | ||
| .custom_pzpt_percis_div { | ||
| width: 100% !important; | ||
| height: 100% !important; | ||
| box-sizing: border-box !important; | ||
| white-space: pre-wrap; | ||
| overflow: hidden; | ||
| scrollbar-width: none; | ||
| } | ||
| </style> |
| <!-- 会计科目选择 --> | ||
| <script setup lang="ts"> | ||
| import { ICustomSubjectsProps, ICustomVoucherData } from "./types"; | ||
| import CustomK8km from "../CustomK8km/CustomK8km.vue"; | ||
| import { computed, ref } from "vue"; | ||
| import { ICustomK8kmRef } from "../CustomK8km/types"; | ||
| import { IPzptK8kmResponse } from "@ningboyz/types/src/pzpt"; | ||
| import { VxeInputDefines } from "vxe-pc-ui"; | ||
| import _ from "lodash"; | ||
| const props = defineProps<ICustomSubjectsProps>(); | ||
| const subjectIndex = defineModel<number | undefined>("subjectIndex", { required: false, type: Number, default: undefined }); | ||
| const subjectName = defineModel<string | undefined>("subjectName", { required: false, type: String, default: undefined }); | ||
| const subjectNameFull = defineModel<string | undefined>("subjectNameFull", { required: false, type: String, default: undefined }); | ||
| const emits = defineEmits<{ | ||
| (e: "k8kmOpen"): void; | ||
| (e: "k8kmClose", data: ICustomVoucherData): void; | ||
| }>(); | ||
| const k8kmRef = ref<ICustomK8kmRef>(); | ||
| const text = computed(() => { | ||
| const k8km = props.listK8km.find((u) => u.k8kmKmid === subjectIndex.value); | ||
| if (!_.isNil(k8km)) { | ||
| return `${k8km?.k8kmKmmc}_${k8km?.k8kmFull}`; | ||
| } | ||
| }); | ||
| const inputText = ref<string>(""); | ||
| const handleIconClick = () => { | ||
| k8kmRef.value?.open(inputText.value); | ||
| emits("k8kmOpen"); | ||
| }; | ||
| const handleK8kmOk = (k8km: IPzptK8kmResponse) => { | ||
| subjectIndex.value = k8km.k8kmKmid; | ||
| subjectName.value = k8km.k8kmKmmc; | ||
| subjectNameFull.value = `${k8km.k8kmKmmc}_${k8km.k8kmFull}`; | ||
| emits("k8kmClose", props.row); | ||
| }; | ||
| const isNumber = (value: string) => { | ||
| var pattern = /^\d+$/; | ||
| return pattern.test(value); | ||
| }; | ||
| const handleInputEnterDown = (e: VxeInputDefines.KeydownEventParams) => { | ||
| if (e.$event.key === "Enter") { | ||
| let k8kmKmbm = ""; | ||
| if (isNumber(inputText.value)) { | ||
| k8kmKmbm = inputText.value; | ||
| } | ||
| k8kmRef.value?.open(k8kmKmbm); | ||
| emits("k8kmOpen"); | ||
| } | ||
| }; | ||
| const handleInputChange = (e: VxeInputDefines.ChangeEventParams) => { | ||
| inputText.value = e.value; | ||
| }; | ||
| </script> | ||
| <template> | ||
| <vxe-input v-model="text" placeholder="会计科目" style="width: 100%" @keydown="handleInputEnterDown" class-name="pzpt-custom-subjects" @change="handleInputChange"> | ||
| <template #suffix> | ||
| <vxe-icon name="search" @click="handleIconClick" style="cursor: pointer" /> | ||
| </template> | ||
| </vxe-input> | ||
| <custom-k8km ref="k8kmRef" :list-k8km="props.listK8km" :tree-k8km="props.treeK8km" @ok="handleK8kmOk" :id="props.id" /> | ||
| </template> | ||
| <style scoped lang="scss"> | ||
| .pzpt-custom-subjects { | ||
| width: 100% !important; | ||
| height: 100% !important; | ||
| box-sizing: border-box !important; | ||
| border-radius: 0px !important; | ||
| border: 1px solid transparent !important; | ||
| } | ||
| .is--active { | ||
| border: 1px solid #409eff !important; | ||
| } | ||
| </style> |
| <script setup lang="ts"> | ||
| import { onMounted, reactive, ref } from 'vue' | ||
| </script> | ||
| <template> | ||
| <div class="custom-subjects-detail">vue3</div> | ||
| </template> | ||
| <style scoped lang="scss"> | ||
| </style> |
| 凭证界面组件 1、摘要组件 2、科目选择组件 3、金额组件 | ||
| <script setup lang="ts"> | ||
| import { VxeGrid, VxeGridPropTypes, VxeTableInstance } from "vxe-table"; | ||
| import { ref, nextTick } from "vue"; | ||
| import { IdUtil, NumberUtil } from "@ningboyz/utils"; | ||
| //摘要组件 | ||
| import CustomPrecis from "./CustomPrecis.vue"; | ||
| //会计科目组件 | ||
| import CustomSubjects from "./CustomSubjects.vue"; | ||
| //金额组件 | ||
| import CustomNumber from "./CustomNumber.vue"; | ||
| import { ICustomVoucherData, ICustomVoucherRef } from "./types"; | ||
| import { TPzpt } from "@ningboyz/types"; | ||
| import _ from "lodash"; | ||
| import { TEditMode } from "@ningboyz/types/src/enums"; | ||
| const data = ref<ICustomVoucherData[]>([]); | ||
| const gridRef = ref<VxeTableInstance<any>>(); | ||
| const listK8km = ref<TPzpt.IPzptK8kmResponse[]>([]); | ||
| const treeK8km = ref<TPzpt.IPzptK8kmResponse[]>([]); | ||
| const getColumns = () => { | ||
| const columns: VxeGridPropTypes.Columns<ICustomVoucherData> = []; | ||
| const precis: VxeGridPropTypes.Column<ICustomVoucherData> = { | ||
| field: "precis", | ||
| title: "摘要", | ||
| width: 360, | ||
| headerAlign: "center", | ||
| editRender: { autofocus: ".vxe-textarea--inner" }, | ||
| slots: { default: "default_precis", edit: "edit_precis", footer: "footer_precis" } | ||
| }; | ||
| const subject: VxeGridPropTypes.Column = { | ||
| field: "subject", | ||
| title: "会计科目", | ||
| headerAlign: "center", | ||
| editRender: { autofocus: ".vxe-input--inner" }, | ||
| slots: { default: "default_subject", edit: "edit_subject", footer: "footer_subject" } | ||
| }; | ||
| const debit: VxeGridPropTypes.Column = { | ||
| field: "debit", | ||
| title: "借方金额", | ||
| width: 200, | ||
| headerAlign: "center", | ||
| editRender: { autofocus: ".vxe-input--inner" }, | ||
| slots: { default: "default_debit", edit: "edit_debit", footer: "footer_debit" } | ||
| }; | ||
| const credit: VxeGridPropTypes.Column = { | ||
| field: "credit", | ||
| title: "贷方金额", | ||
| width: 200, | ||
| headerAlign: "center", | ||
| editRender: { autofocus: ".vxe-input--inner" }, | ||
| slots: { default: "default_credit", edit: "edit_credit", footer: "footer_credit" } | ||
| }; | ||
| columns.push(precis); | ||
| columns.push(subject); | ||
| columns.push(debit); | ||
| columns.push(credit); | ||
| return columns; | ||
| }; | ||
| /** | ||
| * 表尾数据 | ||
| */ | ||
| const footerData = () => { | ||
| const tableData = gridRef.value?.getTableData(); | ||
| const result = [{ precis: "合计", debit: "0.00", credit: "0.00" }]; | ||
| if (_.isNil(tableData)) { | ||
| return result; | ||
| } | ||
| if (_.isNil(tableData.fullData)) { | ||
| return result; | ||
| } | ||
| const debitSum = NumberUtil.plusObjArray2Number(tableData.fullData, "debit"); | ||
| const creditSum = NumberUtil.plusObjArray2Number(tableData.fullData, "credit"); | ||
| return [{ precis: "合计", debit: debitSum, credit: creditSum }]; | ||
| }; | ||
| /** | ||
| * k8km选择框打开时,表格获失去焦点 | ||
| */ | ||
| const handleK8kmOpen = () => { | ||
| gridRef.value?.blur(); | ||
| }; | ||
| /** | ||
| * k8km选择框关闭时,表格获取焦点 | ||
| */ | ||
| const handleK8kmClose = (data: ICustomVoucherData) => { | ||
| gridRef.value?.focus(); | ||
| const column = gridRef.value?.getColumnByField("debit"); | ||
| if (!_.isNil(column)) { | ||
| gridRef.value?.setEditRow(data, column); | ||
| } | ||
| }; | ||
| const handleNumberChange = (value: string, row: ICustomVoucherData, fs: "credit" | "debit") => { | ||
| if (_.isEmpty(value)) { | ||
| return; | ||
| } | ||
| const val = NumberUtil.createBN(value); | ||
| if (val.isNaN() || val.isZero()) { | ||
| return; | ||
| } | ||
| if (fs === "credit" && !_.isEmpty(row.debit)) { | ||
| row.debit = ""; | ||
| } | ||
| if (fs === "debit" && !_.isEmpty(row.credit)) { | ||
| row.credit = ""; | ||
| } | ||
| gridRef.value?.setRow(row); | ||
| }; | ||
| const init = async (lk8km: TPzpt.IPzptK8kmResponse[]) => { | ||
| lk8km.forEach((element) => { | ||
| element.label = element.k8kmKmbm + element.k8kmKmmc; | ||
| }); | ||
| const dataSource: ICustomVoucherData[] = []; | ||
| for (let i = 0; i < 6; i++) { | ||
| const item: ICustomVoucherData = { | ||
| id: IdUtil.getUUID() | ||
| }; | ||
| dataSource.push(item); | ||
| } | ||
| gridRef.value?.loadData(dataSource); | ||
| listK8km.value = lk8km; | ||
| treeK8km.value = TPzpt.TPzptK8kmResponse.toTree(_.cloneDeep(lk8km)); | ||
| await nextTick(); | ||
| gridRef.value?.focus(); | ||
| }; | ||
| defineExpose<ICustomVoucherRef>({ | ||
| init | ||
| }); | ||
| </script> | ||
| <template> | ||
| <VxeGrid | ||
| ref="gridRef" | ||
| height="396" | ||
| border | ||
| :data="data" | ||
| :columns="getColumns()" | ||
| show-footer | ||
| show-overflow | ||
| show-footer-overflow | ||
| show-header-overflow | ||
| resizable | ||
| cell-class-name="pzpt_custom_voucher_cell" | ||
| footer-cell-class-name="pzpt_custom_voucher_footer_cell" | ||
| :footer-method="footerData" | ||
| :row-config="{ | ||
| height: 50 | ||
| }" | ||
| :edit-config="{ | ||
| trigger: 'click', | ||
| mode: 'row' | ||
| }" | ||
| :keyboard-config="{ | ||
| isEdit: true, | ||
| isArrow: false, | ||
| isEnter: true, | ||
| enterToTab: true | ||
| }" | ||
| :mouse-config="{ | ||
| selected: true | ||
| }"> | ||
| <template #default_precis="{ row }: { row: ICustomVoucherData }"> | ||
| <CustomPrecis v-model:precis="row.precis" :edit-mode="TEditMode.emBrowse" /> | ||
| </template> | ||
| <template #edit_precis="{ row }: { row: ICustomVoucherData }"> | ||
| <CustomPrecis v-model:precis="row.precis" :edit-mode="TEditMode.emInsert" /> | ||
| </template> | ||
| <template #default_subject="{ row }: { row: ICustomVoucherData }"> | ||
| {{ row.subjectFullName }} | ||
| </template> | ||
| <template #edit_subject="{ row }: { row: ICustomVoucherData }"> | ||
| <CustomSubjects | ||
| :id="row.id" | ||
| :row="row" | ||
| v-model:subject-index="row.subjectIndex" | ||
| v-model:subject-name="row.subjectName" | ||
| v-model:subject-name-full="row.subjectFullName" | ||
| :list-k8km="listK8km" | ||
| :tree-k8km="treeK8km" | ||
| @k8km-open="handleK8kmOpen" | ||
| @k8km-close="handleK8kmClose" /> | ||
| </template> | ||
| <template #default_debit="{ row }: { row: ICustomVoucherData }"> | ||
| <CustomNumber v-model:money="row.debit" placeholder="借方金额" :edit-mode="TEditMode.emBrowse" /> | ||
| </template> | ||
| <template #edit_debit="{ row }: { row: ICustomVoucherData }"> | ||
| <CustomNumber v-model:money="row.debit" placeholder="借方金额" :edit-mode="TEditMode.emInsert" @change="(value:string)=>{handleNumberChange(value, row, 'debit')}" /> | ||
| </template> | ||
| <template #default_credit="{ row }: { row: ICustomVoucherData }"> | ||
| <CustomNumber v-model:money="row.credit" placeholder="贷方金额" :edit-mode="TEditMode.emBrowse" /> | ||
| </template> | ||
| <template #edit_credit="{ row }: { row: ICustomVoucherData }"> | ||
| <CustomNumber v-model:money="row.credit" placeholder="贷方金额" :edit-mode="TEditMode.emInsert" @change="(value:string)=>{handleNumberChange(value, row, 'credit')}" /> | ||
| </template> | ||
| <!-- 摘要表尾合计 --> | ||
| <template #footer_precis="{ row }: { row: ICustomVoucherData }"> | ||
| <div style="text-align: center">{{ row.precis }}</div> | ||
| </template> | ||
| <!-- 科目表尾合计 --> | ||
| <template #footer_subject="{ row }: { row: ICustomVoucherData }"> | ||
| <div v-if="!_.isNil(row.credit) && !_.isNil(row.debit) && !NumberUtil.minusItem2BN(row.credit, row.debit).isZero()" style="text-align: center"> | ||
| 借方金额({{ NumberUtil.formatNumber(row.debit, { decimalPlaces: 2 }) }}) - 贷方金额({{ NumberUtil.formatNumber(row.credit, { decimalPlaces: 2 }) }}) = | ||
| {{ NumberUtil.minusItem2Format(row.debit, row.credit) }} | ||
| </div> | ||
| </template> | ||
| <!-- 借方表尾合计 --> | ||
| <template #footer_debit="{ row }: { row: ICustomVoucherData }"> | ||
| <div style="text-align: right" v-if="!_.isNil(row.debit)">{{ NumberUtil.formatNumber(row.debit, { decimalPlaces: 2 }) }}</div> | ||
| </template> | ||
| <!-- 贷方表尾合计 --> | ||
| <template #footer_credit="{ row }: { row: ICustomVoucherData }"> | ||
| <div style="text-align: right" v-if="!_.isNil(row.credit)">{{ NumberUtil.formatNumber(row.credit, { decimalPlaces: 2 }) }}</div> | ||
| </template> | ||
| </VxeGrid> | ||
| </template> | ||
| <style lang="scss"> | ||
| .pzpt_custom_voucher_cell { | ||
| > div { | ||
| width: 100% !important; | ||
| height: 100% !important; | ||
| padding: 0 1px 1px 0 !important; | ||
| box-sizing: border-box !important; | ||
| } | ||
| } | ||
| .pzpt_custom_voucher_footer_cell { | ||
| width: 100%; | ||
| > div { | ||
| > span { | ||
| width: 100%; | ||
| } | ||
| } | ||
| } | ||
| </style> |
| /** | ||
| * 凭证类型组件 | ||
| */ | ||
| import { TPzpt } from "@ningboyz/types"; | ||
| import { TEditMode } from "@ningboyz/types/src/enums"; | ||
| import { IPzptK8kmResponse } from "@ningboyz/types/src/pzpt"; | ||
| /** | ||
| * 凭证组件props | ||
| */ | ||
| export interface ICustomVoucherProps {} | ||
| export interface ICustomVoucherRef { | ||
| init: (listK8km: TPzpt.IPzptK8kmResponse[]) => Promise<void>; | ||
| } | ||
| /** | ||
| * 摘要组件props | ||
| */ | ||
| export interface ICustomPrecisProps { | ||
| editMode: TEditMode; | ||
| } | ||
| /** | ||
| * 会计科目props | ||
| */ | ||
| export interface ICustomSubjectsProps { | ||
| id: string; | ||
| row: ICustomVoucherData; | ||
| listK8km: TPzpt.IPzptK8kmResponse[]; | ||
| treeK8km: TPzpt.IPzptK8kmResponse[]; | ||
| } | ||
| export interface ICustomSubjectsState { | ||
| k8km: IPzptK8kmResponse | undefined; | ||
| } | ||
| /** | ||
| * 金额组件 | ||
| */ | ||
| export interface ICustomNumberProps { | ||
| editMode: TEditMode; | ||
| placeholder: string; | ||
| } | ||
| export interface ICustomVoucherData { | ||
| id: string; | ||
| //摘要 | ||
| precis?: string; | ||
| //科目id | ||
| subjectIndex?: number; | ||
| //科目名称 | ||
| subjectName?: string; | ||
| //科目全名 | ||
| subjectFullName?: string; | ||
| //借方金额 | ||
| debit?: string; | ||
| //贷方金额 | ||
| credit?: string; | ||
| } |
| import CustomVoucher from "./CustomVoucher/CustomVoucher.vue"; | ||
| import CustomPrecis from "./CustomVoucher/CustomPrecis.vue"; | ||
| import CustomSubjects from "./CustomVoucher/CustomSubjects.vue"; | ||
| import CustomNumber from "./CustomVoucher/CustomNumber.vue"; | ||
| export { CustomVoucher, CustomPrecis, CustomSubjects, CustomNumber }; |
| ##财务管理专用组件库 |
| class VPzptUtil {} | ||
| export default VPzptUtil; |
| import { VxeUI } from "vxe-pc-ui"; | ||
| class LoadingUtil { | ||
| public static startLoading(text: string = "加载中...") { | ||
| VxeUI.loading.open({ | ||
| icon: "vxe-icon-indicator roll", | ||
| text | ||
| }); | ||
| } | ||
| public static closeLoading() { | ||
| VxeUI.loading.close(); | ||
| } | ||
| } | ||
| export default LoadingUtil; |
+25
-12
@@ -9,17 +9,30 @@ import MessageUtil from "./src/messageUtil/MessageUtil"; | ||
| import CustomCode, { ICustomCodeRef } from "./src/customCode/CustomCode.vue"; | ||
| import CustomCodeMirror from "./src/customCodeMirror/CustomCodeMirror.vue" | ||
| import CustomCodeMirror from "./src/customCodeMirror/CustomCodeMirror.vue"; | ||
| import { ELangType } from "./src/customCodeMirror/types"; | ||
| import { CustomVoucher, CustomPrecis, CustomSubjects, CustomNumber } from "./src/customPzpt"; | ||
| import CustomContainer from "./src/customContainer/CustomContainer.vue"; | ||
| import CustomCnfgInput from "./src/customCnfg/customCnfgInput/CustomCnfgInput.vue"; | ||
| import CustomCnfgModal from "./src/customCnfg/customCnfgModal/CustomCnfgModal.vue"; | ||
| import CustomCnfgSelect from "./src/customCnfg/customCnfgSelect/CustomCnfgSelect.vue"; | ||
| import LoadingUtil from "./src/messageUtil/LadongUtil"; | ||
| export { | ||
| CustomTable, | ||
| MessageUtil, | ||
| CustomUnitInput, | ||
| CustomUnitTree, | ||
| CustomIcon, | ||
| CustomChangePassword, | ||
| CustomCode, | ||
| CustomCodeMirror, | ||
| ELangType | ||
| export { | ||
| CustomTable, | ||
| MessageUtil, | ||
| LoadingUtil, | ||
| CustomUnitInput, | ||
| CustomUnitTree, | ||
| CustomContainer, | ||
| CustomIcon, | ||
| CustomChangePassword, | ||
| CustomCode, | ||
| CustomCodeMirror, | ||
| ELangType, | ||
| CustomCnfgSelect, | ||
| CustomCnfgInput, | ||
| CustomCnfgModal | ||
| }; | ||
| export type { ICustomTableRef, ICustomTablePagerConfig, IChangeForm, ICustomChangePasswordRef, ICustomCodeRef }; | ||
| export { CustomVoucher, CustomPrecis, CustomSubjects, CustomNumber }; | ||
| export type { ICustomTableRef, ICustomTablePagerConfig, IChangeForm, ICustomChangePasswordRef, ICustomCodeRef }; |
+4
-3
| { | ||
| "name": "@ningboyz/vcomponent", | ||
| "version": "1.0.1", | ||
| "private":false, | ||
| "version": "1.0.2", | ||
| "private": false, | ||
| "type": "module", | ||
@@ -20,4 +20,5 @@ "main": "index.ts", | ||
| "@ningboyz/apis": "workspace:^", | ||
| "@ningboyz/types": "workspace:^" | ||
| "@ningboyz/types": "workspace:^", | ||
| "@ningboyz/utils": "workspace:^" | ||
| } | ||
| } |
@@ -91,3 +91,3 @@ <script setup lang="ts"> | ||
| <template> | ||
| <vxe-modal v-model="state.visible" title="修改密码" show-footer width="520" centerd class-name="change-password" @close="handleCancel"> | ||
| <vxe-modal v-model="state.visible" title="修改密码" show-footer width="520" class-name="change-password" @close="handleCancel"> | ||
| <vxe-form ref="formRef" title-align="right" title-width="100" title-colon :data="formData" :rules="formRules"> | ||
@@ -94,0 +94,0 @@ <vxe-form-item title="用户名" field="username" span="24" :item-render="{}"> |
@@ -107,12 +107,7 @@ <script setup lang="ts"> | ||
| @on-unit-select="handleUnitSelect" | ||
| @on-cnfg-select="handleCnfgSelect" | ||
| /> | ||
| @on-cnfg-select="handleCnfgSelect" /> | ||
| </template> | ||
| <template #footer> | ||
| <el-button @click="handleCancelClick"> | ||
| 取消 | ||
| </el-button> | ||
| <el-button type="primary" @click="handleOkClick"> | ||
| 确定 | ||
| </el-button> | ||
| <vxe-button icon="vxe-icon-close" @click="handleCancelClick">取消</vxe-button> | ||
| <vxe-button icon="vxe-icon-check" status="primary" @click="handleOkClick">确定</vxe-button> | ||
| </template> | ||
@@ -119,0 +114,0 @@ </vxe-modal> |
| <script setup lang="ts"> | ||
| import _ from "lodash"; | ||
| import { reactive, ref } from "vue"; | ||
| import { ElInput } from "element-plus"; | ||
| // import { ElInput } from "element-plus"; | ||
| // import { VxeInput } from "vxe-table"; | ||
@@ -31,2 +32,7 @@ interface IState { | ||
| const onInputHandler = (index: number, event: any) => { | ||
| const value = (event as { value: string }).value; | ||
| handleInput(value, index); | ||
| }; | ||
| const handleInput = (value: string, index: number) => { | ||
@@ -72,2 +78,7 @@ const reg = /^\d{1,4}$/; | ||
| const onKeyDownHandler = (index: number, event: Event | KeyboardEvent) => { | ||
| const value = (event as KeyboardEvent).code; | ||
| handleInputKeyDown(value, index); | ||
| }; | ||
| const handleInputKeyDown = (code: string, index: number) => { | ||
@@ -114,105 +125,63 @@ if (code === "Backspace") { | ||
| <div class="code-form"> | ||
| <ElInput | ||
| <VxeInput | ||
| type="number" | ||
| min="0" | ||
| max="9" | ||
| ref="inputRef0" | ||
| v-model="state.a" | ||
| placeholder="" | ||
| placeholder=" " | ||
| class="code-form-input" | ||
| @input=" | ||
| (value: string) => { | ||
| handleInput(value, 0); | ||
| } | ||
| " | ||
| @keydown=" | ||
| (event: Event | KeyboardEvent) => { | ||
| //@ts-ignore | ||
| handleInputKeyDown(event.code, 0); | ||
| } | ||
| " | ||
| /> | ||
| @input="onInputHandler(0, $event)" | ||
| @keydown="onKeyDownHandler(0, $event.$event)" /> | ||
| <ElInput | ||
| <VxeInput | ||
| type="number" | ||
| min="0" | ||
| max="9" | ||
| ref="inputRef1" | ||
| v-model="state.b" | ||
| placeholder="" | ||
| placeholder=" " | ||
| class="code-form-input" | ||
| @input=" | ||
| (value: string) => { | ||
| handleInput(value, 1); | ||
| } | ||
| " | ||
| @keydown=" | ||
| (event: Event | KeyboardEvent) => { | ||
| //@ts-ignore | ||
| handleInputKeyDown(event.code, 1); | ||
| } | ||
| " | ||
| /> | ||
| <ElInput | ||
| @input="onInputHandler(1, $event)" | ||
| @keydown="onKeyDownHandler(1, $event.$event)" /> | ||
| <VxeInput | ||
| type="number" | ||
| min="0" | ||
| max="9" | ||
| ref="inputRef2" | ||
| v-model="state.c" | ||
| placeholder="" | ||
| placeholder=" " | ||
| class="code-form-input" | ||
| @input=" | ||
| (value: string) => { | ||
| handleInput(value, 2); | ||
| } | ||
| " | ||
| @keydown=" | ||
| (event: Event | KeyboardEvent) => { | ||
| //@ts-ignore | ||
| handleInputKeyDown(event.code, 2); | ||
| } | ||
| " | ||
| /> | ||
| <ElInput | ||
| @input="onInputHandler(2, $event)" | ||
| @keydown="onKeyDownHandler(2, $event.$event)" /> | ||
| <VxeInput | ||
| type="number" | ||
| min="0" | ||
| max="9" | ||
| ref="inputRef3" | ||
| v-model="state.d" | ||
| placeholder="" | ||
| placeholder=" " | ||
| class="code-form-input" | ||
| @input=" | ||
| (value: string) => { | ||
| handleInput(value, 3); | ||
| } | ||
| " | ||
| @keydown=" | ||
| (event: Event | KeyboardEvent) => { | ||
| //@ts-ignore | ||
| handleInputKeyDown(event.code, 3); | ||
| } | ||
| " | ||
| /> | ||
| <ElInput | ||
| @input="onInputHandler(3, $event)" | ||
| @keydown="onKeyDownHandler(3, $event.$event)" /> | ||
| <VxeInput | ||
| type="number" | ||
| min="0" | ||
| max="9" | ||
| ref="inputRef4" | ||
| v-model="state.e" | ||
| placeholder="" | ||
| placeholder=" " | ||
| class="code-form-input" | ||
| @input=" | ||
| (value: string) => { | ||
| handleInput(value, 4); | ||
| } | ||
| " | ||
| @keydown=" | ||
| (event: Event | KeyboardEvent) => { | ||
| //@ts-ignore | ||
| handleInputKeyDown(event.code, 4); | ||
| } | ||
| " | ||
| /> | ||
| <ElInput | ||
| @input="onInputHandler(4, $event)" | ||
| @keydown="onKeyDownHandler(4, $event.$event)" /> | ||
| <VxeInput | ||
| type="number" | ||
| min="0" | ||
| max="9" | ||
| ref="inputRef5" | ||
| v-model="state.f" | ||
| placeholder="" | ||
| placeholder=" " | ||
| class="code-form-input" | ||
| @input=" | ||
| (value: string) => { | ||
| handleInput(value, 5); | ||
| } | ||
| " | ||
| @keydown=" | ||
| (event: Event | KeyboardEvent) => { | ||
| //@ts-ignore | ||
| handleInputKeyDown(event.code, 5); | ||
| } | ||
| " | ||
| /> | ||
| @input="onInputHandler(5, $event)" | ||
| @keydown="onKeyDownHandler(5, $event.$event)" /> | ||
| </div> | ||
@@ -233,3 +202,3 @@ </template> | ||
| .code-form :deep(.el-input__inner) { | ||
| .code-form :deep(.vxe-input) { | ||
| padding-left: 9px !important; | ||
@@ -239,2 +208,6 @@ font-size: 18px; | ||
| } | ||
| .vxe-input :deep(.vxe-input--control-icon) { | ||
| display: none; | ||
| } | ||
| </style> |
@@ -1,2 +0,2 @@ | ||
| .cnfg-container { | ||
| .custom-container { | ||
| width: 100%; | ||
@@ -7,3 +7,3 @@ height: 100%; | ||
| background-color: #eeecec; | ||
| padding: 6px; | ||
| padding: 4px; | ||
@@ -10,0 +10,0 @@ &-inner { |
@@ -1,2 +0,2 @@ | ||
| <script setup lang="ts" name="/pzpt/cnfg/index"> | ||
| <script setup lang="ts"> | ||
@@ -6,4 +6,4 @@ </script> | ||
| <template> | ||
| <div class="cnfg-container"> | ||
| <div class="cnfg-container-inner"> | ||
| <div class="custom-container"> | ||
| <div class="custom-container-inner"> | ||
| <slot /> | ||
@@ -10,0 +10,0 @@ </div> |
| <script setup lang="ts" generic="T extends object"> | ||
| import { ref, useSlots } from "vue"; | ||
| import type { VxeTableDefines, VxeTableInstance } from "vxe-table"; | ||
| import { onMounted, reactive, ref, useSlots } from "vue"; | ||
| import { VxeColumnPropTypes, VxeTableDefines, VxeTableInstance, VxeTablePropTypes, VxeToolbarInstance } from "vxe-table"; | ||
| import { VxeGrid } from "vxe-table"; | ||
@@ -17,2 +17,3 @@ import _ from "lodash"; | ||
| columns: () => [], | ||
| toolbarConfig: () => ({ custom: false }), | ||
| multiple: false, | ||
@@ -26,2 +27,9 @@ loading: false, | ||
| const emits = defineEmits(["onCellClick", "onRadioChange", "onCheckBoxChange", "onMenuClick", "editClosed", "onPageChange"]); | ||
| const toolbarRef = ref<VxeToolbarInstance>(); | ||
| const customConfig = reactive<VxeTablePropTypes.CustomConfig>({ | ||
| mode: "drawer" | ||
| }); | ||
| const slots = useSlots(); | ||
@@ -31,2 +39,10 @@ | ||
| onMounted(() => { | ||
| const $table = tableRef.value; | ||
| const $toolbar = toolbarRef.value; | ||
| if ($table && $toolbar) { | ||
| $table.connect($toolbar); | ||
| } | ||
| }); | ||
| const getSelectRecords = () => { | ||
@@ -54,9 +70,12 @@ const checkBoxRecords = getCheckboxRecords(); | ||
| const setTreeExpand = (rows: T[], checked: boolean) => { | ||
| tableRef.value?.setTreeExpand(rows, checked); | ||
| const setTreeExpand = async (rows: T[], checked: boolean) => { | ||
| await tableRef.value?.setTreeExpand(rows, checked); | ||
| }; | ||
| const setCheckboxRow = (rows: T[], checked: boolean) => { | ||
| const setCheckboxRow = async (rows: T[] | T, checked: boolean) => { | ||
| tableRef.value?.setCheckboxRow(rows, checked); | ||
| }; | ||
| const toggleCheckboxRow = async (rows: T) => { | ||
| tableRef.value?.toggleCheckboxRow(rows); | ||
| }; | ||
@@ -127,2 +146,19 @@ const setRadioFirstRow = () => { | ||
| /** 清空排序条件 */ | ||
| const clearSort = (fieldOrColumn?: string | VxeColumnPropTypes.Field | VxeTableDefines.ColumnInfo<T> | null) => { | ||
| const table = tableRef.value; | ||
| if (_.isNil(table)) { | ||
| return; | ||
| } | ||
| table.clearSort(fieldOrColumn); | ||
| }; | ||
| /** 清空选中 */ | ||
| const clearRadioRow = async () => { | ||
| const table = tableRef.value; | ||
| if (_.isNil(table)) { | ||
| return; | ||
| } | ||
| await table.clearRadioRow(); | ||
| }; | ||
| const removeCheckboxRow = () => { | ||
@@ -144,2 +180,10 @@ const table = tableRef.value; | ||
| const getTableGrid = () => { | ||
| const table = tableRef.value; | ||
| if (_.isNil(table)) { | ||
| return; | ||
| } | ||
| return table; | ||
| }; | ||
| const editClosed = ({ row }: any) => { | ||
@@ -173,8 +217,11 @@ emits("editClosed", row); | ||
| }; | ||
| const scrollToRow = (row: T) => { | ||
| tableRef.value?.scrollToRow(row); | ||
| }; | ||
| const getRadioRecordByOne = () => { | ||
| if(_.isNil(tableRef.value)){ | ||
| if (_.isNil(tableRef.value)) { | ||
| return undefined; | ||
| } | ||
| if(_.isNil(tableRef.value.getRadioRecord())){ | ||
| if (_.isNil(tableRef.value.getRadioRecord())) { | ||
| return undefined; | ||
@@ -203,3 +250,8 @@ } | ||
| setCurrentRow, | ||
| setAllTreeExpand | ||
| setAllTreeExpand, | ||
| scrollToRow, | ||
| clearSort, | ||
| getTableGrid, | ||
| clearRadioRow, | ||
| toggleCheckboxRow | ||
| }); | ||
@@ -213,3 +265,2 @@ </script> | ||
| :size="props.size" | ||
| :width="props.width" | ||
| :height="props.height" | ||
@@ -226,11 +277,19 @@ :data="props.data" | ||
| :tree-config="props.treeConfig" | ||
| :custom-config="customConfig" | ||
| :toolbar-config="props.toolbarConfig" | ||
| :span-method="props.spanMethod" | ||
| :pager-config="props.usesPager && !_.isNil(props.pagerConfig) ? { | ||
| total: props.pagerConfig!.total, | ||
| currentPage: props.pagerConfig!.currentPage, | ||
| pageSize: props.pagerConfig!.pageSize, | ||
| layouts: ['Home', 'PrevJump', 'PrevPage', 'Number', 'NextPage', 'NextJump', 'End', 'Sizes', 'FullJump', 'Total'], | ||
| } : undefined" | ||
| :pager-config=" | ||
| props.usesPager && !_.isNil(props.pagerConfig) | ||
| ? { | ||
| total: props.pagerConfig!.total, | ||
| currentPage: props.pagerConfig!.currentPage, | ||
| pageSize: props.pagerConfig!.pageSize, | ||
| pageSizes: props.pagerConfig!.pageSizes, | ||
| layouts: ['Home', 'PrevJump', 'PrevPage', 'Number', 'NextPage', 'NextJump', 'End', 'Sizes', 'FullJump', 'Total'], | ||
| } | ||
| : undefined | ||
| " | ||
| :loading="props.loading" | ||
| resizable | ||
| show-footer | ||
| :show-overflow="!props.noShowOverFlow" | ||
@@ -242,9 +301,30 @@ @cell-click="onCellClick" | ||
| @edit-closed="editClosed" | ||
| @page-change="handlePageChange"> | ||
| <template v-for="(_item, key, i) in slots" :key="i" #[key]="{ row, rowIndex }"> | ||
| <slot :name="key" v-bind="{ row, rowIndex }" /> | ||
| @page-change="handlePageChange" | ||
| > | ||
| <template #toolbar> | ||
| <div class="toolbar-title"> | ||
| <div class="empty-div"></div> | ||
| <vxe-toolbar v-if="props.toolbarConfig?.custom ?? false" ref="toolbarRef" custom class="toolbar" /> | ||
| </div> | ||
| </template> | ||
| <template v-for="(_item, key, i) in slots" :key="i" #[key]="{ row, rowIndex, column }"> | ||
| <div class="toolbar-title"> | ||
| <slot :name="key" v-bind="{ row, rowIndex, column }" /> | ||
| <vxe-toolbar v-if="key === 'toolbar' && (props.toolbarConfig?.custom ?? false)" ref="toolbarRef" custom class="toolbar" /> | ||
| </div> | ||
| </template> | ||
| </VxeGrid> | ||
| </template> | ||
| <style lang="scss"></style> | ||
| <style lang="scss"> | ||
| .toolbar-title { | ||
| display: flex !important; | ||
| justify-content: space-between; | ||
| align-items: center; | ||
| position: relative; | ||
| .table-toolbar { | ||
| padding: 0.6em 0; | ||
| } | ||
| } | ||
| </style> |
@@ -1,2 +0,2 @@ | ||
| import type { VxeComponentSizeType, VxeGridPropTypes, VxeTablePropTypes } from "vxe-table"; | ||
| import type { VxeColumnPropTypes, VxeComponentSizeType, VxeGridPropTypes, VxeTableDefines, VxeTableInstance, VxeTablePropTypes } from "vxe-table"; | ||
@@ -7,2 +7,3 @@ export interface ICustomTablePagerConfig { | ||
| pageSize: number; | ||
| pageSizes?: number[] | Array<{ label: string; value: number }>; | ||
| } | ||
@@ -25,2 +26,8 @@ | ||
| round?: boolean; | ||
| /** | ||
| * 工具栏配置 | ||
| */ | ||
| toolbarConfig?: { | ||
| custom: boolean | object; // 自定义列配置 | ||
| }; | ||
@@ -81,2 +88,4 @@ /** | ||
| noShowOverFlow?: boolean; | ||
| spanMethod?: VxeTablePropTypes.SpanMethod<T>; | ||
| } | ||
@@ -109,3 +118,3 @@ export interface ICustomTableRef<T> { | ||
| */ | ||
| setTreeExpand: (rows: T[], checked: boolean) => void; | ||
| setTreeExpand: (rows: T[], checked: boolean) => Promise<void>; | ||
@@ -118,4 +127,5 @@ /** | ||
| */ | ||
| setCheckboxRow: (rows: T[], checked: boolean) => void; | ||
| setCheckboxRow: (rows: T[] | T, checked: boolean) => Promise<void>; | ||
| toggleCheckboxRow: (row: T) => void; | ||
| /** | ||
@@ -157,2 +167,6 @@ * 用于 type=radio,设置第一行为选中状态 | ||
| scrollToRow: (row: T, fieldOrColumn?: VxeColumnPropTypes.Field | VxeTableDefines.ColumnInfo<T>) => void; | ||
| clearRadioRow: () => void; | ||
| getTableData: () => | ||
@@ -166,2 +180,6 @@ | { | ||
| | undefined; | ||
| clearSort: (fieldOrColumn?: string | VxeColumnPropTypes.Field | VxeTableDefines.ColumnInfo<T> | null) => void; | ||
| getTableGrid: () => VxeTableInstance<T> | undefined; | ||
| } |
@@ -22,5 +22,4 @@ <script setup lang="ts" generic="T extends object, K extends keyof T" name="CustomTree"> | ||
| const getCheckedNodes = () => { | ||
| // return treeRef.value?.getCheckedNodes() as T[]; | ||
| // return treeRef.value?.getCheckedNodes() as T[]; | ||
| return treeRef.value?.getCheckedNodes(false, true) as T[]; | ||
| }; | ||
@@ -77,3 +76,3 @@ | ||
| .el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content > .el-tree-node__expand-icon { | ||
| .el-tree--highlight-current .el-tree-node.is-current > .el-tree-node_ontent > .el-tree-node__expand-icon { | ||
| transition: all 0.2s; | ||
@@ -80,0 +79,0 @@ } |
@@ -12,2 +12,4 @@ <script setup lang="ts"> | ||
| isUseUnitIndx?: boolean; | ||
| /** 加载loading */ | ||
| loading?: boolean; | ||
| } | ||
@@ -18,5 +20,7 @@ | ||
| setRadioRow: (listUnit: IUnitResponse) => void; | ||
| getCheckboxRecords: () => IUnitResponse[]; | ||
| setAllTreeExpand: (check: boolean) => void; | ||
| setCheckboxRow: (rows: IUnitResponse[], checked: boolean) => void; | ||
| setTreeExpand: (rows: IUnitResponse[], checked: boolean) => void; | ||
| clearRadioRow: () => void; | ||
| } | ||
@@ -47,2 +51,7 @@ | ||
| }; | ||
| const getCheckboxRecords = () => { | ||
| let checkboxList: IUnitResponse[] = []; | ||
| checkboxList = tableRef.value?.getCheckboxRecords() || []; | ||
| return checkboxList; | ||
| }; | ||
@@ -60,2 +69,6 @@ const setAllTreeExpand = (check: boolean) => { | ||
| }; | ||
| const clearRadioRow = () => { | ||
| if (_.isNil(tableRef.value)) return; | ||
| tableRef.value.clearRadioRow(); | ||
| }; | ||
@@ -67,3 +80,5 @@ defineExpose<ICustomUnitTreeRef>({ | ||
| setCheckboxRow, | ||
| setTreeExpand | ||
| setTreeExpand, | ||
| getCheckboxRecords, | ||
| clearRadioRow | ||
| }); | ||
@@ -83,2 +98,3 @@ | ||
| round | ||
| :loading="props.loading" | ||
| :data="props.listUnit" | ||
@@ -85,0 +101,0 @@ :columns="[ |
@@ -1,9 +0,9 @@ | ||
| import { ElMessage, ElMessageBox } from "element-plus"; | ||
| import type { VNode } from "vue"; | ||
| import { VxeUI } from "vxe-pc-ui"; | ||
| export default class MessageUtil { | ||
| class MessageUtil { | ||
| public static showError(message: string) { | ||
| ElMessage({ | ||
| message, | ||
| type: "error" | ||
| VxeUI.modal.message({ | ||
| id: "vxe-modal-message-id", | ||
| content: message, | ||
| status: "error" | ||
| }); | ||
@@ -13,5 +13,5 @@ } | ||
| public static showSuccess(message: string) { | ||
| ElMessage({ | ||
| message, | ||
| type: "success" | ||
| VxeUI.modal.message({ | ||
| content: message, | ||
| status: "success" | ||
| }); | ||
@@ -21,5 +21,5 @@ } | ||
| public static showWarning(message: string) { | ||
| ElMessage({ | ||
| message, | ||
| type: "warning" | ||
| VxeUI.modal.message({ | ||
| content: message, | ||
| status: "warning" | ||
| }); | ||
@@ -29,20 +29,38 @@ } | ||
| public static showInfo(message: string) { | ||
| ElMessage({ | ||
| message, | ||
| type: "info" | ||
| VxeUI.modal.message({ | ||
| content: message, | ||
| status: "info" | ||
| }); | ||
| } | ||
| public static confirm = (title: string, content: VNode | string): Promise<boolean> => { | ||
| public static openLoading = (content: string) => { | ||
| VxeUI.modal.message({ | ||
| id: "46226e065bd7c2c621a03de33a09fda1", | ||
| content: content, | ||
| status: "loading", | ||
| duration: undefined, | ||
| lockView: true | ||
| }); | ||
| }; | ||
| public static closeLoading = () => { | ||
| VxeUI.modal.close("46226e065bd7c2c621a03de33a09fda1"); | ||
| }; | ||
| public static confirm = (title: string, message: string, needMask = false): Promise<any> => { | ||
| return new Promise((resolve) => { | ||
| ElMessageBox.confirm(content, title, { | ||
| confirmButtonText: "确定", | ||
| cancelButtonText: "取消", | ||
| type: "warning" | ||
| }) | ||
| .then(() => { | ||
| resolve(true); | ||
| VxeUI.modal | ||
| .confirm({ | ||
| title, | ||
| content: message, | ||
| lockView: true, | ||
| mask: needMask, | ||
| showClose: true, | ||
| showConfirmButton: true, | ||
| confirmButtonText: "确定", | ||
| cancelButtonText: "取消" | ||
| }) | ||
| .catch(() => { | ||
| resolve(false); | ||
| .then((type) => { | ||
| console.log(`操作类型 ${type}`); | ||
| resolve(type === "confirm"); | ||
| }); | ||
@@ -52,1 +70,3 @@ }); | ||
| } | ||
| export default MessageUtil; |
Unpublished package
Supply chain riskPackage version was not found on the registry. It may exist on a different registry and need to be configured to pull from that registry.
Found 1 instance in 1 package
Unpublished package
Supply chain riskPackage version was not found on the registry. It may exist on a different registry and need to be configured to pull from that registry.
Found 1 instance in 1 package
86755
46.49%49
40%651
38.51%3
50%+ Added