diff --git a/apps/web-antd/src/views/crm/receivable/data.ts b/apps/web-antd/src/views/crm/receivable/data.ts index 558b284fc..cbbc5c25f 100644 --- a/apps/web-antd/src/views/crm/receivable/data.ts +++ b/apps/web-antd/src/views/crm/receivable/data.ts @@ -1,24 +1,48 @@ 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 { DICT_TYPE } from '#/utils/dict'; +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: '请输入回款编号', + placeholder: '保存时自动生成', + disabled: true, + }, + }, + { + fieldName: 'ownerUserId', + label: '负责人', + component: 'ApiSelect', + rules: 'required', + componentProps: { + api: getSimpleUserList, + labelField: 'nickname', + valueField: 'id', + placeholder: '请选择客户', }, }, { fieldName: 'customerId', - label: '客户', + label: '客户名称', component: 'ApiSelect', rules: 'required', componentProps: { @@ -30,23 +54,63 @@ export function useFormSchema(): VbenFormSchema[] { }, { fieldName: 'contractId', - label: '合同', - component: 'ApiSelect', + label: '合同名称', + component: 'Select', rules: 'required', - componentProps: { - api: getCustomerSimpleList, - labelField: 'name', - valueField: 'id', - placeholder: '请选择合同', + 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', - rules: 'required', componentProps: { placeholder: '请选择回款日期', + showTime: false, + valueFormat: 'x', + format: 'YYYY-MM-DD', }, }, { @@ -63,10 +127,10 @@ export function useFormSchema(): VbenFormSchema[] { { fieldName: 'returnType', label: '回款方式', - component: 'DictSelect', + component: 'Select', rules: 'required', componentProps: { - type: DICT_TYPE.CRM_RECEIVABLE_RETURN_TYPE, + options: getDictOptions(DICT_TYPE.CRM_RECEIVABLE_RETURN_TYPE, 'number'), placeholder: '请选择回款方式', }, }, diff --git a/apps/web-antd/src/views/crm/receivable/index.vue b/apps/web-antd/src/views/crm/receivable/index.vue index 14802db09..ff187d968 100644 --- a/apps/web-antd/src/views/crm/receivable/index.vue +++ b/apps/web-antd/src/views/crm/receivable/index.vue @@ -49,7 +49,7 @@ function handleCreate() { /** 编辑回款 */ function handleEdit(row: CrmReceivableApi.Receivable) { - formModalApi.setData(row).open(); + formModalApi.setData({ receivable: row }).open(); } /** 删除回款 */ diff --git a/apps/web-antd/src/views/crm/receivable/modules/form.vue b/apps/web-antd/src/views/crm/receivable/modules/form.vue index 0166fb2b3..e92610c25 100644 --- a/apps/web-antd/src/views/crm/receivable/modules/form.vue +++ b/apps/web-antd/src/views/crm/receivable/modules/form.vue @@ -65,12 +65,28 @@ const [Modal, modalApi] = useVbenModal({ } // 加载数据 const data = modalApi.getData(); - if (!data || !data.id) { + if (!data) { return; } + const { receivable, plan } = data; modalApi.lock(); try { - formData.value = await getReceivable(data.id as number); + if (receivable) { + formData.value = await getReceivable(receivable.id as number); + } else if (plan) { + formData.value = plan.id + ? { + planId: plan.id, + price: plan.price, + returnType: plan.returnType, + customerId: plan.customerId, + contractId: plan.contractId, + } + : { + customerId: plan.customerId, + contractId: plan.contractId, + }; + } // 设置到 values await formApi.setValues(formData.value); } finally { 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 @@ + + +