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 } from 'vue'; import type { JColumnsProps } from './types' import JEmpty from '@/components/Empty/index.vue' 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; 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' // 分页 ], emits: [ 'modelChange', // 切换卡片和表格 'reload' // 刷新数据 ], 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: [2, 3, 4] }, gridColumn: { type: Number, default: 4 }, alertRender: { type: Boolean, default: true }, type: { type: String, default: 'PAGE' }, defaultParams: { type: Object, default: () => { return { pageIndex: 0, pageSize: 12 } } }, scroll: { type: Object, default: () => { x: 1366 } } } as any, 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(6) 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 : 2; 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 : 3; column.value = props.gridColumns ? props.gridColumns[1] : _column } else if (window.innerWidth > 1600) { const _column = props.gridColumn && props.gridColumn < 4 ? props.gridColumn : 4; column.value = props.gridColumns ? props.gridColumns[2] : _column } } /** * 请求数据 */ const handleSearch = async (_params?: Record) => { loading.value = true if (props.request) { const resp = await props.request({ pageIndex: 0, pageSize: 12, ...props.defaultParams, ..._params, terms: [ ...(props.defaultParams?.terms || []), ...(_params?.terms || []) ] }) if (resp.status === 200) { if (props.type === 'PAGE') { // 判断如果是最后一页且最后一页为空,就跳转到前一页 if (resp.result.total && resp.result.pageSize && resp.result.pageIndex && resp.result?.data?.length === 0) { handleSearch({ ..._params, pageSize: pageSize.value, pageIndex: pageIndex.value > 0 ? pageIndex.value - 1 : 0, }) } else { _dataSource.value = resp.result?.data || [] pageIndex.value = resp.result?.pageIndex || 0 pageSize.value = resp.result?.pageSize || 6 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: 12, pageIndex: 0 }) } /** * 导出方法 */ expose({ reload, _dataSource }) return () =>
{/* 顶部左边插槽 */} {slots.headerTitle && slots.headerTitle()}
{/* 顶部右边插槽 */} {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() : { const minSize = pageIndex.value * pageSize.value + 1; const MaxSize = (pageIndex.value + 1) * pageSize.value; return `第 ${minSize} - ${MaxSize > num ? num : MaxSize} 条/总共 ${num} 条`; }} onChange={(page, size) => { handleSearch({ ...props.params, pageSize: size, pageIndex: pageSize.value === size ? (page ? page - 1 : 0) : 0 }) }} /> }
} } }) export default JTable