123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317 |
- import type { BasicColumn, BasicTableProps, CellFormat, GetColumnsParams } from '../types/table';
- import type { PaginationProps } from '../types/pagination';
- import type { ComputedRef } from 'vue';
- import { computed, Ref, ref, reactive, toRaw, unref, watch } from 'vue';
- import { renderEditCell } from '../components/editable';
- import { usePermission } from '/@/hooks/web/usePermission';
- import { useI18n } from '/@/hooks/web/useI18n';
- import { isArray, isBoolean, isFunction, isMap, isString } from '/@/utils/is';
- import { cloneDeep, isEqual } from 'lodash-es';
- import { formatToDate } from '/@/utils/dateUtil';
- import { ACTION_COLUMN_FLAG, DEFAULT_ALIGN, INDEX_COLUMN_FLAG, PAGE_SIZE } from '../const';
- function handleItem(item: BasicColumn, ellipsis: boolean) {
- const { key, dataIndex, children } = item;
- item.align = item.align || DEFAULT_ALIGN;
- if (ellipsis) {
- if (!key) {
- item.key = dataIndex;
- }
- if (!isBoolean(item.ellipsis)) {
- Object.assign(item, {
- ellipsis,
- });
- }
- }
- if (children && children.length) {
- handleChildren(children, !!ellipsis);
- }
- }
- function handleChildren(children: BasicColumn[] | undefined, ellipsis: boolean) {
- if (!children) return;
- children.forEach((item) => {
- const { children } = item;
- handleItem(item, ellipsis);
- handleChildren(children, ellipsis);
- });
- }
- function handleIndexColumn(
- propsRef: ComputedRef<BasicTableProps>,
- getPaginationRef: ComputedRef<boolean | PaginationProps>,
- columns: BasicColumn[],
- ) {
- const { t } = useI18n();
- const { showIndexColumn, indexColumnProps, isTreeTable } = unref(propsRef);
- let pushIndexColumns = false;
- if (unref(isTreeTable)) {
- return;
- }
- columns.forEach(() => {
- const indIndex = columns.findIndex((column) => column.flag === INDEX_COLUMN_FLAG);
- if (showIndexColumn) {
- pushIndexColumns = indIndex === -1;
- } else if (!showIndexColumn && indIndex !== -1) {
- columns.splice(indIndex, 1);
- }
- });
- if (!pushIndexColumns) return;
- const isFixedLeft = columns.some((item) => item.fixed === 'left');
- columns.unshift({
- flag: INDEX_COLUMN_FLAG,
- width: 50,
- title: t('component.table.index'),
- align: 'center',
- customRender: ({ index }) => {
- const getPagination = unref(getPaginationRef);
- if (isBoolean(getPagination)) {
- return `${index + 1}`;
- }
- const { current = 1, pageSize = PAGE_SIZE } = getPagination;
- return ((current < 1 ? 1 : current) - 1) * pageSize + index + 1;
- },
- ...(isFixedLeft
- ? {
- fixed: 'left',
- }
- : {}),
- ...indexColumnProps,
- });
- }
- function handleActionColumn(propsRef: ComputedRef<BasicTableProps>, columns: BasicColumn[]) {
- const { actionColumn } = unref(propsRef);
- if (!actionColumn) return;
- const hasIndex = columns.findIndex((column) => column.flag === ACTION_COLUMN_FLAG);
- if (hasIndex === -1) {
- columns.push({
- ...columns[hasIndex],
- fixed: 'right',
- ...actionColumn,
- flag: ACTION_COLUMN_FLAG,
- });
- }
- }
- export function useColumns(
- propsRef: ComputedRef<BasicTableProps>,
- getPaginationRef: ComputedRef<boolean | PaginationProps>,
- ) {
- const columnsRef = ref(unref(propsRef).columns) as unknown as Ref<BasicColumn[]>;
- let cacheColumns = unref(propsRef).columns;
- const getColumnsRef = computed(() => {
- const columns = cloneDeep(unref(columnsRef));
- handleIndexColumn(propsRef, getPaginationRef, columns);
- handleActionColumn(propsRef, columns);
- if (!columns) {
- return [];
- }
- const { ellipsis } = unref(propsRef);
- columns.forEach((item) => {
- const { customRender, slots } = item;
- handleItem(
- item,
- Reflect.has(item, 'ellipsis') ? !!item.ellipsis : !!ellipsis && !customRender && !slots,
- );
- });
- return columns;
- });
- function isIfShow(column: BasicColumn): boolean {
- const ifShow = column.ifShow;
- let isIfShow = true;
- if (isBoolean(ifShow)) {
- isIfShow = ifShow;
- }
- if (isFunction(ifShow)) {
- isIfShow = ifShow(column);
- }
- return isIfShow;
- }
- const { hasPermission } = usePermission();
- const getViewColumns = computed(() => {
- const viewColumns = sortFixedColumn(unref(getColumnsRef));
- const columns = cloneDeep(viewColumns);
- return columns
- .filter((column) => {
- return hasPermission(column.auth) && isIfShow(column);
- })
- .map((column) => {
- const { slots, customRender, format, edit, editRow, flag } = column;
- if (!slots || !slots?.title) {
- // column.slots = { title: `header-${dataIndex}`, ...(slots || {}) };
- column.customTitle = column.title;
- Reflect.deleteProperty(column, 'title');
- }
- const isDefaultAction = [INDEX_COLUMN_FLAG, ACTION_COLUMN_FLAG].includes(flag!);
- if (!customRender && format && !edit && !isDefaultAction) {
- column.customRender = ({ text, record, index }) => {
- return formatCell(text, format, record, index);
- };
- }
- // edit table
- if ((edit || editRow) && !isDefaultAction) {
- column.customRender = renderEditCell(column);
- }
- return reactive(column);
- });
- });
- watch(
- () => unref(propsRef).columns,
- (columns) => {
- columnsRef.value = columns;
- cacheColumns = columns?.filter((item) => !item.flag) ?? [];
- },
- );
- function setCacheColumnsByField(dataIndex: string | undefined, value: Partial<BasicColumn>) {
- if (!dataIndex || !value) {
- return;
- }
- cacheColumns.forEach((item) => {
- if (item.dataIndex === dataIndex) {
- Object.assign(item, value);
- return;
- }
- });
- }
- /**
- * set columns
- * @param columnList key|column
- */
- function setColumns(columnList: Partial<BasicColumn>[] | (string | string[])[]) {
- const columns = cloneDeep(columnList);
- if (!isArray(columns)) return;
- if (columns.length <= 0) {
- columnsRef.value = [];
- return;
- }
- const firstColumn = columns[0];
- const cacheKeys = cacheColumns.map((item) => item.dataIndex);
- if (!isString(firstColumn) && !isArray(firstColumn)) {
- columnsRef.value = columns as BasicColumn[];
- } else {
- const columnKeys = (columns as (string | string[])[]).map((m) => m.toString());
- const newColumns: BasicColumn[] = [];
- cacheColumns.forEach((item) => {
- newColumns.push({
- ...item,
- defaultHidden: !columnKeys.includes(item.dataIndex?.toString() || (item.key as string)),
- });
- });
- // Sort according to another array
- if (!isEqual(cacheKeys, columns)) {
- newColumns.sort((prev, next) => {
- return (
- columnKeys.indexOf(prev.dataIndex?.toString() as string) -
- columnKeys.indexOf(next.dataIndex?.toString() as string)
- );
- });
- }
- columnsRef.value = newColumns;
- }
- }
- function getColumns(opt?: GetColumnsParams) {
- const { ignoreIndex, ignoreAction, sort } = opt || {};
- let columns = toRaw(unref(getColumnsRef));
- if (ignoreIndex) {
- columns = columns.filter((item) => item.flag !== INDEX_COLUMN_FLAG);
- }
- if (ignoreAction) {
- columns = columns.filter((item) => item.flag !== ACTION_COLUMN_FLAG);
- }
- if (sort) {
- columns = sortFixedColumn(columns);
- }
- return columns;
- }
- function getCacheColumns() {
- return cacheColumns;
- }
- return {
- getColumnsRef,
- getCacheColumns,
- getColumns,
- setColumns,
- getViewColumns,
- setCacheColumnsByField,
- };
- }
- function sortFixedColumn(columns: BasicColumn[]) {
- const fixedLeftColumns: BasicColumn[] = [];
- const fixedRightColumns: BasicColumn[] = [];
- const defColumns: BasicColumn[] = [];
- for (const column of columns) {
- if (column.fixed === 'left') {
- fixedLeftColumns.push(column);
- continue;
- }
- if (column.fixed === 'right') {
- fixedRightColumns.push(column);
- continue;
- }
- defColumns.push(column);
- }
- return [...fixedLeftColumns, ...defColumns, ...fixedRightColumns].filter(
- (item) => !item.defaultHidden,
- );
- }
- // format cell
- export function formatCell(text: string, format: CellFormat, record: Recordable, index: number) {
- if (!format) {
- return text;
- }
- // custom function
- if (isFunction(format)) {
- return format(text, record, index);
- }
- try {
- // date type
- const DATE_FORMAT_PREFIX = 'date|';
- if (isString(format) && format.startsWith(DATE_FORMAT_PREFIX) && text) {
- const dateFormat = format.replace(DATE_FORMAT_PREFIX, '');
- if (!dateFormat) {
- return text;
- }
- return formatToDate(text, dateFormat);
- }
- // Map
- if (isMap(format)) {
- return format.get(text);
- }
- } catch (error) {
- return text;
- }
- }
|