diff --git a/apps/web-antd/src/views/crm/followup/data.ts b/apps/web-antd/src/views/crm/followup/data.ts index 6c7f8b14..b64a59ec 100644 --- a/apps/web-antd/src/views/crm/followup/data.ts +++ b/apps/web-antd/src/views/crm/followup/data.ts @@ -1,7 +1,162 @@ +import type { Ref } from 'vue'; + +import type { VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; import type { DescriptionItemSchema } from '#/components/description'; +import { DICT_TYPE } from '@vben/constants'; +import { getDictOptions } from '@vben/hooks'; import { formatDateTime } from '@vben/utils'; +import { getBusinessPageByCustomer } from '#/api/crm/business'; +import { getContactPageByCustomer } from '#/api/crm/contact'; +import { BizTypeEnum } from '#/api/crm/permission'; + +/** 新增/修改的表单 */ +export function useFormSchema( + bizId: Ref, +): VbenFormSchema[] { + return [ + { + component: 'Input', + fieldName: 'bizId', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + component: 'Input', + fieldName: 'bizType', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'type', + label: '跟进类型', + component: 'Select', + componentProps: { + options: getDictOptions(DICT_TYPE.CRM_FOLLOW_UP_TYPE, 'number'), + }, + rules: 'required', + }, + { + fieldName: 'nextTime', + label: '下次联系时间', + component: 'DatePicker', + componentProps: { + showTime: true, + format: 'YYYY-MM-DD HH:mm:ss', + valueFormat: 'x', + }, + rules: 'required', + }, + { + fieldName: 'content', + label: '跟进内容', + component: 'Textarea', + rules: 'required', + }, + { + fieldName: 'picUrls', + label: '图片', + component: 'ImageUpload', + }, + { + fieldName: 'fileUrls', + label: '附件', + component: 'FileUpload', + }, + { + fieldName: 'contactIds', + label: '关联联系人', + component: 'ApiSelect', + componentProps: { + api: async () => { + if (!bizId.value) { + return []; + } + const res = await getContactPageByCustomer({ + pageNo: 1, + pageSize: 100, + customerId: bizId.value, + }); + return res.list; + }, + mode: 'multiple', + fieldNames: { label: 'name', value: 'id' }, + }, + }, + { + fieldName: 'businessIds', + label: '关联商机', + component: 'ApiSelect', + componentProps: { + api: async () => { + if (!bizId.value) { + return []; + } + const res = await getBusinessPageByCustomer({ + pageNo: 1, + pageSize: 100, + customerId: bizId.value, + }); + return res.list; + }, + mode: 'multiple', + fieldNames: { label: 'name', value: 'id' }, + }, + }, + ]; +} + +/** 列表的字段 */ +export function useGridColumns( + bizType: number, +): VxeTableGridOptions['columns'] { + return [ + { + field: 'createTime', + title: '创建时间', + formatter: 'formatDateTime', + }, + { field: 'creatorName', title: '跟进人' }, + { + field: 'type', + title: '跟进类型', + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.CRM_FOLLOW_UP_TYPE }, + }, + }, + { field: 'content', title: '跟进内容' }, + { + field: 'nextTime', + title: '下次联系时间', + formatter: 'formatDateTime', + }, + { + field: 'contacts', + title: '关联联系人', + visible: bizType === BizTypeEnum.CRM_CUSTOMER, + slots: { default: 'contacts' }, + }, + { + field: 'businesses', + title: '关联商机', + visible: bizType === BizTypeEnum.CRM_CUSTOMER, + slots: { default: 'businesses' }, + }, + { + field: 'actions', + title: '操作', + slots: { default: 'actions' }, + }, + ]; +} + /** 详情页的系统字段 */ export function useFollowUpDetailSchema(): DescriptionItemSchema[] { return [ @@ -33,4 +188,4 @@ export function useFollowUpDetailSchema(): DescriptionItemSchema[] { content: (data) => formatDateTime(data?.updateTime) as string, }, ]; -} +} \ No newline at end of file diff --git a/apps/web-antd/src/views/crm/followup/index.vue b/apps/web-antd/src/views/crm/followup/index.vue index a24ec7a4..1467db44 100644 --- a/apps/web-antd/src/views/crm/followup/index.vue +++ b/apps/web-antd/src/views/crm/followup/index.vue @@ -6,7 +6,6 @@ import { watch } from 'vue'; import { useRouter } from 'vue-router'; import { useVbenModal } from '@vben/common-ui'; -import { DICT_TYPE } from '@vben/constants'; import { Button, message } from 'ant-design-vue'; @@ -15,9 +14,9 @@ import { deleteFollowUpRecord, getFollowUpRecordPage, } from '#/api/crm/followup'; -import { BizTypeEnum } from '#/api/crm/permission'; import { $t } from '#/locales'; +import { useGridColumns } from './data'; import FollowUpRecordForm from './modules/form.vue'; /** 跟进记录列表 */ @@ -50,7 +49,7 @@ async function handleDelete(row: CrmFollowUpApi.FollowUpRecord) { await deleteFollowUpRecord(row.id); message.success($t('ui.actionMessage.deleteSuccess', [row.id])); handleRefresh(); - } catch { + } finally { hideLoading(); } } @@ -72,45 +71,7 @@ const [FormModal, formModalApi] = useVbenModal({ const [Grid, gridApi] = useVbenVxeGrid({ gridOptions: { - columns: [ - { - field: 'createTime', - title: '创建时间', - formatter: 'formatDateTime', - }, - { field: 'creatorName', title: '跟进人' }, - { - field: 'type', - title: '跟进类型', - cellRender: { - name: 'CellDict', - props: { type: DICT_TYPE.CRM_FOLLOW_UP_TYPE }, - }, - }, - { field: 'content', title: '跟进内容' }, - { - field: 'nextTime', - title: '下次联系时间', - formatter: 'formatDateTime', - }, - { - field: 'contacts', - title: '关联联系人', - visible: props.bizType === BizTypeEnum.CRM_CUSTOMER, - slots: { default: 'contacts' }, - }, - { - field: 'businesses', - title: '关联商机', - visible: props.bizType === BizTypeEnum.CRM_CUSTOMER, - slots: { default: 'businesses' }, - }, - { - field: 'actions', - title: '操作', - slots: { default: 'actions' }, - }, - ], + columns: useGridColumns(props.bizType), height: 600, keepSource: true, proxyConfig: { @@ -135,6 +96,7 @@ const [Grid, gridApi] = useVbenVxeGrid({ } as VxeTableGridOptions, }); +/** 监听业务 ID 变化 */ watch( () => props.bizId, () => { @@ -160,13 +122,25 @@ watch( />