import { delConfirm } from "@/utils"; import { Doption, Dropdown, Link, Message, TableColumnData } from "@arco-design/web-vue"; import { isArray, merge } from "lodash-es"; import { Component, Ref, reactive } from "vue"; import { useFormModal } from "../form"; import { Table, TableInstance, TableProps } from "./table"; import { config } from "./table.config"; import { UseTableOptions } from "./use-interface"; const onClick = async (item: any, columnData: any, getTable: any) => { if (item.type === "modify") { const data = (await item.onClick?.(columnData)) ?? columnData.record; getTable()?.openModifyModal(data); return; } if (item.type === "delete") { await delConfirm(); try { const resData: any = await item?.onClick?.(columnData); const message = resData?.data?.message; message && Message.success(`提示:${message}`); getTable()?.loadData(); } catch (error: any) { const message = error.response?.data?.message; message && Message.warning(`提示:${message}`); } return; } item.onClick?.(columnData); }; /** * 表格组件hook * @see `src/components/table/use-table.tsx` */ export const useTable = (optionsOrFn: UseTableOptions | (() => UseTableOptions)): any => { const options: UseTableOptions = typeof optionsOrFn === "function" ? optionsOrFn() : optionsOrFn; const columns: TableColumnData[] = []; const getTable = (): TableInstance => (columns as any).instance; /** * 表格列处理 */ for (let column of options.columns) { /** * 索引列处理 */ if (column.type === "index") { column = merge({}, config.columnIndex, column); } /** * 按钮列处理 */ if (column.type === "button" && isArray(column.buttons)) { const buttons = column.buttons; let hasModify = false; let hasDelete = false; for (let i = 0; i < buttons.length; i++) { let btn = merge({}, config.columnButtonBase); if (buttons[i].type === "modify") { btn = merge(btn, buttons[i]); hasModify = true; } if (buttons[i].type === "delete") { btn = merge(btn, buttons[i]); hasDelete = true; } buttons[i] = merge(btn, buttons[i]); } if (!hasModify) { buttons.push(merge({}, config.columnButtonBase)); } if (!hasDelete) { buttons.push(merge({}, config.columnButtonBase)); } column.render = (columnData) => { return column.buttons?.map((btn) => { if (btn.visible?.(columnData) === false) { return null; } return ( onClick(btn, columnData, getTable)} disabled={btn.disabled?.(columnData)} > {btn.text} ); }); }; } /** * 菜单列处理 */ if (column.type === "dropdown" && Array.isArray(column.dropdowns)) { if (options.modify) { const index = column.dropdowns?.findIndex((i) => i.type === "modify"); if (index !== undefined) { column.dropdowns[index] = merge({}, config.columnDropdownModify, column.dropdowns[index]); } else { column.dropdowns?.unshift(merge({}, config.columnDropdownModify)); } } column.render = (columnData) => { const content = column.dropdowns?.map((dropdown) => { const { text, icon, disabled, visibled, doptionProps } = dropdown; if (visibled?.(columnData) === false) { return null; } return ( onClick(dropdown, columnData, getTable)} disabled={disabled?.(columnData)} > {{ icon: typeof icon === "function" ? icon() : () => , default: text, }} ); }); const trigger = () => ( ); return ( <> 编辑 详情 {{ default: trigger, content: content, }} ); }; } columns.push({ ...config.columnBase, ...column }); } /** * 新增表单处理 */ if (options.create) { options.create = useFormModal(options.create as any) as any; } /** * 搜索表单的处理 */ if (options.search && options.search.items) { const searchItems: any[] = []; const createItems = options.create?.items ?? []; for (const item of options.search.items) { if (item.extend) { const createItem = createItems.find((i) => i.field === item.extend); if (createItem) { searchItems.push(merge({}, createItem, item)); continue; } } const search = !item.enableLoad ? undefined : () => getTable().reloadData(); searchItems.push( merge( { nodeProps: { onSearch: search, onPressEnter: search, }, }, item ) ); } if (options.search.button !== false) { searchItems.push(config.searchItemSubmit); } options.search.items = searchItems; } /** * 修改表单处理 */ if (options.modify) { if (options.modify.extend && options.create) { const createItems = options.create.items; const modifyItems = options.modify.items; if (modifyItems && createItems) { for (let i = 0; i < modifyItems.length; i++) { if (modifyItems[i].extend) { modifyItems[i] = merge({}, createItems[i], modifyItems[i]); } } } const merged = merge( { modalProps: { titleAlign: "start", closable: false }, model: { id: undefined } }, options.create, options.modify ); options.modify = useFormModal(merged as any) as any; } else { options.modify = useFormModal(options.modify as any) as any; } } return reactive({ ...options, columns }); }; /** * 提供操作的上下文 */ interface TableContext { /** * 传递给表格的参数(响应式) */ props: TableProps; /** * 表格实例 */ tableRef: Ref; /** * 刷新表格 */ refresh: () => void; /** * 重置表格 */ reload?: () => void; } type TableReturnType = [ /** * 绑定好参数的组件 */ Component, /** * 提供操作的上下文 */ TableContext ]; export const useAniTable = (options: UseTableOptions): TableReturnType => { const props = useTable(options); const tableRef = ref(null); const context = { props, tableRef, refresh: () => tableRef.value?.reloadData(), }; const aniTable = defineComponent({ name: "AniTableWrapper", setup() { const onRef = (el: TableInstance) => (tableRef.value = el); return () =>
; }, }); return [aniTable, context]; };