import {computed, nextTick, reactive, Ref, ref, watch, onMounted} from 'vue' import type {VxePagerProps, VxeTableProps} from "vxe-table"; import {VxePager, VxeTable, VxeColumn} from "vxe-table"; import {TablePublicMethods, VxeTableEventProps} from "vxe-table/types/table"; import XEUtils from "xe-utils"; import {stringIsBlank, stringNotBlank} from "@/utils/blank-utils"; import {TableExportMethods} from "vxe-table/types/export"; import {BizException, ExceptionEnum} from "@/utils/BizException"; import {eachAndReturnList} from "@/utils/cyRefList"; import {ElButton, ElPopover} from "element-plus"; import setDialogToJs from "@/components/js-dialog-comp/useDialogToJs"; import CyDialog from "@/components/cy/dialog/src/CyDialog.vue"; import {IsCyDialog} from "@/components/cy/dialog/src/useCyDialog"; import CyFlex from "@/components/cy/flex/src/CyFlex.vue"; declare type PageQuery = { currentPage?: number, pageSize?: number, } declare type SimplifiedConfiguration = { rowHeight?: number, keyField?: string, currentKey?: string | number, remoteSearch?: (data?: PageQuery & any) => Promise, tableProps?: VxeTableEventProps & VxeTableProps, showPage?: boolean, result?: string, total?: string, pagesProps?: VxePagerProps, showCheckbox?: boolean, mountedQuery?: boolean, dialogProps?: IsCyDialog, dialogHeader?: () => any } function tsxVModel(modelValue: object, name: string, modelName?: string) { const updateName = modelName || name return { // @ts-ignore [updateName]: modelValue[name], ['onUpdate:' + updateName]: (el: any) => { // @ts-ignore modelValue[name] = el } } } function useVxeTable(simplifiedConfiguration: SimplifiedConfiguration) { const tableRef: Ref & TableExportMethods | undefined> = ref() const props: VxeTableProps & VxeTableEventProps & SimplifiedConfiguration = reactive({ height: '100%', rowConfig: { isHover: true, isCurrent: true, height: simplifiedConfiguration?.rowHeight || 48, useKey: true, keyField: simplifiedConfiguration?.keyField || '', }, scrollY: { enabled: true, gt: 0 }, columnConfig: { resizable: true }, scrollX: { enabled: false, }, exportConfig: {}, showOverflow: true, currentKey: '', menuConfig: { enabled: true }, loading: false, loadingConfig: { text: '加载中...', icon: '', }, checkboxConfig: { reserve: true, highlight: true, range: true, }, data: [], }) if (simplifiedConfiguration.showPage) { delete props.rowConfig?.height props.scrollY!.enabled = false props!.showOverflow = false props!.checkboxConfig!.reserve = true if (stringIsBlank(props.rowConfig?.keyField)) { BizException(ExceptionEnum.MESSAGE_ERROR, '请先设置行id') } } const pageVO = reactive({ currentPage: 1, pageSize: 30, total: 0 }) const pagerProps: VxePagerProps = reactive({ loading: false, }) watch(() => props.currentKey, () => { if (stringNotBlank(defaultProps.value.rowConfig?.keyField)) { const findData = XEUtils.find(tableRef.value?.getData(), (item) => { // @ts-ignore return item[defaultProps.value.rowConfig?.keyField] === props.currentKey; }) if (findData) { tableRef.value?.scrollToRow(findData) tableRef.value?.setCurrentRow(findData) } } }, {flush: 'post'}) const defaultProps = computed(() => { return { ...simplifiedConfiguration?.tableProps, ...props } as VxeTableProps }) const CyVxeTable = (props: VxeTableProps, {slots}: any) => { mutation.setTableDefaultSlots = () => { return slots.default ? slots.default() : null } const TempVxeTable = () => { return {{ default: () => { function renderIcon(checked: boolean, indeterminate: boolean) { if (indeterminate) { return } else if (checked) { return } else { return } } function checkboxHeader(checked: boolean, indeterminate: boolean) { return {{ default: () => { return [ `当前选中${pageMemory.size}条`,
{ if (pageMemory.size > 0) handelLookCheckBox() }} >{{default: () => '详情'}} { mutation.clearCheckboxRow() }} >{{default: () => '清空'}}
] }, reference: () => { return { el.preventDefault() el.stopPropagation() handelCheckboxAll() }}>{renderIcon(checked, indeterminate)} } }}
} return [ simplifiedConfiguration.showCheckbox ? {{ // @ts-ignore header({checked, indeterminate}) { return checkboxHeader(checked, indeterminate) }, // @ts-ignore checkbox({row, checked, indeterminate}) { return { el.preventDefault() el.stopPropagation() handelCheckboxChange({row, checked: !checked}) }}> {renderIcon(checked, indeterminate)} } }} : null, ...slots.default ? slots.default() : null, ]; } }}
} if (simplifiedConfiguration.showPage) { return
{ pageChange() }} size={"small"} {...tsxVModel(pageVO, 'currentPage')} {...tsxVModel(pageVO, 'pageSize')} total={pageVO.total} {...simplifiedConfiguration.pagesProps} {...pagerProps} />
} else { return } } function exportExcel(filename: string = '', sheetName: string = 'sheet1') { if (!XEUtils.isString(filename)) { filename = '' } tableRef.value?.openExport({ filename, sheetName, types: ['xlsx', 'csv', 'html', 'xml', 'txt'], type: 'xlsx', useStyle: true, original: true, }) } let queryParamsCache = {} function pageChange() { if (XEUtils.isEmpty(queryParamsCache)) { return } const data = { ...queryParamsCache, ...pageVO } props.loading = true pageQuery(data, false) } function pageQuery(data: any, clearCurrentPage: boolean = true) { pagerProps.loading = true // @ts-ignore simplifiedConfiguration.remoteSearch(data).then(res => { // @ts-ignore const data: D[] = XEUtils.get(res, simplifiedConfiguration!.result || 'result') as D[] // @ts-ignore const total: number = XEUtils.get(res, simplifiedConfiguration!.total || 'total') as number props.data = data pageVO.total = total }).catch((e) => { props.data = [] pageVO.total = 0 console.error(e) }).finally(() => { if (clearCurrentPage) { pageVO.currentPage = 1 pageMemory.clear() } props.loading = false pagerProps.loading = false handelPageCheckBox() }) } const pageMemory = reactive(new Map()); function getCheckboxRecords() { // @ts-ignore return eachAndReturnList(pageMemory, (item) => { return item }) } function handelCheckbox() { const data = tableRef.value!.getCheckboxRecords() if (data.length > 0) { XEUtils.arrayEach(tableRef.value!.getCheckboxRecords(), (item) => { // @ts-ignore pageMemory.set(item[simplifiedConfiguration.keyField], item) }) } else { XEUtils.arrayEach(tableRef.value!.getData(), (item) => { // @ts-ignore pageMemory.delete(item[simplifiedConfiguration.keyField]) }) } } function handelPageCheckBox() { nextTick().then(() => { // @ts-ignore XEUtils.arrayEach(pageMemory, (item) => { tableRef.value?.setCheckboxRow(item, true) }) }) } function handelCheckboxChange({row, checked}: { row: any, checked: boolean }) { mutation.setCheckboxRow(row, checked) } async function handelCheckboxAll() { await tableRef.value?.toggleAllCheckboxRow() nextTick().then(() => { handelCheckbox() }) } function querySearch() { props.loading = true // @ts-ignore if (simplifiedConfiguration.showPage) { const pageData = { ...pageVO, total: 0, currentPage: 1 } queryParamsCache = pageData pageQuery(pageData) } else { // @ts-ignore simplifiedConfiguration.remoteSearch({...pageVO}).then(res => { props.data = res }).catch(() => { props.data = [] }).finally(() => { props.loading = false }) } } function handelLookCheckBox() { const dialog = ( {{ default: () => { const data = getCheckboxRecords() return {{ header: () => { try { if (simplifiedConfiguration.dialogHeader) { const Scc = simplifiedConfiguration?.dialogHeader(); if (typeof Scc !== 'undefined') { return } else { console.error('dialogHeader需要返回一个组件') } } } catch (e) { console.error('dialogHeader需要返回一个组件', e) return null } }, default: () => { return 100} height={"100%"}> {{ default: () => { return [ {{ default({row}: any) { return { handelCheckboxChange({row, checked: false}) }} >{{default: () => '删除'}} } }} , mutation.setTableDefaultSlots() ] } }} } }} } }} ) setDialogToJs(dialog, null).then(() => { }) } const mutation = { updateByIndex: function updateByIndex(data: D | any, index: number) { const tableData = tableRef.value?.getData() // @ts-ignore tableData[index] = data // @ts-ignore tableRef.value?.loadData(tableData) }, setCheckboxRow: async function (row: D, checked: boolean) { await tableRef.value?.setCheckboxRow(row, checked) // @ts-ignore const key = XEUtils.get(row, simplifiedConfiguration!.keyField, null) as string | null if (key === null) return if (checked) { pageMemory.set(key, row) } else { pageMemory.delete(key) } }, clearCheckboxRow() { tableRef.value?.clearCheckboxRow() pageMemory.clear() }, setTableDefaultSlots(): any { } } onMounted(() => { if (simplifiedConfiguration.mountedQuery) { nextTick().then(() => { querySearch() }) } }) return { tableRef, CyVxeTable: CyVxeTable, tableProps: props, exportExcel, mutation, querySearch, getCheckboxRecords } } export default useVxeTable