diff --git a/apps/web-antd/src/components/dept-select-modal/dept-select-modal.vue b/apps/web-antd/src/components/select-modal/dept-select-modal.vue similarity index 100% rename from apps/web-antd/src/components/dept-select-modal/dept-select-modal.vue rename to apps/web-antd/src/components/select-modal/dept-select-modal.vue diff --git a/apps/web-antd/src/components/dept-select-modal/index.ts b/apps/web-antd/src/components/select-modal/index.ts similarity index 50% rename from apps/web-antd/src/components/dept-select-modal/index.ts rename to apps/web-antd/src/components/select-modal/index.ts index d373be445..2b6e91893 100644 --- a/apps/web-antd/src/components/dept-select-modal/index.ts +++ b/apps/web-antd/src/components/select-modal/index.ts @@ -1 +1,2 @@ export { default as DeptSelectModal } from './dept-select-modal.vue'; +export { default as UserSelectModal } from './user-select-modal.vue'; diff --git a/apps/web-antd/src/components/user-select-modal/user-select-modal.vue b/apps/web-antd/src/components/select-modal/user-select-modal.vue similarity index 100% rename from apps/web-antd/src/components/user-select-modal/user-select-modal.vue rename to apps/web-antd/src/components/select-modal/user-select-modal.vue diff --git a/apps/web-antd/src/components/user-select-modal/index.ts b/apps/web-antd/src/components/user-select-modal/index.ts deleted file mode 100644 index 9cb1c93fd..000000000 --- a/apps/web-antd/src/components/user-select-modal/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default as UserSelectModal } from './user-select-modal.vue'; diff --git a/apps/web-antd/src/views/bpm/group/data.ts b/apps/web-antd/src/views/bpm/group/data.ts index 34c0926fb..0bd1fd252 100644 --- a/apps/web-antd/src/views/bpm/group/data.ts +++ b/apps/web-antd/src/views/bpm/group/data.ts @@ -123,8 +123,8 @@ export function useGridColumns( field: 'userIds', title: '成员', minWidth: 200, - formatter: (row) => { - return getMemberNames(row.cellValue); + formatter: ({ cellValue }) => { + return getMemberNames(cellValue); }, }, { diff --git a/apps/web-antd/src/views/bpm/model/form/modules/basic-info.vue b/apps/web-antd/src/views/bpm/model/form/modules/basic-info.vue index f31ad4d7c..485dcf470 100644 --- a/apps/web-antd/src/views/bpm/model/form/modules/basic-info.vue +++ b/apps/web-antd/src/views/bpm/model/form/modules/basic-info.vue @@ -22,9 +22,8 @@ import { Tooltip, } from 'ant-design-vue'; -import { DeptSelectModal } from '#/components/dept-select-modal'; +import { DeptSelectModal, UserSelectModal } from '#/components/select-modal'; import { ImageUpload } from '#/components/upload'; -import { UserSelectModal } from '#/components/user-select-modal'; import { DICT_TYPE, getBoolDictOptions, getIntDictOptions } from '#/utils'; const props = defineProps({ diff --git a/apps/web-antd/src/views/bpm/processInstance/detail/modules/time-line.vue b/apps/web-antd/src/views/bpm/processInstance/detail/modules/time-line.vue index 23b3aa217..6edd28af0 100644 --- a/apps/web-antd/src/views/bpm/processInstance/detail/modules/time-line.vue +++ b/apps/web-antd/src/views/bpm/processInstance/detail/modules/time-line.vue @@ -10,7 +10,7 @@ import { formatDateTime, isEmpty } from '@vben/utils'; import { Avatar, Button, Image, Timeline, Tooltip } from 'ant-design-vue'; -import { UserSelectModal } from '#/components/user-select-modal'; +import { UserSelectModal } from '#/components/select-modal'; import { BpmCandidateStrategyEnum, BpmNodeTypeEnum, diff --git a/apps/web-antd/src/views/bpm/task/done/data.ts b/apps/web-antd/src/views/bpm/task/done/data.ts index f69ceee22..fe59f9119 100644 --- a/apps/web-antd/src/views/bpm/task/done/data.ts +++ b/apps/web-antd/src/views/bpm/task/done/data.ts @@ -133,8 +133,8 @@ export function useGridColumns( field: 'durationInMillis', title: '耗时', minWidth: 180, - formatter: ({ row }) => { - return `${formatPast2(row.durationInMillis)}`; + formatter: ({ cellValue }) => { + return `${formatPast2(cellValue)}`; }, }, { diff --git a/apps/web-antd/src/views/bpm/task/manager/data.ts b/apps/web-antd/src/views/bpm/task/manager/data.ts index d06b6dc82..3c4a27e22 100644 --- a/apps/web-antd/src/views/bpm/task/manager/data.ts +++ b/apps/web-antd/src/views/bpm/task/manager/data.ts @@ -89,8 +89,8 @@ export function useGridColumns( field: 'durationInMillis', title: '耗时', minWidth: 180, - formatter: ({ row }) => { - return `${formatPast2(row.durationInMillis)}`; + formatter: ({ cellValue }) => { + return `${formatPast2(cellValue)}`; }, }, { diff --git a/apps/web-antd/src/views/crm/backlog/data.ts b/apps/web-antd/src/views/crm/backlog/data.ts index b56566f14..ef6047d0e 100644 --- a/apps/web-antd/src/views/crm/backlog/data.ts +++ b/apps/web-antd/src/views/crm/backlog/data.ts @@ -2,7 +2,6 @@ import type { Ref } from 'vue'; import type { VbenFormSchema } from '#/adapter/form'; import type { OnActionClickFn, VxeTableGridOptions } from '#/adapter/vxe-table'; -import type { CrmContractApi } from '#/api/crm/contract'; import type { CrmReceivableApi } from '#/api/crm/receivable'; import { useAccess } from '@vben/access'; @@ -133,14 +132,12 @@ export function useClueFollowColumns(): VxeTableGridOptions['columns'] { { field: 'name', title: '线索名称', - minWidth: 160, fixed: 'left', slots: { default: 'name' }, }, { field: 'source', title: '线索来源', - minWidth: 100, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.CRM_CUSTOMER_SOURCE }, @@ -149,27 +146,22 @@ export function useClueFollowColumns(): VxeTableGridOptions['columns'] { { field: 'mobile', title: '手机', - minWidth: 120, }, { field: 'telephone', title: '电话', - minWidth: 130, }, { field: 'email', title: '邮箱', - minWidth: 180, }, { field: 'detailAddress', title: '地址', - minWidth: 180, }, { field: 'industryId', title: '客户行业', - minWidth: 100, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.CRM_CUSTOMER_INDUSTRY }, @@ -178,7 +170,6 @@ export function useClueFollowColumns(): VxeTableGridOptions['columns'] { { field: 'level', title: '客户级别', - minWidth: 100, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.CRM_CUSTOMER_LEVEL }, @@ -187,51 +178,42 @@ export function useClueFollowColumns(): VxeTableGridOptions['columns'] { { field: 'contactNextTime', title: '下次联系时间', - minWidth: 180, formatter: 'formatDateTime', }, { field: 'remark', title: '备注', - minWidth: 200, }, { field: 'contactLastTime', title: '最后跟进时间', - minWidth: 180, formatter: 'formatDateTime', }, { field: 'contactLastContent', title: '最后跟进记录', - minWidth: 200, }, { field: 'ownerUserName', title: '负责人', - minWidth: 100, }, { field: 'ownerUserDeptName', title: '所属部门', - minWidth: 100, }, { field: 'updateTime', title: '更新时间', - minWidth: 180, formatter: 'formatDateTime', }, { field: 'createTime', title: '创建时间', - minWidth: 180, formatter: 'formatDateTime', }, { field: 'creatorName', title: '创建人', - minWidth: 100, }, ]; } @@ -269,156 +251,111 @@ export function useContractRemindFormSchema(): VbenFormSchema[] { } /** 合同审核列表的字段 */ -export function useContractColumns( - onActionClick: OnActionClickFn, -): VxeTableGridOptions['columns'] { +export function useContractColumns(): VxeTableGridOptions['columns'] { return [ { field: 'no', title: '合同编号', - minWidth: 160, fixed: 'left', }, { field: 'name', title: '合同名称', - minWidth: 160, - slots: { - default: 'name', - }, + slots: { default: 'name' }, }, { field: 'customerName', title: '客户名称', - minWidth: 160, - slots: { - default: 'customerName', - }, + slots: { default: 'customerName' }, }, { field: 'businessName', title: '商机名称', - minWidth: 160, - slots: { - default: 'businessName', - }, + slots: { default: 'businessName' }, }, { field: 'price', title: '合同金额(元)', - minWidth: 120, formatter: 'formatNumber', }, { field: 'orderDate', title: '下单时间', - minWidth: 120, formatter: 'formatDateTime', }, { field: 'startTime', title: '合同开始时间', - minWidth: 120, formatter: 'formatDateTime', }, { field: 'endTime', title: '合同结束时间', - minWidth: 120, formatter: 'formatDateTime', }, { field: 'contactName', title: '客户签约人', - minWidth: 130, - slots: { - default: 'contactName', - }, + slots: { default: 'contactName' }, }, { field: 'signUserName', title: '公司签约人', - minWidth: 130, }, { field: 'remark', title: '备注', - minWidth: 200, }, { field: 'totalReceivablePrice', title: '已回款金额(元)', - minWidth: 140, formatter: 'formatNumber', }, { field: 'noReceivablePrice', title: '未回款金额(元)', - minWidth: 120, formatter: 'formatNumber', }, { field: 'contactLastTime', title: '最后跟进时间', - minWidth: 180, formatter: 'formatDateTime', }, { field: 'ownerUserName', title: '负责人', - minWidth: 120, }, { field: 'ownerUserDeptName', title: '所属部门', - minWidth: 100, }, { field: 'updateTime', title: '更新时间', - minWidth: 180, formatter: 'formatDateTime', }, { field: 'createTime', title: '创建时间', - minWidth: 180, formatter: 'formatDateTime', }, { field: 'creatorName', title: '创建人', - minWidth: 100, }, { field: 'auditStatus', title: '合同状态', - minWidth: 120, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.CRM_AUDIT_STATUS }, }, }, { - field: 'operation', title: '操作', - minWidth: 130, - align: 'center', + width: 80, fixed: 'right', - cellRender: { - attrs: { - nameField: 'no', - nameTitle: '合同编号', - onClick: onActionClick, - }, - name: 'CellOperation', - options: [ - { - code: 'processDetail', - show: hasAccessByCodes(['crm:contract:update']), - }, - ], - }, + slots: { default: 'actions' }, }, ]; } @@ -487,15 +424,11 @@ export function useCustomerColumns(): VxeTableGridOptions['columns'] { { field: 'name', title: '客户名称', - minWidth: 160, - slots: { - default: 'name', - }, + slots: { default: 'name' }, }, { field: 'source', title: '客户来源', - minWidth: 100, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.CRM_CUSTOMER_SOURCE }, @@ -504,22 +437,18 @@ export function useCustomerColumns(): VxeTableGridOptions['columns'] { { field: 'mobile', title: '手机', - minWidth: 120, }, { field: 'telephone', title: '电话', - minWidth: 130, }, { field: 'email', title: '邮箱', - minWidth: 180, }, { field: 'level', title: '客户级别', - minWidth: 100, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.CRM_CUSTOMER_LEVEL }, @@ -528,7 +457,6 @@ export function useCustomerColumns(): VxeTableGridOptions['columns'] { { field: 'industryId', title: '客户行业', - minWidth: 100, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.CRM_CUSTOMER_INDUSTRY }, @@ -537,18 +465,15 @@ export function useCustomerColumns(): VxeTableGridOptions['columns'] { { field: 'contactNextTime', title: '下次联系时间', - minWidth: 180, formatter: 'formatDateTime', }, { field: 'remark', title: '备注', - minWidth: 200, }, { field: 'lockStatus', title: '锁定状态', - minWidth: 100, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.INFRA_BOOLEAN_STRING }, @@ -557,7 +482,6 @@ export function useCustomerColumns(): VxeTableGridOptions['columns'] { { field: 'dealStatus', title: '成交状态', - minWidth: 100, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.INFRA_BOOLEAN_STRING }, @@ -566,50 +490,41 @@ export function useCustomerColumns(): VxeTableGridOptions['columns'] { { field: 'contactLastTime', title: '最后跟进时间', - minWidth: 180, formatter: 'formatDateTime', }, { field: 'contactLastContent', title: '最后跟进记录', - minWidth: 200, }, { field: 'detailAddress', title: '地址', - minWidth: 200, }, { field: 'poolDay', title: '距离进入公海天数', - minWidth: 180, }, { field: 'ownerUserName', title: '负责人', - minWidth: 100, }, { field: 'ownerUserDeptName', title: '所属部门', - minWidth: 100, }, { field: 'updateTime', title: '更新时间', - minWidth: 180, formatter: 'formatDateTime', }, { field: 'createTime', title: '创建时间', - minWidth: 180, formatter: 'formatDateTime', }, { field: 'creatorName', title: '创建人', - minWidth: 100, }, ]; } @@ -638,44 +553,32 @@ export function useReceivableAuditColumns( { field: 'no', title: '回款编号', - minWidth: 180, fixed: 'left', - slots: { - default: 'no', - }, + slots: { default: 'no' }, }, { field: 'customerName', title: '客户名称', - minWidth: 120, - slots: { - default: 'customerName', - }, + slots: { default: 'customerName' }, }, { field: 'contractNo', title: '合同编号', - minWidth: 180, - slots: { - default: 'contractNo', - }, + slots: { default: 'contractNo' }, }, { field: 'returnTime', title: '回款日期', - minWidth: 150, formatter: 'formatDateTime', }, { field: 'price', title: '回款金额(元)', - minWidth: 140, formatter: 'formatNumber', }, { field: 'returnType', title: '回款方式', - minWidth: 130, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.CRM_RECEIVABLE_RETURN_TYPE }, @@ -684,45 +587,37 @@ export function useReceivableAuditColumns( { field: 'remark', title: '备注', - minWidth: 200, }, { field: 'contract.totalPrice', title: '合同金额(元)', - minWidth: 140, formatter: 'formatNumber', }, { field: 'ownerUserName', title: '负责人', - minWidth: 120, }, { field: 'ownerUserDeptName', title: '所属部门', - minWidth: 100, }, { field: 'updateTime', title: '更新时间', - minWidth: 180, formatter: 'formatDateTime', }, { field: 'createTime', title: '创建时间', - minWidth: 180, formatter: 'formatDateTime', }, { field: 'creatorName', title: '创建人', - minWidth: 120, }, { field: 'auditStatus', title: '回款状态', - minWidth: 120, fixed: 'right', cellRender: { name: 'CellDict', @@ -778,52 +673,40 @@ export function useReceivablePlanRemindColumns( { field: 'customerName', title: '客户名称', - minWidth: 160, fixed: 'left', - slots: { - default: 'customerName', - }, + slots: { default: 'customerName' }, }, { field: 'contractNo', title: '合同编号', - minWidth: 200, }, { field: 'period', title: '期数', - minWidth: 160, - slots: { - default: 'period', - }, + slots: { default: 'period' }, }, { field: 'price', title: '计划回款金额(元)', - minWidth: 120, formatter: 'formatNumber', }, { field: 'returnTime', title: '计划回款日期', - minWidth: 180, formatter: 'formatDateTime', }, { field: 'remindDays', title: '提前几天提醒', - minWidth: 150, }, { field: 'remindTime', title: '提醒日期', - minWidth: 180, formatter: 'formatDateTime', }, { field: 'returnType', title: '回款方式', - minWidth: 120, fixed: 'right', cellRender: { name: 'CellDict', @@ -833,41 +716,34 @@ export function useReceivablePlanRemindColumns( { field: 'remark', title: '备注', - minWidth: 200, }, { field: 'ownerUserName', title: '负责人', - minWidth: 100, }, { field: 'receivable.price', title: '实际回款金额(元)', - minWidth: 160, formatter: 'formatNumber', }, { field: 'receivable.returnTime', title: '实际回款日期', - minWidth: 180, formatter: 'formatDateTime', }, { field: 'updateTime', title: '更新时间', - minWidth: 180, formatter: 'formatDateTime', }, { field: 'createTime', title: '创建时间', - minWidth: 180, formatter: 'formatDateTime', }, { field: 'creatorName', title: '创建人', - minWidth: 100, }, { field: 'operation', diff --git a/apps/web-antd/src/views/crm/backlog/index.vue b/apps/web-antd/src/views/crm/backlog/index.vue index 971814f55..1f8b7a62a 100644 --- a/apps/web-antd/src/views/crm/backlog/index.vue +++ b/apps/web-antd/src/views/crm/backlog/index.vue @@ -13,8 +13,8 @@ import * as ReceivablePlanApi from '#/api/crm/receivable/plan'; import { DocAlert } from '#/components/doc-alert'; import { useLeftSides } from './data'; -import ClueFollowList from './modules/ClueFollowList.vue'; -import ContractAuditList from './modules/ContractAuditList.vue'; +import ClueFollowList from './modules/clue-follow-list.vue'; +import ContractAuditList from './modules/contract-audit-list.vue'; import ContractRemindList from './modules/ContractRemindList.vue'; import CustomerFollowList from './modules/CustomerFollowList.vue'; import CustomerPutPoolRemindList from './modules/CustomerPutPoolRemindList.vue'; diff --git a/apps/web-antd/src/views/crm/backlog/modules/ClueFollowList.vue b/apps/web-antd/src/views/crm/backlog/modules/clue-follow-list.vue similarity index 91% rename from apps/web-antd/src/views/crm/backlog/modules/ClueFollowList.vue rename to apps/web-antd/src/views/crm/backlog/modules/clue-follow-list.vue index 23d109c94..60ca44d9b 100644 --- a/apps/web-antd/src/views/crm/backlog/modules/ClueFollowList.vue +++ b/apps/web-antd/src/views/crm/backlog/modules/clue-follow-list.vue @@ -14,7 +14,7 @@ import { useClueFollowColumns, useClueFollowFormSchema } from '../data'; const { push } = useRouter(); /** 打开线索详情 */ -function onDetail(row: CrmClueApi.Clue) { +function handleDetail(row: CrmClueApi.Clue) { push({ name: 'CrmClueDetail', params: { id: row.id } }); } @@ -52,7 +52,7 @@ const [Grid] = useVbenVxeGrid({ diff --git a/apps/web-antd/src/views/crm/backlog/modules/ContractAuditList.vue b/apps/web-antd/src/views/crm/backlog/modules/contract-audit-list.vue similarity index 66% rename from apps/web-antd/src/views/crm/backlog/modules/ContractAuditList.vue rename to apps/web-antd/src/views/crm/backlog/modules/contract-audit-list.vue index a243bfe58..f9048a24c 100644 --- a/apps/web-antd/src/views/crm/backlog/modules/ContractAuditList.vue +++ b/apps/web-antd/src/views/crm/backlog/modules/contract-audit-list.vue @@ -1,13 +1,12 @@ diff --git a/apps/web-antd/src/views/crm/contact/modules/form.vue b/apps/web-antd/src/views/crm/contact/modules/form.vue new file mode 100644 index 000000000..d6a822d66 --- /dev/null +++ b/apps/web-antd/src/views/crm/contact/modules/form.vue @@ -0,0 +1,81 @@ + + + diff --git a/apps/web-antd/src/views/crm/contract/config/index.vue b/apps/web-antd/src/views/crm/contract/config/index.vue index db64ed742..d0dcd1aff 100644 --- a/apps/web-antd/src/views/crm/contract/config/index.vue +++ b/apps/web-antd/src/views/crm/contract/config/index.vue @@ -1,38 +1,104 @@ diff --git a/apps/web-antd/src/views/crm/contract/data.ts b/apps/web-antd/src/views/crm/contract/data.ts new file mode 100644 index 000000000..32847eb3b --- /dev/null +++ b/apps/web-antd/src/views/crm/contract/data.ts @@ -0,0 +1,276 @@ +import type { VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; + +import { getSimpleBusinessList } from '#/api/crm/business'; +import { getSimpleContactList } from '#/api/crm/contact'; +import { getCustomerSimpleList } from '#/api/crm/customer'; +import { floatToFixed2 } from '#/utils'; +import { DICT_TYPE } from '#/utils/dict'; + +/** 新增/修改的表单 */ +export function useFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'no', + label: '合同编号', + component: 'Input', + rules: 'required', + componentProps: { + placeholder: '请输入合同编号', + }, + }, + { + fieldName: 'name', + label: '合同名称', + component: 'Input', + rules: 'required', + componentProps: { + placeholder: '请输入合同名称', + }, + }, + { + fieldName: 'customerId', + label: '客户', + component: 'ApiSelect', + rules: 'required', + componentProps: { + api: getCustomerSimpleList, + labelField: 'name', + valueField: 'id', + placeholder: '请选择客户', + }, + }, + { + fieldName: 'businessId', + label: '商机', + component: 'ApiSelect', + rules: 'required', + componentProps: { + api: getSimpleBusinessList, + labelField: 'name', + valueField: 'id', + placeholder: '请选择商机', + }, + }, + { + fieldName: 'totalPrice', + label: '合同金额', + component: 'InputNumber', + rules: 'required', + componentProps: { + placeholder: '请输入合同金额', + min: 0, + precision: 2, + }, + }, + { + fieldName: 'orderDate', + label: '下单时间', + component: 'DatePicker', + rules: 'required', + componentProps: { + placeholder: '请选择下单时间', + }, + }, + { + fieldName: 'startTime', + label: '合同开始时间', + component: 'DatePicker', + rules: 'required', + componentProps: { + placeholder: '请选择合同开始时间', + }, + }, + { + fieldName: 'endTime', + label: '合同结束时间', + component: 'DatePicker', + rules: 'required', + componentProps: { + placeholder: '请选择合同结束时间', + }, + }, + { + fieldName: 'signContactId', + label: '客户签约人', + component: 'ApiSelect', + rules: 'required', + componentProps: { + api: getSimpleContactList, + labelField: 'name', + valueField: 'id', + placeholder: '请选择客户签约人', + }, + }, + { + fieldName: 'remark', + label: '备注', + component: 'Textarea', + componentProps: { + placeholder: '请输入备注', + rows: 4, + }, + }, + ]; +} + +/** 列表的搜索表单 */ +export function useGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'no', + label: '合同编号', + component: 'Input', + }, + { + fieldName: 'name', + label: '合同名称', + component: 'Input', + }, + { + fieldName: 'customerId', + label: '客户', + component: 'ApiSelect', + componentProps: { + api: getCustomerSimpleList, + labelField: 'name', + valueField: 'id', + placeholder: '请选择客户', + }, + }, + ]; +} + +export function useGridColumns(): VxeTableGridOptions['columns'] { + return [ + { + title: '合同编号', + field: 'no', + width: 150, + fixed: 'left', + }, + { + title: '合同名称', + field: 'name', + width: 150, + fixed: 'left', + slots: { default: 'name' }, + }, + { + title: '客户名称', + field: 'customerName', + width: 150, + slots: { default: 'customerName' }, + }, + { + title: '商机名称', + field: 'businessName', + width: 150, + slots: { default: 'businessName' }, + }, + { + title: '合同金额(元)', + field: 'totalPrice', + width: 150, + formatter: 'formatNumber', + }, + { + title: '下单时间', + field: 'orderDate', + width: 150, + formatter: 'formatDateTime', + }, + { + title: '合同开始时间', + field: 'startTime', + width: 150, + formatter: 'formatDateTime', + }, + { + title: '合同结束时间', + field: 'endTime', + width: 150, + formatter: 'formatDateTime', + }, + { + title: '客户签约人', + field: 'signContactName', + width: 150, + slots: { default: 'signContactName' }, + }, + { + title: '公司签约人', + field: 'signUserName', + width: 150, + }, + { + title: '已回款金额(元)', + field: 'totalReceivablePrice', + width: 150, + formatter: 'formatNumber', + }, + { + title: '未回款金额(元)', + field: 'unpaidPrice', + width: 150, + formatter: ({ row }) => { + return floatToFixed2(row.totalPrice - row.totalReceivablePrice); + }, + }, + { + title: '最后跟进时间', + field: 'contactLastTime', + width: 150, + formatter: 'formatDateTime', + }, + { + title: '负责人', + field: 'ownerUserName', + width: 150, + }, + { + title: '所属部门', + field: 'ownerUserDeptName', + width: 150, + }, + { + title: '更新时间', + field: 'updateTime', + width: 150, + formatter: 'formatDateTime', + }, + { + title: '创建时间', + field: 'createTime', + width: 150, + formatter: 'formatDateTime', + }, + { + title: '创建人', + field: 'creatorName', + width: 150, + }, + { + title: '备注', + field: 'remark', + width: 150, + }, + { + title: '合同状态', + field: 'auditStatus', + fixed: 'right', + width: 100, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.CRM_AUDIT_STATUS }, + }, + }, + { + title: '操作', + field: 'actions', + fixed: 'right', + width: 130, + slots: { default: 'actions' }, + }, + ]; +} diff --git a/apps/web-antd/src/views/crm/contract/index.vue b/apps/web-antd/src/views/crm/contract/index.vue index 6622d144a..9d306627f 100644 --- a/apps/web-antd/src/views/crm/contract/index.vue +++ b/apps/web-antd/src/views/crm/contract/index.vue @@ -1,38 +1,265 @@ diff --git a/apps/web-antd/src/views/crm/contract/modules/form.vue b/apps/web-antd/src/views/crm/contract/modules/form.vue new file mode 100644 index 000000000..5d2b0b78a --- /dev/null +++ b/apps/web-antd/src/views/crm/contract/modules/form.vue @@ -0,0 +1,85 @@ + + + diff --git a/apps/web-antd/src/views/crm/customer/data.ts b/apps/web-antd/src/views/crm/customer/data.ts index c1f505a48..551569da0 100644 --- a/apps/web-antd/src/views/crm/customer/data.ts +++ b/apps/web-antd/src/views/crm/customer/data.ts @@ -1,11 +1,9 @@ import type { VbenFormSchema } from '#/adapter/form'; -import type { OnActionClickFn, VxeTableGridOptions } from '#/adapter/vxe-table'; -import type { CrmCustomerApi } from '#/api/crm/customer'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; import type { DescriptionItemSchema } from '#/components/description'; import { h } from 'vue'; -import { useAccess } from '@vben/access'; import { formatDateTime } from '@vben/utils'; import { getAreaTree } from '#/api/system/area'; @@ -13,8 +11,6 @@ import { getSimpleUserList } from '#/api/system/user'; import { DictTag } from '#/components/dict-tag'; import { DICT_TYPE, getDictOptions, getRangePickerDefaultProps } from '#/utils'; -const { hasAccessByCodes } = useAccess(); - /** 新增/修改的表单 */ export function useFormSchema(): VbenFormSchema[] { return [ @@ -158,14 +154,11 @@ export function useGridFormSchema(): VbenFormSchema[] { } /** 列表的字段 */ -export function useGridColumns( - onActionClick: OnActionClickFn, -): VxeTableGridOptions['columns'] { +export function useGridColumns(): VxeTableGridOptions['columns'] { return [ { field: 'name', title: '客户名称', - minWidth: 160, fixed: 'left', slots: { default: 'name', @@ -174,7 +167,6 @@ export function useGridColumns( { field: 'source', title: '客户来源', - minWidth: 100, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.CRM_CUSTOMER_SOURCE }, @@ -183,27 +175,22 @@ export function useGridColumns( { field: 'mobile', title: '手机', - minWidth: 120, }, { field: 'telephone', title: '电话', - minWidth: 130, }, { field: 'email', title: '邮箱', - minWidth: 180, }, { field: 'detailAddress', title: '地址', - minWidth: 180, }, { field: 'industryId', title: '客户行业', - minWidth: 100, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.CRM_CUSTOMER_INDUSTRY }, @@ -212,7 +199,6 @@ export function useGridColumns( { field: 'level', title: '客户级别', - minWidth: 100, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.CRM_CUSTOMER_LEVEL }, @@ -221,61 +207,36 @@ export function useGridColumns( { field: 'ownerUserName', title: '负责人', - minWidth: 100, }, { field: 'ownerUserDeptName', title: '所属部门', - minWidth: 100, }, { field: 'contactNextTime', title: '下次联系时间', - minWidth: 180, formatter: 'formatDateTime', }, { field: 'contactLastTime', title: '最后跟进时间', - minWidth: 180, formatter: 'formatDateTime', }, { field: 'updateTime', title: '更新时间', - minWidth: 180, formatter: 'formatDateTime', }, { field: 'createTime', title: '创建时间', - minWidth: 180, formatter: 'formatDateTime', }, { - field: 'operation', title: '操作', - width: 130, + width: 180, fixed: 'right', - align: 'center', - cellRender: { - attrs: { - nameField: 'name', - nameTitle: '线索', - onClick: onActionClick, - }, - name: 'CellOperation', - options: [ - { - code: 'edit', - show: hasAccessByCodes(['crm:clue:update']), - }, - { - code: 'delete', - show: hasAccessByCodes(['crm:clue:delete']), - }, - ], - }, + slots: { default: 'actions' }, }, ]; } diff --git a/apps/web-antd/src/views/crm/customer/index.vue b/apps/web-antd/src/views/crm/customer/index.vue index df3c8e7ee..5795fdb0c 100644 --- a/apps/web-antd/src/views/crm/customer/index.vue +++ b/apps/web-antd/src/views/crm/customer/index.vue @@ -1,20 +1,16 @@ diff --git a/apps/web-antd/src/views/crm/customer/poolConfig/index.vue b/apps/web-antd/src/views/crm/customer/poolConfig/index.vue index 717d8cbec..75244ab15 100644 --- a/apps/web-antd/src/views/crm/customer/poolConfig/index.vue +++ b/apps/web-antd/src/views/crm/customer/poolConfig/index.vue @@ -1,38 +1,154 @@ diff --git a/apps/web-antd/src/views/crm/product/data.ts b/apps/web-antd/src/views/crm/product/data.ts index 592460a61..348afb372 100644 --- a/apps/web-antd/src/views/crm/product/data.ts +++ b/apps/web-antd/src/views/crm/product/data.ts @@ -1,7 +1,10 @@ import type { VbenFormSchema } from '#/adapter/form'; import type { VxeTableGridOptions } from '#/adapter/vxe-table'; +import { handleTree } from '@vben/utils'; + import { z } from '#/adapter/form'; +import { getProductCategoryList } from '#/api/crm/product/category'; import { CommonStatusEnum, DICT_TYPE, getDictOptions } from '#/utils'; /** 新增/修改的表单 */ @@ -28,17 +31,24 @@ export function useFormSchema(): VbenFormSchema[] { rules: 'required', }, { - component: 'Input', + component: 'ApiTreeSelect', fieldName: 'categoryName', label: '产品类型', rules: 'required', + componentProps: { + api: async () => { + const data = await getProductCategoryList(); + return handleTree(data); + }, + fieldNames: { label: 'name', value: 'id', children: 'children' }, + }, }, { fieldName: 'unit', label: '产品单位', component: 'Select', componentProps: { - options: getDictOptions(DICT_TYPE.CRM_PRODUCT_UNIT), + options: getDictOptions(DICT_TYPE.CRM_PRODUCT_UNIT, 'number'), }, rules: 'required', }, diff --git a/apps/web-antd/src/views/crm/receivable/data.ts b/apps/web-antd/src/views/crm/receivable/data.ts new file mode 100644 index 000000000..cbbc5c25f --- /dev/null +++ b/apps/web-antd/src/views/crm/receivable/data.ts @@ -0,0 +1,269 @@ +import type { VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; + +import { getContractSimpleList } from '#/api/crm/contract'; +import { getCustomerSimpleList } from '#/api/crm/customer'; +import { getReceivablePlanSimpleList } from '#/api/crm/receivable/plan'; +import { getSimpleUserList } from '#/api/system/user'; +import { DICT_TYPE, getDictOptions } from '#/utils/dict'; + +/** 新增/修改的表单 */ +export function useFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'id', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'no', + label: '回款编号', + component: 'Input', + rules: 'required', + componentProps: { + placeholder: '保存时自动生成', + disabled: true, + }, + }, + { + fieldName: 'ownerUserId', + label: '负责人', + component: 'ApiSelect', + rules: 'required', + componentProps: { + api: getSimpleUserList, + labelField: 'nickname', + valueField: 'id', + placeholder: '请选择客户', + }, + }, + { + fieldName: 'customerId', + label: '客户名称', + component: 'ApiSelect', + rules: 'required', + componentProps: { + api: getCustomerSimpleList, + labelField: 'name', + valueField: 'id', + placeholder: '请选择客户', + }, + }, + { + fieldName: 'contractId', + label: '合同名称', + component: 'Select', + rules: 'required', + dependencies: { + triggerFields: ['customerId'], + disabled: (values) => !values.customerId, + async componentProps(values) { + if (values.customerId) { + values.contractId = undefined; + const contracts = await getContractSimpleList(values.customerId); + return { + options: contracts.map((item) => ({ + label: item.name, + value: item.id, + disabled: item.auditStatus === 20, + })), + placeholder: '请选择合同', + } as any; + } + }, + }, + }, + { + fieldName: 'planId', + label: '回款期数', + component: 'Select', + rules: 'required', + dependencies: { + triggerFields: ['contractId'], + disabled: (values) => !values.contractId, + async componentProps(values) { + if (values.contractId) { + values.planId = undefined; + const plans = await getReceivablePlanSimpleList( + values.customerId, + values.contractId, + ); + return { + options: plans.map((item) => ({ + label: item.period, + value: item.id, + })), + placeholder: '请选择回款期数', + } as any; + } + }, + }, + }, + { + fieldName: 'returnTime', + label: '回款日期', + component: 'DatePicker', + componentProps: { + placeholder: '请选择回款日期', + showTime: false, + valueFormat: 'x', + format: 'YYYY-MM-DD', + }, + }, + { + fieldName: 'price', + label: '回款金额', + component: 'InputNumber', + rules: 'required', + componentProps: { + placeholder: '请输入回款金额', + min: 0, + precision: 2, + }, + }, + { + fieldName: 'returnType', + label: '回款方式', + component: 'Select', + rules: 'required', + componentProps: { + options: getDictOptions(DICT_TYPE.CRM_RECEIVABLE_RETURN_TYPE, 'number'), + placeholder: '请选择回款方式', + }, + }, + { + fieldName: 'remark', + label: '备注', + component: 'Textarea', + componentProps: { + placeholder: '请输入备注', + rows: 4, + }, + }, + ]; +} + +/** 列表的搜索表单 */ +export function useGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'no', + label: '回款编号', + component: 'Input', + }, + { + fieldName: 'customerId', + label: '客户', + component: 'ApiSelect', + componentProps: { + api: getCustomerSimpleList, + labelField: 'name', + valueField: 'id', + placeholder: '请选择客户', + }, + }, + ]; +} + +export function useGridColumns(): VxeTableGridOptions['columns'] { + return [ + { + title: '回款编号', + field: 'no', + width: 150, + fixed: 'left', + slots: { default: 'no' }, + }, + { + title: '客户名称', + field: 'customerName', + width: 150, + slots: { default: 'customerName' }, + }, + { + title: '合同编号', + field: 'contract', + width: 150, + slots: { default: 'contractNo' }, + }, + { + title: '回款日期', + field: 'returnTime', + width: 150, + formatter: 'formatDateTime', + }, + { + title: '回款金额(元)', + field: 'price', + width: 150, + formatter: 'formatNumber', + }, + { + title: '回款方式', + field: 'returnType', + width: 150, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.CRM_RECEIVABLE_RETURN_TYPE }, + }, + }, + { + title: '备注', + field: 'remark', + width: 150, + }, + { + title: '合同金额(元)', + field: 'contract.totalPrice', + width: 150, + formatter: 'formatNumber', + }, + { + title: '负责人', + field: 'ownerUserName', + width: 150, + }, + { + title: '所属部门', + field: 'ownerUserDeptName', + width: 150, + }, + { + title: '更新时间', + field: 'updateTime', + width: 150, + formatter: 'formatDateTime', + }, + { + title: '创建时间', + field: 'createTime', + width: 150, + formatter: 'formatDateTime', + }, + { + title: '创建人', + field: 'creatorName', + width: 150, + }, + { + title: '回款状态', + field: 'auditStatus', + width: 100, + fixed: 'right', + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.CRM_AUDIT_STATUS }, + }, + }, + { + title: '操作', + field: 'actions', + width: 130, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} diff --git a/apps/web-antd/src/views/crm/receivable/index.vue b/apps/web-antd/src/views/crm/receivable/index.vue index 016c4968a..ff187d968 100644 --- a/apps/web-antd/src/views/crm/receivable/index.vue +++ b/apps/web-antd/src/views/crm/receivable/index.vue @@ -1,38 +1,255 @@ diff --git a/apps/web-antd/src/views/crm/receivable/modules/form.vue b/apps/web-antd/src/views/crm/receivable/modules/form.vue new file mode 100644 index 000000000..e92610c25 --- /dev/null +++ b/apps/web-antd/src/views/crm/receivable/modules/form.vue @@ -0,0 +1,103 @@ + + + diff --git a/apps/web-antd/src/views/crm/receivable/plan/data.ts b/apps/web-antd/src/views/crm/receivable/plan/data.ts new file mode 100644 index 000000000..cc76b1eeb --- /dev/null +++ b/apps/web-antd/src/views/crm/receivable/plan/data.ts @@ -0,0 +1,229 @@ +import type { VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; + +import { getCustomerSimpleList } from '#/api/crm/customer'; +import { DICT_TYPE, getDictOptions } from '#/utils/dict'; + +/** 新增/修改的表单 */ +export function useFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'customerId', + label: '客户', + component: 'ApiSelect', + rules: 'required', + componentProps: { + api: getCustomerSimpleList, + labelField: 'name', + valueField: 'id', + placeholder: '请选择客户', + }, + }, + { + fieldName: 'contractId', + label: '合同', + component: 'ApiSelect', + rules: 'required', + componentProps: { + api: getCustomerSimpleList, + labelField: 'name', + valueField: 'id', + placeholder: '请选择合同', + }, + }, + { + fieldName: 'period', + label: '期数', + component: 'Input', + componentProps: { + placeholder: '保存时自动生成', + disabled: true, + }, + }, + { + fieldName: 'price', + label: '计划回款金额', + component: 'InputNumber', + rules: 'required', + componentProps: { + placeholder: '请输入计划回款金额', + min: 0, + precision: 2, + }, + }, + { + fieldName: 'returnTime', + label: '计划回款日期', + component: 'DatePicker', + rules: 'required', + componentProps: { + placeholder: '请选择计划回款日期', + }, + }, + { + fieldName: 'remindDays', + label: '提前几天提醒', + component: 'InputNumber', + rules: 'required', + componentProps: { + placeholder: '请输入提前几天提醒', + min: 0, + }, + }, + { + fieldName: 'returnType', + label: '回款方式', + component: 'Select', + rules: 'required', + componentProps: { + options: getDictOptions(DICT_TYPE.CRM_RECEIVABLE_RETURN_TYPE, 'number'), + placeholder: '请选择回款方式', + }, + }, + { + fieldName: 'remark', + label: '备注', + component: 'Textarea', + componentProps: { + placeholder: '请输入备注', + rows: 4, + }, + }, + ]; +} + +/** 列表的搜索表单 */ +export function useGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'customerId', + label: '客户', + component: 'ApiSelect', + componentProps: { + api: getCustomerSimpleList, + labelField: 'name', + valueField: 'id', + placeholder: '请选择客户', + }, + }, + { + fieldName: 'contractNo', + label: '合同编号', + component: 'Input', + componentProps: { + placeholder: '请输入合同编号', + }, + }, + ]; +} + +export function useGridColumns(): VxeTableGridOptions['columns'] { + return [ + { + title: '客户名称', + field: 'customerName', + width: 150, + fixed: 'left', + slots: { default: 'customerName' }, + }, + { + title: '合同编号', + field: 'contractNo', + width: 200, + }, + { + title: '期数', + field: 'period', + width: 150, + slots: { default: 'period' }, + }, + { + title: '计划回款金额(元)', + field: 'price', + width: 160, + formatter: 'formatNumber', + }, + { + title: '计划回款日期', + field: 'returnTime', + width: 180, + formatter: 'formatDateTime', + }, + { + title: '提前几天提醒', + field: 'remindDays', + width: 150, + }, + { + title: '提醒日期', + field: 'remindTime', + width: 180, + formatter: 'formatDateTime', + }, + { + title: '回款方式', + field: 'returnType', + width: 130, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.CRM_RECEIVABLE_RETURN_TYPE }, + }, + }, + { + title: '备注', + field: 'remark', + }, + { + title: '负责人', + field: 'ownerUserName', + width: 120, + }, + { + title: '实际回款金额(元)', + field: 'receivable.price', + width: 160, + formatter: 'formatNumber', + }, + { + title: '实际回款日期', + field: 'receivable.returnTime', + width: 180, + formatter: 'formatDateTime', + }, + { + title: '未回款金额(元)', + field: 'unpaidPrice', + width: 160, + formatter: ({ row }) => { + if (row.receivable) { + return row.price - row.receivable.price; + } + return row.price; + }, + }, + { + title: '更新时间', + field: 'updateTime', + width: 180, + formatter: 'formatDateTime', + }, + { + title: '创建时间', + field: 'createTime', + width: 180, + formatter: 'formatDateTime', + }, + { + title: '创建人', + field: 'creatorName', + width: 100, + }, + { + title: '操作', + field: 'actions', + width: 180, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} diff --git a/apps/web-antd/src/views/crm/receivable/plan/index.vue b/apps/web-antd/src/views/crm/receivable/plan/index.vue index dc177ae79..1f4c479cb 100644 --- a/apps/web-antd/src/views/crm/receivable/plan/index.vue +++ b/apps/web-antd/src/views/crm/receivable/plan/index.vue @@ -1,38 +1,217 @@ diff --git a/apps/web-antd/src/views/crm/receivable/plan/modules/form.vue b/apps/web-antd/src/views/crm/receivable/plan/modules/form.vue new file mode 100644 index 000000000..41a2132c1 --- /dev/null +++ b/apps/web-antd/src/views/crm/receivable/plan/modules/form.vue @@ -0,0 +1,88 @@ + + + diff --git a/apps/web-antd/src/views/infra/apiAccessLog/data.ts b/apps/web-antd/src/views/infra/apiAccessLog/data.ts index df569c12c..05d6b391d 100644 --- a/apps/web-antd/src/views/infra/apiAccessLog/data.ts +++ b/apps/web-antd/src/views/infra/apiAccessLog/data.ts @@ -70,17 +70,14 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'id', title: '日志编号', - minWidth: 100, }, { field: 'userId', title: '用户编号', - minWidth: 100, }, { field: 'userType', title: '用户类型', - minWidth: 120, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.USER_TYPE }, @@ -89,34 +86,28 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'applicationName', title: '应用名', - minWidth: 150, }, { field: 'requestMethod', title: '请求方法', - minWidth: 80, }, { field: 'requestUrl', title: '请求地址', - minWidth: 300, }, { field: 'beginTime', title: '请求时间', - minWidth: 180, formatter: 'formatDateTime', }, { field: 'duration', title: '执行时长', - minWidth: 120, - formatter: ({ row }) => `${row.duration} ms`, + formatter: ({ cellValue }) => `${cellValue} ms`, }, { field: 'resultCode', title: '操作结果', - minWidth: 150, formatter: ({ row }) => { return row.resultCode === 0 ? '成功' : `失败(${row.resultMsg})`; }, @@ -124,17 +115,14 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'operateModule', title: '操作模块', - minWidth: 150, }, { field: 'operateName', title: '操作名', - minWidth: 220, }, { field: 'operateType', title: '操作类型', - minWidth: 120, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.INFRA_OPERATE_TYPE }, diff --git a/apps/web-antd/src/views/infra/apiErrorLog/data.ts b/apps/web-antd/src/views/infra/apiErrorLog/data.ts index b60d797b6..a22715e41 100644 --- a/apps/web-antd/src/views/infra/apiErrorLog/data.ts +++ b/apps/web-antd/src/views/infra/apiErrorLog/data.ts @@ -71,17 +71,14 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'id', title: '日志编号', - minWidth: 100, }, { field: 'userId', title: '用户编号', - minWidth: 100, }, { field: 'userType', title: '用户类型', - minWidth: 120, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.USER_TYPE }, @@ -90,33 +87,27 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'applicationName', title: '应用名', - minWidth: 150, }, { field: 'requestMethod', title: '请求方法', - minWidth: 80, }, { field: 'requestUrl', title: '请求地址', - minWidth: 200, }, { field: 'exceptionTime', title: '异常发生时间', - minWidth: 180, formatter: 'formatDateTime', }, { field: 'exceptionName', title: '异常名', - minWidth: 180, }, { field: 'processStatus', title: '处理状态', - minWidth: 120, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.INFRA_API_ERROR_LOG_PROCESS_STATUS }, diff --git a/apps/web-antd/src/views/infra/codegen/data.ts b/apps/web-antd/src/views/infra/codegen/data.ts index a5647cf82..a2b50d9c3 100644 --- a/apps/web-antd/src/views/infra/codegen/data.ts +++ b/apps/web-antd/src/views/infra/codegen/data.ts @@ -397,34 +397,28 @@ export function useGridColumns( { field: 'dataSourceConfigId', title: '数据源', - minWidth: 120, - formatter: (row) => getDataSourceConfigName?.(row.cellValue) || '-', + formatter: ({ cellValue }) => getDataSourceConfigName?.(cellValue) || '-', }, { field: 'tableName', title: '表名称', - minWidth: 200, }, { field: 'tableComment', title: '表描述', - minWidth: 200, }, { field: 'className', title: '实体', - minWidth: 200, }, { field: 'createTime', title: '创建时间', - minWidth: 180, formatter: 'formatDateTime', }, { field: 'updateTime', title: '更新时间', - minWidth: 180, formatter: 'formatDateTime', }, { diff --git a/apps/web-antd/src/views/infra/config/data.ts b/apps/web-antd/src/views/infra/config/data.ts index 4ca8a36d6..ae886c47f 100644 --- a/apps/web-antd/src/views/infra/config/data.ts +++ b/apps/web-antd/src/views/infra/config/data.ts @@ -122,32 +122,26 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'id', title: '参数主键', - minWidth: 100, }, { field: 'category', title: '参数分类', - minWidth: 120, }, { field: 'name', title: '参数名称', - minWidth: 200, }, { field: 'key', title: '参数键名', - minWidth: 200, }, { field: 'value', title: '参数键值', - minWidth: 150, }, { field: 'visible', title: '是否可见', - minWidth: 100, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.INFRA_BOOLEAN_STRING }, @@ -156,7 +150,6 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'type', title: '系统内置', - minWidth: 100, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.INFRA_CONFIG_TYPE }, @@ -165,12 +158,10 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'remark', title: '备注', - minWidth: 150, }, { field: 'createTime', title: '创建时间', - minWidth: 180, formatter: 'formatDateTime', }, { diff --git a/apps/web-antd/src/views/infra/dataSourceConfig/data.ts b/apps/web-antd/src/views/infra/dataSourceConfig/data.ts index 98bb063ea..8ea49f895 100644 --- a/apps/web-antd/src/views/infra/dataSourceConfig/data.ts +++ b/apps/web-antd/src/views/infra/dataSourceConfig/data.ts @@ -58,27 +58,22 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'id', title: '主键编号', - minWidth: 100, }, { field: 'name', title: '数据源名称', - minWidth: 150, }, { field: 'url', title: '数据源连接', - minWidth: 300, }, { field: 'username', title: '用户名', - minWidth: 120, }, { field: 'createTime', title: '创建时间', - minWidth: 180, formatter: 'formatDateTime', }, { diff --git a/apps/web-antd/src/views/infra/demo/demo03/normal/data.ts b/apps/web-antd/src/views/infra/demo/demo03/normal/data.ts index 9d515e49d..8aa1eeaf1 100644 --- a/apps/web-antd/src/views/infra/demo/demo03/normal/data.ts +++ b/apps/web-antd/src/views/infra/demo/demo03/normal/data.ts @@ -111,17 +111,14 @@ export function useGridColumns( { field: 'id', title: '编号', - minWidth: 120, }, { field: 'name', title: '名字', - minWidth: 120, }, { field: 'sex', title: '性别', - minWidth: 120, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.SYSTEM_USER_SEX }, @@ -130,18 +127,15 @@ export function useGridColumns( { field: 'birthday', title: '出生日期', - minWidth: 120, formatter: 'formatDateTime', }, { field: 'description', title: '简介', - minWidth: 120, }, { field: 'createTime', title: '创建时间', - minWidth: 120, formatter: 'formatDateTime', }, { @@ -183,13 +177,11 @@ export function useDemo03CourseGridEditColumns( { field: 'name', title: '名字', - minWidth: 120, slots: { default: 'name' }, }, { field: 'score', title: '分数', - minWidth: 120, slots: { default: 'score' }, }, { diff --git a/apps/web-antd/src/views/infra/file/data.ts b/apps/web-antd/src/views/infra/file/data.ts index 912e1c949..3b9eecb1e 100644 --- a/apps/web-antd/src/views/infra/file/data.ts +++ b/apps/web-antd/src/views/infra/file/data.ts @@ -57,24 +57,20 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'name', title: '文件名', - minWidth: 150, }, { field: 'path', title: '文件路径', - minWidth: 200, showOverflow: true, }, { field: 'url', title: 'URL', - minWidth: 200, showOverflow: true, }, { field: 'size', title: '文件大小', - minWidth: 80, formatter: ({ cellValue }) => { // TODO @芋艿:后续优化下 if (!cellValue) return '0 B'; @@ -88,20 +84,15 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'type', title: '文件类型', - minWidth: 120, }, { field: 'file-content', title: '文件内容', - minWidth: 120, - slots: { - default: 'file-content', - }, + slots: { default: 'file-content' }, }, { field: 'createTime', title: '上传时间', - minWidth: 180, formatter: 'formatDateTime', }, { diff --git a/apps/web-antd/src/views/infra/fileConfig/data.ts b/apps/web-antd/src/views/infra/fileConfig/data.ts index 4821e4e6d..11ea4475e 100644 --- a/apps/web-antd/src/views/infra/fileConfig/data.ts +++ b/apps/web-antd/src/views/infra/fileConfig/data.ts @@ -265,17 +265,14 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'id', title: '编号', - width: 100, }, { field: 'name', title: '配置名', - minWidth: 120, }, { field: 'storage', title: '存储器', - width: 100, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.INFRA_FILE_STORAGE }, @@ -284,12 +281,10 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'remark', title: '备注', - minWidth: 150, }, { field: 'master', title: '主配置', - width: 100, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.INFRA_BOOLEAN_STRING }, @@ -298,7 +293,6 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'createTime', title: '创建时间', - width: 180, formatter: 'formatDateTime', }, { diff --git a/apps/web-antd/src/views/infra/job/data.ts b/apps/web-antd/src/views/infra/job/data.ts index 8d4db1e89..982ee9f9b 100644 --- a/apps/web-antd/src/views/infra/job/data.ts +++ b/apps/web-antd/src/views/infra/job/data.ts @@ -132,17 +132,14 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'id', title: '任务编号', - minWidth: 80, }, { field: 'name', title: '任务名称', - minWidth: 120, }, { field: 'status', title: '任务状态', - minWidth: 100, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.INFRA_JOB_STATUS }, @@ -151,17 +148,14 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'handlerName', title: '处理器的名字', - minWidth: 180, }, { field: 'handlerParam', title: '处理器的参数', - minWidth: 140, }, { field: 'cronExpression', title: 'CRON 表达式', - minWidth: 120, }, { title: '操作', diff --git a/apps/web-antd/src/views/infra/job/logger/data.ts b/apps/web-antd/src/views/infra/job/logger/data.ts index 9d5530e6c..b58629a8b 100644 --- a/apps/web-antd/src/views/infra/job/logger/data.ts +++ b/apps/web-antd/src/views/infra/job/logger/data.ts @@ -70,32 +70,26 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'id', title: '日志编号', - minWidth: 80, }, { field: 'jobId', title: '任务编号', - minWidth: 80, }, { field: 'handlerName', title: '处理器的名字', - minWidth: 180, }, { field: 'handlerParam', title: '处理器的参数', - minWidth: 140, }, { field: 'executeIndex', title: '第几次执行', - minWidth: 100, }, { field: 'beginTime', title: '执行时间', - minWidth: 280, formatter: ({ row }) => { return `${formatDateTime(row.beginTime)} ~ ${formatDateTime(row.endTime)}`; }, @@ -103,15 +97,11 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'duration', title: '执行时长', - minWidth: 120, - formatter: ({ row }) => { - return `${row.duration} 毫秒`; - }, + formatter: ({ cellValue }) => `${cellValue} 毫秒`, }, { field: 'status', title: '任务状态', - minWidth: 100, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.INFRA_JOB_LOG_STATUS }, diff --git a/apps/web-antd/src/views/member/tag/data.ts b/apps/web-antd/src/views/member/tag/data.ts index 73728e0c3..c0da8541e 100644 --- a/apps/web-antd/src/views/member/tag/data.ts +++ b/apps/web-antd/src/views/member/tag/data.ts @@ -48,17 +48,14 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'id', title: '编号', - minWidth: 200, }, { field: 'name', title: '标签名称', - minWidth: 200, }, { field: 'createTime', title: '创建时间', - minWidth: 180, formatter: 'formatDateTime', }, { diff --git a/apps/web-antd/src/views/pay/demo/order/data.ts b/apps/web-antd/src/views/pay/demo/order/data.ts index 2683b905a..f38050df5 100644 --- a/apps/web-antd/src/views/pay/demo/order/data.ts +++ b/apps/web-antd/src/views/pay/demo/order/data.ts @@ -38,45 +38,37 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'id', title: '订单编号', - minWidth: 200, }, { field: 'userId', title: '用户编号', - minWidth: 200, }, { field: 'spuName', title: '商品名字', - minWidth: 200, }, { field: 'price', title: '支付价格', - minWidth: 120, formatter: 'formatNumber', }, { field: 'refundPrice', title: '退款金额', - minWidth: 120, formatter: 'formatNumber', }, { field: 'createTime', title: '创建时间', - minWidth: 180, formatter: 'formatDateTime', }, { field: 'payOrderId', title: '支付单号', - minWidth: 200, }, { field: 'payStatus', title: '是否支付', - minWidth: 100, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.INFRA_BOOLEAN_STRING }, @@ -85,13 +77,11 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'payTime', title: '支付时间', - minWidth: 180, formatter: 'formatDateTime', }, { field: 'refundTime', title: '退款时间', - minWidth: 180, slots: { default: 'refundTime' }, }, { diff --git a/apps/web-antd/src/views/pay/demo/withdraw/data.ts b/apps/web-antd/src/views/pay/demo/withdraw/data.ts index ccfa1af1b..7fcfb6055 100644 --- a/apps/web-antd/src/views/pay/demo/withdraw/data.ts +++ b/apps/web-antd/src/views/pay/demo/withdraw/data.ts @@ -65,50 +65,41 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'id', title: '提现单编号', - minWidth: 100, }, { field: 'subject', title: '提现标题', - minWidth: 120, }, { field: 'type', title: '提现类型', - minWidth: 90, slots: { default: 'type' }, }, { field: 'price', title: '提现金额', - minWidth: 120, formatter: 'formatNumber', }, { field: 'userName', title: '收款人姓名', - minWidth: 150, }, { field: 'userAccount', title: '收款人账号', - minWidth: 250, }, { field: 'status', title: '提现状态', - minWidth: 100, slots: { default: 'status' }, }, { field: 'payTransferId', title: '转账单号', - minWidth: 120, }, { field: 'transferChannelCode', title: '转账渠道', - minWidth: 180, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.PAY_CHANNEL_CODE }, @@ -117,13 +108,11 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'transferTime', title: '转账时间', - minWidth: 180, formatter: 'formatDateTime', }, { field: 'transferErrorMsg', title: '转账失败原因', - minWidth: 200, }, { title: '操作', diff --git a/apps/web-antd/src/views/pay/notify/data.ts b/apps/web-antd/src/views/pay/notify/data.ts index 7fc2e6354..6b7b5cc57 100644 --- a/apps/web-antd/src/views/pay/notify/data.ts +++ b/apps/web-antd/src/views/pay/notify/data.ts @@ -69,22 +69,18 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'id', title: '任务编号', - minWidth: 100, }, { field: 'appName', title: '应用编号', - minWidth: 120, }, { field: 'merchantOrderId', title: '商户订单编号', - minWidth: 180, }, { field: 'type', title: '通知类型', - minWidth: 120, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.PAY_NOTIFY_TYPE }, @@ -93,12 +89,10 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'dataId', title: '关联编号', - minWidth: 120, }, { field: 'status', title: '通知状态', - minWidth: 120, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.PAY_NOTIFY_STATUS }, @@ -107,19 +101,16 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'lastExecuteTime', title: '最后通知时间', - minWidth: 180, formatter: 'formatDateTime', }, { field: 'nextNotifyTime', title: '下次通知时间', - minWidth: 180, formatter: 'formatDateTime', }, { field: 'notifyTimes', title: '通知次数', - minWidth: 120, cellRender: { name: 'CellTag', props: { diff --git a/apps/web-antd/src/views/pay/transfer/data.ts b/apps/web-antd/src/views/pay/transfer/data.ts index b6f8fef96..36d7cb861 100644 --- a/apps/web-antd/src/views/pay/transfer/data.ts +++ b/apps/web-antd/src/views/pay/transfer/data.ts @@ -107,29 +107,24 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'id', title: '编号', - minWidth: 100, }, { field: 'createTime', title: '创建时间', - minWidth: 180, formatter: 'formatDateTime', }, { field: 'appName', title: '支付应用', - minWidth: 100, }, { field: 'price', title: '转账金额', - minWidth: 120, formatter: ({ cellValue }) => `¥${(cellValue / 100).toFixed(2)}`, }, { field: 'status', title: '转账状态', - minWidth: 120, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.PAY_TRANSFER_STATUS }, @@ -138,7 +133,6 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'type', title: '类型', - minWidth: 120, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.PAY_TRANSFER_TYPE }, @@ -147,7 +141,6 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'channelCode', title: '支付渠道', - minWidth: 120, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.PAY_CHANNEL_CODE }, @@ -156,22 +149,18 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'merchantTransferId', title: '商户单号', - minWidth: 180, }, { field: 'channelTransferNo', title: '渠道单号', - minWidth: 180, }, { field: 'userName', title: '收款人姓名', - minWidth: 120, }, { field: 'accountNo', title: '收款人账号', - minWidth: 180, }, { title: '操作', diff --git a/apps/web-antd/src/views/system/area/data.ts b/apps/web-antd/src/views/system/area/data.ts index 48339f19e..087133e96 100644 --- a/apps/web-antd/src/views/system/area/data.ts +++ b/apps/web-antd/src/views/system/area/data.ts @@ -32,7 +32,6 @@ export function useGridColumns(): VxeTableGridOptions['colum { field: 'id', title: '地区编码', - minWidth: 120, align: 'left', fixed: 'left', treeNode: true, @@ -40,7 +39,6 @@ export function useGridColumns(): VxeTableGridOptions['colum { field: 'name', title: '地区名称', - minWidth: 200, }, ]; } diff --git a/apps/web-antd/src/views/system/dept/data.ts b/apps/web-antd/src/views/system/dept/data.ts index f57287407..155f60f21 100644 --- a/apps/web-antd/src/views/system/dept/data.ts +++ b/apps/web-antd/src/views/system/dept/data.ts @@ -116,7 +116,6 @@ export function useGridColumns( { field: 'name', title: '部门名称', - minWidth: 150, align: 'left', fixed: 'left', treeNode: true, @@ -124,20 +123,15 @@ export function useGridColumns( { field: 'leaderUserId', title: '负责人', - minWidth: 150, - formatter: (row) => { - return getLeaderName?.(row.cellValue) || '-'; - }, + formatter: ({ cellValue }) => getLeaderName?.(cellValue) || '-', }, { field: 'sort', title: '显示顺序', - minWidth: 100, }, { field: 'status', title: '部门状态', - minWidth: 100, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.COMMON_STATUS }, @@ -146,7 +140,6 @@ export function useGridColumns( { field: 'createTime', title: '创建时间', - minWidth: 180, formatter: 'formatDateTime', }, { diff --git a/apps/web-antd/src/views/system/dict/data.ts b/apps/web-antd/src/views/system/dict/data.ts index 531531bc2..d116f0d28 100644 --- a/apps/web-antd/src/views/system/dict/data.ts +++ b/apps/web-antd/src/views/system/dict/data.ts @@ -95,22 +95,18 @@ export function useTypeGridColumns(): VxeTableGridOptions['columns'] { { field: 'id', title: '字典编号', - minWidth: 100, }, { field: 'name', title: '字典名称', - minWidth: 200, }, { field: 'type', title: '字典类型', - minWidth: 220, }, { field: 'status', title: '状态', - minWidth: 120, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.COMMON_STATUS }, @@ -119,12 +115,10 @@ export function useTypeGridColumns(): VxeTableGridOptions['columns'] { { field: 'remark', title: '备注', - minWidth: 180, }, { field: 'createTime', title: '创建时间', - minWidth: 180, formatter: 'formatDateTime', }, { @@ -288,27 +282,22 @@ export function useDataGridColumns(): VxeTableGridOptions['columns'] { { field: 'id', title: '字典编码', - minWidth: 100, }, { field: 'label', title: '字典标签', - minWidth: 180, }, { field: 'value', title: '字典键值', - minWidth: 100, }, { field: 'sort', title: '字典排序', - minWidth: 100, }, { field: 'status', title: '状态', - minWidth: 100, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.COMMON_STATUS }, @@ -317,17 +306,14 @@ export function useDataGridColumns(): VxeTableGridOptions['columns'] { { field: 'colorType', title: '颜色类型', - minWidth: 120, }, { field: 'cssClass', title: 'CSS Class', - minWidth: 120, }, { title: '创建时间', field: 'createTime', - minWidth: 180, formatter: 'formatDateTime', }, { diff --git a/apps/web-antd/src/views/system/loginlog/data.ts b/apps/web-antd/src/views/system/loginlog/data.ts index 730e5f8b5..f09f6b535 100644 --- a/apps/web-antd/src/views/system/loginlog/data.ts +++ b/apps/web-antd/src/views/system/loginlog/data.ts @@ -42,12 +42,10 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'id', title: '日志编号', - minWidth: 100, }, { field: 'logType', title: '操作类型', - minWidth: 120, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.SYSTEM_LOGIN_TYPE }, @@ -56,22 +54,18 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'username', title: '用户名称', - minWidth: 180, }, { field: 'userIp', title: '登录地址', - minWidth: 180, }, { field: 'userAgent', title: '浏览器', - minWidth: 200, }, { field: 'result', title: '登录结果', - minWidth: 120, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.SYSTEM_LOGIN_RESULT }, @@ -80,7 +74,6 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'createTime', title: '登录日期', - minWidth: 180, formatter: 'formatDateTime', }, { diff --git a/apps/web-antd/src/views/system/mail/account/data.ts b/apps/web-antd/src/views/system/mail/account/data.ts index 60736eb95..e4cbbec40 100644 --- a/apps/web-antd/src/views/system/mail/account/data.ts +++ b/apps/web-antd/src/views/system/mail/account/data.ts @@ -125,32 +125,26 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'id', title: '编号', - minWidth: 100, }, { field: 'mail', title: '邮箱', - minWidth: 160, }, { field: 'username', title: '用户名', - minWidth: 160, }, { field: 'host', title: 'SMTP 服务器域名', - minWidth: 150, }, { field: 'port', title: 'SMTP 服务器端口', - minWidth: 130, }, { field: 'sslEnable', title: '是否开启 SSL', - minWidth: 120, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.INFRA_BOOLEAN_STRING }, @@ -159,7 +153,6 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'starttlsEnable', title: '是否开启 STARTTLS', - minWidth: 145, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.INFRA_BOOLEAN_STRING }, @@ -168,7 +161,6 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'createTime', title: '创建时间', - minWidth: 180, formatter: 'formatDateTime', }, { diff --git a/apps/web-antd/src/views/system/mail/log/data.ts b/apps/web-antd/src/views/system/mail/log/data.ts index b357472fc..9c8ee7e5c 100644 --- a/apps/web-antd/src/views/system/mail/log/data.ts +++ b/apps/web-antd/src/views/system/mail/log/data.ts @@ -75,38 +75,31 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'id', title: '编号', - minWidth: 100, }, { field: 'sendTime', title: '发送时间', - minWidth: 180, formatter: 'formatDateTime', }, { field: 'toMail', title: '收件邮箱', - minWidth: 160, }, { field: 'templateTitle', title: '邮件标题', - minWidth: 120, }, { field: 'templateContent', title: '邮件内容', - minWidth: 300, }, { field: 'fromMail', title: '发送邮箱', - minWidth: 120, }, { field: 'sendStatus', title: '发送状态', - minWidth: 120, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.SYSTEM_MAIL_SEND_STATUS }, @@ -115,7 +108,6 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'templateCode', title: '模板编码', - minWidth: 120, }, { title: '操作', diff --git a/apps/web-antd/src/views/system/mail/template/data.ts b/apps/web-antd/src/views/system/mail/template/data.ts index 3fb229264..06f03457a 100644 --- a/apps/web-antd/src/views/system/mail/template/data.ts +++ b/apps/web-antd/src/views/system/mail/template/data.ts @@ -195,38 +195,31 @@ export function useGridColumns( { field: 'id', title: '编号', - minWidth: 100, }, { field: 'code', title: '模板编码', - minWidth: 120, }, { field: 'name', title: '模板名称', - minWidth: 120, }, { field: 'title', title: '模板标题', - minWidth: 120, }, { field: 'accountId', title: '邮箱账号', - minWidth: 120, - formatter: (row) => getAccountMail?.(row.cellValue) || '-', + formatter: ({ cellValue }) => getAccountMail?.(cellValue) || '-', }, { field: 'nickname', title: '发送人名称', - minWidth: 120, }, { field: 'status', title: '开启状态', - minWidth: 100, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.COMMON_STATUS }, @@ -235,7 +228,6 @@ export function useGridColumns( { field: 'createTime', title: '创建时间', - minWidth: 180, formatter: 'formatDateTime', }, { diff --git a/apps/web-antd/src/views/system/menu/data.ts b/apps/web-antd/src/views/system/menu/data.ts index 8c338134f..0cc5a6a86 100644 --- a/apps/web-antd/src/views/system/menu/data.ts +++ b/apps/web-antd/src/views/system/menu/data.ts @@ -271,7 +271,6 @@ export function useGridColumns(): VxeTableGridOptions['colum { field: 'name', title: '菜单名称', - minWidth: 250, align: 'left', fixed: 'left', slots: { default: 'name' }, @@ -280,7 +279,6 @@ export function useGridColumns(): VxeTableGridOptions['colum { field: 'type', title: '菜单类型', - minWidth: 100, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.SYSTEM_MENU_TYPE }, @@ -289,27 +287,22 @@ export function useGridColumns(): VxeTableGridOptions['colum { field: 'sort', title: '显示排序', - minWidth: 100, }, { field: 'permission', title: '权限标识', - minWidth: 200, }, { field: 'path', title: '组件路径', - minWidth: 200, }, { field: 'componentName', - minWidth: 200, title: '组件名称', }, { field: 'status', title: '状态', - minWidth: 100, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.COMMON_STATUS }, diff --git a/apps/web-antd/src/views/system/notice/data.ts b/apps/web-antd/src/views/system/notice/data.ts index 20aa96a49..7704f69c3 100644 --- a/apps/web-antd/src/views/system/notice/data.ts +++ b/apps/web-antd/src/views/system/notice/data.ts @@ -91,17 +91,14 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'id', title: '公告编号', - minWidth: 100, }, { field: 'title', title: '公告标题', - minWidth: 200, }, { field: 'type', title: '公告类型', - minWidth: 100, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.SYSTEM_NOTICE_TYPE }, @@ -110,7 +107,6 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'status', title: '公告状态', - minWidth: 100, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.COMMON_STATUS }, @@ -119,7 +115,6 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'createTime', title: '创建时间', - minWidth: 180, formatter: 'formatDateTime', }, { diff --git a/apps/web-antd/src/views/system/notify/message/data.ts b/apps/web-antd/src/views/system/notify/message/data.ts index 214966e9b..45e0436fa 100644 --- a/apps/web-antd/src/views/system/notify/message/data.ts +++ b/apps/web-antd/src/views/system/notify/message/data.ts @@ -65,12 +65,10 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'id', title: '编号', - minWidth: 100, }, { field: 'userType', title: '用户类型', - minWidth: 120, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.USER_TYPE }, @@ -79,27 +77,22 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'userId', title: '用户编号', - minWidth: 100, }, { field: 'templateCode', title: '模板编码', - minWidth: 120, }, { field: 'templateNickname', title: '发送人名称', - minWidth: 180, }, { field: 'templateContent', title: '模版内容', - minWidth: 200, }, { field: 'templateParams', title: '模版参数', - minWidth: 180, formatter: ({ cellValue }) => { try { return JSON.stringify(cellValue); @@ -111,7 +104,6 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'templateType', title: '模版类型', - minWidth: 120, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.SYSTEM_NOTIFY_TEMPLATE_TYPE }, @@ -120,7 +112,6 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'readStatus', title: '是否已读', - minWidth: 100, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.INFRA_BOOLEAN_STRING }, @@ -129,13 +120,11 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'readTime', title: '阅读时间', - minWidth: 180, formatter: 'formatDateTime', }, { field: 'createTime', title: '创建时间', - minWidth: 180, formatter: 'formatDateTime', }, { diff --git a/apps/web-antd/src/views/system/notify/my/data.ts b/apps/web-antd/src/views/system/notify/my/data.ts index d133e38f0..fc0606000 100644 --- a/apps/web-antd/src/views/system/notify/my/data.ts +++ b/apps/web-antd/src/views/system/notify/my/data.ts @@ -45,18 +45,15 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'templateNickname', title: '发送人', - minWidth: 180, }, { field: 'createTime', title: '发送时间', - minWidth: 180, formatter: 'formatDateTime', }, { field: 'templateType', title: '类型', - minWidth: 120, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.SYSTEM_NOTIFY_TEMPLATE_TYPE }, @@ -65,12 +62,10 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'templateContent', title: '消息内容', - minWidth: 300, }, { field: 'readStatus', title: '是否已读', - minWidth: 100, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.INFRA_BOOLEAN_STRING }, @@ -79,7 +74,6 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'readTime', title: '阅读时间', - minWidth: 180, formatter: 'formatDateTime', }, { diff --git a/apps/web-antd/src/views/system/notify/template/data.ts b/apps/web-antd/src/views/system/notify/template/data.ts index 32d3adbb5..fd0a63f09 100644 --- a/apps/web-antd/src/views/system/notify/template/data.ts +++ b/apps/web-antd/src/views/system/notify/template/data.ts @@ -229,32 +229,26 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'id', title: '编号', - minWidth: 100, }, { field: 'name', title: '模板名称', - minWidth: 120, }, { field: 'code', title: '模板编码', - minWidth: 120, }, { field: 'nickname', title: '发送人名称', - minWidth: 120, }, { field: 'content', title: '模板内容', - minWidth: 200, }, { field: 'type', title: '模板类型', - minWidth: 120, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.SYSTEM_NOTIFY_TEMPLATE_TYPE }, @@ -263,7 +257,6 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'status', title: '状态', - minWidth: 100, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.COMMON_STATUS }, @@ -272,12 +265,10 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'remark', title: '备注', - minWidth: 120, }, { field: 'createTime', title: '创建时间', - minWidth: 180, formatter: 'formatDateTime', }, { diff --git a/apps/web-antd/src/views/system/oauth2/client/data.ts b/apps/web-antd/src/views/system/oauth2/client/data.ts index 12d5b461f..c510f8fde 100644 --- a/apps/web-antd/src/views/system/oauth2/client/data.ts +++ b/apps/web-antd/src/views/system/oauth2/client/data.ts @@ -191,22 +191,18 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'clientId', title: '客户端编号', - minWidth: 200, }, { field: 'secret', title: '客户端密钥', - minWidth: 120, }, { field: 'name', title: '应用名', - minWidth: 300, }, { field: 'logo', title: '应用图标', - minWidth: 80, cellRender: { name: 'CellImage', }, @@ -214,7 +210,6 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'status', title: '状态', - minWidth: 80, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.COMMON_STATUS }, @@ -223,24 +218,20 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'accessTokenValiditySeconds', title: '访问令牌的有效期', - minWidth: 130, formatter: ({ cellValue }) => `${cellValue} 秒`, }, { field: 'refreshTokenValiditySeconds', title: '刷新令牌的有效期', - minWidth: 130, formatter: ({ cellValue }) => `${cellValue} 秒`, }, { field: 'authorizedGrantTypes', title: '授权类型', - minWidth: 180, }, { field: 'createTime', title: '创建时间', - minWidth: 180, formatter: 'formatDateTime', }, { diff --git a/apps/web-antd/src/views/system/oauth2/token/data.ts b/apps/web-antd/src/views/system/oauth2/token/data.ts index 5df8b9c7f..d990000c6 100644 --- a/apps/web-antd/src/views/system/oauth2/token/data.ts +++ b/apps/web-antd/src/views/system/oauth2/token/data.ts @@ -40,22 +40,18 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'accessToken', title: '访问令牌', - minWidth: 300, }, { field: 'refreshToken', title: '刷新令牌', - minWidth: 300, }, { field: 'userId', title: '用户编号', - minWidth: 100, }, { field: 'userType', title: '用户类型', - minWidth: 100, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.USER_TYPE }, @@ -64,18 +60,15 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'clientId', title: '客户端编号', - minWidth: 120, }, { field: 'expiresTime', title: '过期时间', - minWidth: 180, formatter: 'formatDateTime', }, { field: 'createTime', title: '创建时间', - minWidth: 180, formatter: 'formatDateTime', }, { diff --git a/apps/web-antd/src/views/system/operatelog/data.ts b/apps/web-antd/src/views/system/operatelog/data.ts index 71b552c4b..a2dde0587 100644 --- a/apps/web-antd/src/views/system/operatelog/data.ts +++ b/apps/web-antd/src/views/system/operatelog/data.ts @@ -75,43 +75,35 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'id', title: '日志编号', - minWidth: 100, }, { field: 'userName', title: '操作人', - minWidth: 120, }, { field: 'type', title: '操作模块', - minWidth: 120, }, { field: 'subType', title: '操作名', - minWidth: 160, }, { field: 'action', title: '操作内容', - minWidth: 200, }, { field: 'createTime', title: '操作时间', - minWidth: 180, formatter: 'formatDateTime', }, { field: 'bizId', title: '业务编号', - minWidth: 120, }, { field: 'userIp', title: '操作IP', - minWidth: 120, }, { title: '操作', diff --git a/apps/web-antd/src/views/system/post/data.ts b/apps/web-antd/src/views/system/post/data.ts index ddde2f742..cfb1ceb79 100644 --- a/apps/web-antd/src/views/system/post/data.ts +++ b/apps/web-antd/src/views/system/post/data.ts @@ -86,32 +86,26 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'id', title: '岗位编号', - minWidth: 200, }, { field: 'name', title: '岗位名称', - minWidth: 200, }, { field: 'code', title: '岗位编码', - minWidth: 200, }, { field: 'sort', title: '显示顺序', - minWidth: 100, }, { field: 'remark', title: '岗位备注', - minWidth: 200, }, { field: 'status', title: '岗位状态', - minWidth: 100, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.COMMON_STATUS }, @@ -120,7 +114,6 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'createTime', title: '创建时间', - minWidth: 180, formatter: 'formatDateTime', }, { diff --git a/apps/web-antd/src/views/system/role/data.ts b/apps/web-antd/src/views/system/role/data.ts index 5b0a8b78f..30ee7a3d8 100644 --- a/apps/web-antd/src/views/system/role/data.ts +++ b/apps/web-antd/src/views/system/role/data.ts @@ -189,17 +189,14 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'id', title: '角色编号', - minWidth: 200, }, { field: 'name', title: '角色名称', - minWidth: 200, }, { field: 'type', title: '角色类型', - minWidth: 100, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.SYSTEM_ROLE_TYPE }, @@ -208,22 +205,18 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'code', title: '角色标识', - minWidth: 200, }, { field: 'sort', title: '显示顺序', - minWidth: 100, }, { field: 'remark', title: '角色备注', - minWidth: 100, }, { field: 'status', title: '角色状态', - minWidth: 100, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.COMMON_STATUS }, @@ -232,7 +225,6 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'createTime', title: '创建时间', - minWidth: 180, formatter: 'formatDateTime', }, { diff --git a/apps/web-antd/src/views/system/social/client/data.ts b/apps/web-antd/src/views/system/social/client/data.ts index 88f6b4f99..87307b4e8 100644 --- a/apps/web-antd/src/views/system/social/client/data.ts +++ b/apps/web-antd/src/views/system/social/client/data.ts @@ -152,17 +152,14 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'id', title: '编号', - minWidth: 80, }, { field: 'name', title: '应用名', - minWidth: 120, }, { field: 'socialType', title: '社交平台', - minWidth: 120, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.SYSTEM_SOCIAL_TYPE }, @@ -171,7 +168,6 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'userType', title: '用户类型', - minWidth: 120, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.USER_TYPE }, @@ -180,12 +176,10 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'clientId', title: '客户端编号', - minWidth: 180, }, { field: 'status', title: '状态', - minWidth: 80, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.COMMON_STATUS }, @@ -194,7 +188,6 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'createTime', title: '创建时间', - minWidth: 180, formatter: 'formatDateTime', }, { diff --git a/apps/web-antd/src/views/system/social/user/data.ts b/apps/web-antd/src/views/system/social/user/data.ts index eeed03f4f..7271efdd5 100644 --- a/apps/web-antd/src/views/system/social/user/data.ts +++ b/apps/web-antd/src/views/system/social/user/data.ts @@ -52,7 +52,6 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'type', title: '社交平台', - minWidth: 120, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.SYSTEM_SOCIAL_TYPE }, @@ -61,17 +60,14 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'openid', title: '社交 openid', - minWidth: 180, }, { field: 'nickname', title: '用户昵称', - minWidth: 120, }, { field: 'avatar', title: '用户头像', - minWidth: 80, cellRender: { name: 'CellImage', }, @@ -79,13 +75,11 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'createTime', title: '创建时间', - minWidth: 180, formatter: 'formatDateTime', }, { field: 'updateTime', title: '更新时间', - minWidth: 180, formatter: 'formatDateTime', }, { diff --git a/apps/web-antd/src/views/system/tenant/data.ts b/apps/web-antd/src/views/system/tenant/data.ts index 126941af3..30b2a79d5 100644 --- a/apps/web-antd/src/views/system/tenant/data.ts +++ b/apps/web-antd/src/views/system/tenant/data.ts @@ -164,17 +164,14 @@ export function useGridColumns( { field: 'id', title: '租户编号', - minWidth: 100, }, { field: 'name', title: '租户名', - minWidth: 180, }, { field: 'packageId', title: '租户套餐', - minWidth: 180, formatter: (row: { cellValue: number }) => { return getPackageName?.(row.cellValue) || '-'; }, @@ -182,33 +179,27 @@ export function useGridColumns( { field: 'contactName', title: '联系人', - minWidth: 100, }, { field: 'contactMobile', title: '联系手机', - minWidth: 180, }, { field: 'accountCount', title: '账号额度', - minWidth: 100, }, { field: 'expireTime', title: '过期时间', - minWidth: 180, formatter: 'formatDateTime', }, { field: 'website', title: '绑定域名', - minWidth: 180, }, { field: 'status', title: '租户状态', - minWidth: 100, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.COMMON_STATUS }, @@ -217,7 +208,6 @@ export function useGridColumns( { field: 'createTime', title: '创建时间', - minWidth: 180, formatter: 'formatDateTime', }, { diff --git a/apps/web-antd/src/views/system/tenantPackage/data.ts b/apps/web-antd/src/views/system/tenantPackage/data.ts index f69e6290a..66775f892 100644 --- a/apps/web-antd/src/views/system/tenantPackage/data.ts +++ b/apps/web-antd/src/views/system/tenantPackage/data.ts @@ -91,17 +91,14 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'id', title: '套餐编号', - minWidth: 100, }, { field: 'name', title: '套餐名称', - minWidth: 180, }, { field: 'status', title: '状态', - minWidth: 100, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.COMMON_STATUS }, @@ -110,12 +107,10 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'remark', title: '备注', - minWidth: 200, }, { field: 'createTime', title: '创建时间', - minWidth: 180, formatter: 'formatDateTime', }, { diff --git a/apps/web-antd/src/views/system/user/data.ts b/apps/web-antd/src/views/system/user/data.ts index e38b89b00..ae2c06ff0 100644 --- a/apps/web-antd/src/views/system/user/data.ts +++ b/apps/web-antd/src/views/system/user/data.ts @@ -268,32 +268,26 @@ export function useGridColumns( { field: 'id', title: '用户编号', - minWidth: 100, }, { field: 'username', title: '用户名称', - minWidth: 120, }, { field: 'nickname', title: '用户昵称', - minWidth: 120, }, { field: 'deptName', title: '部门', - minWidth: 120, }, { field: 'mobile', title: '手机号码', - minWidth: 120, }, { field: 'status', title: '状态', - minWidth: 100, align: 'center', cellRender: { attrs: { beforeChange: onStatusChange }, @@ -307,7 +301,6 @@ export function useGridColumns( { field: 'createTime', title: '创建时间', - minWidth: 180, formatter: 'formatDateTime', }, { diff --git a/docs/src/en/guide/in-depth/access.md b/docs/src/en/guide/in-depth/access.md index 05997d7d5..545dddabd 100644 --- a/docs/src/en/guide/in-depth/access.md +++ b/docs/src/en/guide/in-depth/access.md @@ -4,10 +4,11 @@ outline: deep # Access Control -The framework has built-in two types of access control methods: +The framework has built-in three types of access control methods: - Determining whether a menu or button can be accessed based on user roles - Determining whether a menu or button can be accessed through an API +- Mixed mode: Using both frontend and backend access control simultaneously ## Frontend Access Control @@ -151,6 +152,43 @@ const dashboardMenus = [ At this point, the configuration is complete. You need to ensure that after logging in, the format of the menu returned by the interface is correct; otherwise, access will not be possible. +## Mixed Access Control + +**Implementation Principle**: Mixed mode combines both frontend access control and backend access control methods. The system processes frontend fixed route permissions and backend dynamic menu data in parallel, ultimately merging both parts of routes to provide a more flexible access control solution. + +**Advantages**: Combines the performance advantages of frontend control with the flexibility of backend control, suitable for complex business scenarios requiring permission management. + +### Steps + +- Ensure the current mode is set to mixed access control + +Adjust `preferences.ts` in the corresponding application directory to ensure `accessMode='mixed'`. + +```ts +import { defineOverridesPreferences } from '@vben/preferences'; + +export const overridesPreferences = defineOverridesPreferences({ + // overrides + app: { + accessMode: 'mixed', + }, +}); +``` + +- Configure frontend route permissions + +Same as the route permission configuration method in [Frontend Access Control](#frontend-access-control) mode. + +- Configure backend menu interface + +Same as the interface configuration method in [Backend Access Control](#backend-access-control) mode. + +- Ensure roles and permissions match + +Must satisfy both frontend route permission configuration and backend menu data return requirements, ensuring user roles match the permission configurations of both modes. + +At this point, the configuration is complete. Mixed mode will automatically merge frontend and backend routes, providing complete access control functionality. + ## Fine-grained Control of Buttons In some cases, we need to control the display of buttons with fine granularity. We can control the display of buttons through interfaces or roles. diff --git a/docs/src/guide/in-depth/access.md b/docs/src/guide/in-depth/access.md index 0dbd0819d..bbce30a20 100644 --- a/docs/src/guide/in-depth/access.md +++ b/docs/src/guide/in-depth/access.md @@ -4,10 +4,11 @@ outline: deep # 权限 -框架内置了两种权限控制方式: +框架内置了三种权限控制方式: - 通过用户角色来判断菜单或者按钮是否可以访问 - 通过接口来判断菜单或者按钮是否可以访问 +- 混合模式:同时使用前端和后端权限控制 ## 前端访问控制 @@ -159,6 +160,43 @@ const dashboardMenus = [ 到这里,就已经配置完成,你需要确保登录后,接口返回的菜单格式正确,否则无法访问。 +## 混合访问控制 + +**实现原理**: 混合模式同时结合了前端访问控制和后端访问控制两种方式。系统会并行处理前端固定路由权限和后端动态菜单数据,最终将两部分路由合并,提供更灵活的权限控制方案。 + +**优点**: 兼具前端控制的性能优势和后端控制的灵活性,适合复杂业务场景下的权限管理。 + +### 步骤 + +- 确保当前模式为混合访问控制模式 + +调整对应应用目录下的`preferences.ts`,确保`accessMode='mixed'`。 + +```ts +import { defineOverridesPreferences } from '@vben/preferences'; + +export const overridesPreferences = defineOverridesPreferences({ + // overrides + app: { + accessMode: 'mixed', + }, +}); +``` + +- 配置前端路由权限 + +同[前端访问控制](#前端访问控制)模式的路由权限配置方式。 + +- 配置后端菜单接口 + +同[后端访问控制](#后端访问控制)模式的接口配置方式。 + +- 确保角色和权限匹配 + +需要同时满足前端路由权限配置和后端菜单数据返回的要求,确保用户角色与两种模式的权限配置都匹配。 + +到这里,就已经配置完成,混合模式会自动合并前端和后端的路由,提供完整的权限控制功能。 + ## 按钮细粒度控制 在某些情况下,我们需要对按钮进行细粒度的控制,我们可以借助接口或者角色来控制按钮的显示。 diff --git a/packages/@core/base/typings/src/app.d.ts b/packages/@core/base/typings/src/app.d.ts index 02da2466a..d2e86aec4 100644 --- a/packages/@core/base/typings/src/app.d.ts +++ b/packages/@core/base/typings/src/app.d.ts @@ -60,8 +60,9 @@ type BreadcrumbStyleType = 'background' | 'normal'; * 权限模式 * backend 后端权限模式 * frontend 前端权限模式 + * mixed 混合权限模式 */ -type AccessModeType = 'backend' | 'frontend'; +type AccessModeType = 'backend' | 'frontend' | 'mixed'; /** * 导航风格 diff --git a/packages/effects/access/src/accessible.ts b/packages/effects/access/src/accessible.ts index dd93d2e21..eb9081486 100644 --- a/packages/effects/access/src/accessible.ts +++ b/packages/effects/access/src/accessible.ts @@ -96,6 +96,15 @@ async function generateRoutes( ); break; } + case 'mixed': { + const [frontend_resultRoutes, backend_resultRoutes] = await Promise.all([ + generateRoutesByFrontend(routes, roles || [], forbiddenComponent), + generateRoutesByBackend(options), + ]); + + resultRoutes = [...frontend_resultRoutes, ...backend_resultRoutes]; + break; + } } /** diff --git a/packages/effects/plugins/src/vxe-table/use-vxe-grid.vue b/packages/effects/plugins/src/vxe-table/use-vxe-grid.vue index c9490b638..72fbb07a4 100644 --- a/packages/effects/plugins/src/vxe-table/use-vxe-grid.vue +++ b/packages/effects/plugins/src/vxe-table/use-vxe-grid.vue @@ -59,6 +59,7 @@ const FORM_SLOT_PREFIX = 'form-'; const TOOLBAR_ACTIONS = 'toolbar-actions'; const TOOLBAR_TOOLS = 'toolbar-tools'; +const TABLE_TITLE = 'table-title'; const gridRef = useTemplateRef('gridRef'); @@ -129,7 +130,7 @@ const [Form, formApi] = useTableForm({ }); const showTableTitle = computed(() => { - return !!slots.tableTitle?.() || tableTitle.value; + return !!slots[TABLE_TITLE]?.() || tableTitle.value; }); const showToolbar = computed(() => {