import { UnorderedListOutlined, AppstoreOutlined } from '@ant-design/icons-vue'; import styles from './index.module.less'; import { Pagination, Table, Spin, Alert } from 'ant-design-vue'; import type { TableProps } from 'ant-design-vue/es/table'; import type { TooltipProps } from 'ant-design-vue/es/tooltip'; import type { PopconfirmProps } from 'ant-design-vue/es/popconfirm'; import { CSSProperties, PropType, ref, computed, defineComponent, watch, onMounted, onUnmounted } from 'vue'; import type { JColumnsProps } from './types'; import { JEmpty } from '@jdlinker/ui'; enum ModelEnum { TABLE = 'TABLE', CARD = 'CARD' } enum TypeEnum { TREE = 'TREE', PAGE = 'PAGE' } type RequestData = | { code: string; result: { data?: Record[] | undefined; pageIndex: number; pageSize: number; total: number; }; status: number; } | Record; export interface ActionsType { key: string; text?: string; disabled?: boolean; permission?: boolean; onClick?: (data: any) => void; style?: CSSProperties; tooltip?: TooltipProps; popConfirm?: PopconfirmProps; icon?: string; children?: ActionsType[]; } export interface JTableProps extends TableProps { request?: (params?: Record) => Promise>; cardBodyClass?: string; columns: JColumnsProps[]; params?: Record; model?: keyof typeof ModelEnum | undefined; // 显示table还是card // actions?: ActionsType[]; noPagination?: boolean; rowSelection?: TableProps['rowSelection']; cardProps?: Record; showRightExtra?: boolean; dataSource?: Record[]; gridColumn?: number; /** * 用于不同分辨率 * gridColumns[0] 1366 ~ 1440 分辨率; * gridColumns[1] 1440 ~ 1600 分辨率; * gridColumns[2] > 1600 分辨率; */ gridColumns?: number[]; alertRender?: boolean; type?: keyof typeof TypeEnum; defaultParams?: Record; bodyStyle?: Record; } const JTable = defineComponent({ name: 'JTable', slots: [ 'headerTitle', // 顶部左边插槽 'card', // 卡片内容 'rightExtraRender', 'paginationRender' // 分页 ], props: { request: { type: Function, default: undefined }, cardBodyClass: { type: String, default: '' }, bodyStyle: { type: Object, default: {} }, columns: { type: Array, default: () => [] }, params: { type: Object, default: () => {} }, model: { type: [String, undefined], default: undefined }, noPagination: { type: Boolean, default: false }, rowSelection: { type: Object as PropType, default: () => undefined }, cardProps: { type: Object, default: undefined }, dataSource: { type: Array, default: () => [] }, gridColumns: { type: Array as PropType, default: [3, 3, 3] }, gridColumn: { type: Number, default: 4 }, alertRender: { type: Boolean, default: true }, showRightExtra: { type: Boolean, default: true }, type: { type: String, default: 'PAGE' }, defaultParams: { type: Object, default: () => { return { pageIndex: 0, pageSize: 10 }; } }, scroll: { type: Object, default: () => { x: 1366; } } } as any, emits: [ 'modelChange', // 切换卡片和表格 'reload' // 刷新数据 ], setup(props: JTableProps, { slots, emit, expose }) { const _model = ref(props.model ? props.model : ModelEnum.CARD); // 模式切换 const column = ref(props.gridColumn || 4); const _dataSource = ref[]>([]); const pageIndex = ref(0); const pageSize = ref(10); const total = ref(0); const loading = ref(true); const _columns = computed(() => props.columns.filter((i) => !i?.hideInTable)); /** * 监听宽度,计算显示卡片个数 */ const windowChange = () => { if (window.innerWidth <= 1440) { const _column = props.gridColumn && props.gridColumn < 2 ? props.gridColumn : 3; console.log('_column', _column); column.value = props.gridColumns ? props.gridColumns[0] : _column; } else if (window.innerWidth > 1440 && window.innerWidth <= 1600) { const _column = props.gridColumn && props.gridColumn < 3 ? props.gridColumn : 4; column.value = props.gridColumns ? props.gridColumns[1] : _column; } else if (window.innerWidth > 1600) { const _column = props.gridColumn && props.gridColumn < 4 ? props.gridColumn : 5; column.value = props.gridColumns ? props.gridColumns[2] : _column; } //console.log('windowChange...', props.gridColumn, window.innerWidth, props.showRightExtra, column.value); }; /** * 请求数据 */ const handleSearch = async (_params?: Record) => { loading.value = true; if (props.request) { const resp = await props.request({ pageIndex: 1, pageSize: 10, ...props.defaultParams, ..._params }); if (resp.code === 200) { if (props.type === 'PAGE') { // 判断如果是最后一页且最后一页为空,就跳转到前一页 if (resp.result.total && resp.result.size && resp.result.current && resp.result?.records?.length === 0) { handleSearch({ ..._params, pageSize: pageSize.value, pageIndex: pageIndex.value > 0 ? pageIndex.value - 1 : 0 }); } else { _dataSource.value = resp.result?.records || []; pageIndex.value = resp.result?.current || 1; pageSize.value = resp.result?.size || 10; total.value = resp.result?.total || 0; } } else { _dataSource.value = resp?.result || []; } } else { _dataSource.value = []; } } else { _dataSource.value = props?.dataSource || []; } loading.value = false; }; watch( () => props.params, (newValue) => { handleSearch(newValue); }, { deep: true, immediate: true } ); watch( () => props.dataSource, () => { if (props.dataSource && !props.request) { handleSearch(props.params); } }, { deep: true, immediate: true } ); onMounted(() => { windowChange(); // 初始化 window.onresize = () => { windowChange(); }; }); onUnmounted(() => { window.onresize = null; }); /** * 刷新数据 * @param _params */ const reload = (_params?: Record) => { handleSearch({ ..._params, pageSize: 10, pageIndex: 1 }); }; /** * 导出方法 */ expose({ reload, _dataSource }); return () => ( // @ts-ignore
{/* 顶部左边插槽 */} {slots.headerTitle && slots.headerTitle()}
{props.showRightExtra && (
{/* 顶部右边插槽 */} {slots.rightExtraRender && slots.rightExtraRender()} {!props.model && (
{ _model.value = ModelEnum.CARD; }}>
{ _model.value = ModelEnum.TABLE; }}>
)}
)}
{/* content */} {!loading.value ? (
{props.alertRender && props?.rowSelection && props?.rowSelection?.selectedRowKeys && props.rowSelection.selectedRowKeys?.length ? (
{ emit('cancelSelect'); }} closeText={取消选择} />
) : null} {_model.value === ModelEnum.CARD ? (
{_dataSource.value.length ? (
{_dataSource.value.map((item) => slots.card ?
{slots.card(item)}
: null )}
) : (
)}
) : (
) => { const { column, title } = dt; if (column?.headerCell) { return slots?.[column?.headerCell]!(column.title); } else { return title || ''; } }, bodyCell: (dt: Record) => { const { column, record } = dt; if ((column?.key || column?.dataIndex) && column?.scopedSlots && (slots?.[column?.dataIndex] || slots?.[column?.key])) { const _key = column?.key || column?.dataIndex; return slots?.[_key]!(record); } else { return record?.[column?.dataIndex] || ''; } }, emptyText: () => }} /> )} ) : (
)} {/* 分页 */} {!!_dataSource.value.length && !props.noPagination && props.type === 'PAGE' && (
{slots?.paginationRender ? ( slots.paginationRender() ) : ( { return `共 ${num} 条数据`; }} onChange={(page, size) => { handleSearch({ ...props.params, pageSize: size, pageIndex: page }); }} /> )}
)} ); } }); export default JTable;