fix(web-antdv-next): 同步 CRM 回款预填和 ERP 单据弹窗修复
parent
7bc60c481a
commit
4b77779e60
|
|
@ -57,12 +57,19 @@ export function useFormSchema(): VbenFormSchema[] {
|
|||
label: '客户名称',
|
||||
component: 'ApiSelect',
|
||||
rules: 'required',
|
||||
componentProps: {
|
||||
componentProps: (_values, form) => ({
|
||||
api: getCustomerSimpleList,
|
||||
labelField: 'name',
|
||||
valueField: 'id',
|
||||
placeholder: '请选择客户',
|
||||
},
|
||||
onChange: () => {
|
||||
form.setFieldValue('contractId', undefined);
|
||||
form.setFieldValue('planId', undefined);
|
||||
form.setFieldValue('price', undefined);
|
||||
form.setFieldValue('returnTime', undefined);
|
||||
form.setFieldValue('returnType', undefined);
|
||||
},
|
||||
}),
|
||||
dependencies: {
|
||||
triggerFields: ['id'],
|
||||
disabled: (values) => values.id,
|
||||
|
|
@ -76,21 +83,33 @@ export function useFormSchema(): VbenFormSchema[] {
|
|||
dependencies: {
|
||||
triggerFields: ['customerId'],
|
||||
disabled: (values) => !values.customerId || values.id,
|
||||
async componentProps(values) {
|
||||
if (values.customerId) {
|
||||
if (!values.id) {
|
||||
// 特殊:只有在【新增】时,才清空合同编号
|
||||
values.contractId = undefined;
|
||||
}
|
||||
const contracts = await getContractSimpleList(values.customerId);
|
||||
async componentProps(values, form) {
|
||||
if (!values.customerId) {
|
||||
return {
|
||||
options: contracts.map((item) => ({
|
||||
label: item.name,
|
||||
value: item.id,
|
||||
})),
|
||||
placeholder: '请选择合同',
|
||||
} as any;
|
||||
options: [],
|
||||
placeholder: '请选择客户',
|
||||
};
|
||||
}
|
||||
const contracts = await getContractSimpleList(values.customerId);
|
||||
return {
|
||||
options: contracts.map((item) => ({
|
||||
label: item.name,
|
||||
value: item.id,
|
||||
})),
|
||||
placeholder: '请选择合同',
|
||||
onChange: (value: number) => {
|
||||
form.setFieldValue('planId', undefined);
|
||||
form.setFieldValue('returnTime', undefined);
|
||||
form.setFieldValue('returnType', undefined);
|
||||
const contract = contracts.find((item) => item.id === value);
|
||||
form.setFieldValue(
|
||||
'price',
|
||||
contract
|
||||
? contract.totalPrice - contract.totalReceivablePrice
|
||||
: undefined,
|
||||
);
|
||||
},
|
||||
} as any;
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -101,28 +120,38 @@ export function useFormSchema(): VbenFormSchema[] {
|
|||
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,
|
||||
);
|
||||
disabled: (values) => !values.contractId || values.id,
|
||||
async componentProps(values, form) {
|
||||
if (!values.contractId) {
|
||||
return {
|
||||
options: plans.map((item) => ({
|
||||
label: item.period,
|
||||
value: item.id,
|
||||
})),
|
||||
placeholder: '请选择回款期数',
|
||||
onChange: async (value: any) => {
|
||||
const plan = await getReceivablePlan(value);
|
||||
values.returnTime = plan?.returnTime;
|
||||
values.price = plan?.price;
|
||||
values.returnType = plan?.returnType;
|
||||
},
|
||||
} as any;
|
||||
options: [],
|
||||
placeholder: '请选择合同',
|
||||
};
|
||||
}
|
||||
const plans = await getReceivablePlanSimpleList(
|
||||
values.customerId,
|
||||
values.contractId,
|
||||
);
|
||||
return {
|
||||
options: plans.map((item) => ({
|
||||
disabled: !!item.receivableId,
|
||||
label: `第 ${item.period} 期`,
|
||||
value: item.id,
|
||||
})),
|
||||
placeholder: '请选择回款期数',
|
||||
onChange: async (value: any) => {
|
||||
if (!value) {
|
||||
form.setFieldValue('returnTime', undefined);
|
||||
form.setFieldValue('price', undefined);
|
||||
form.setFieldValue('returnType', undefined);
|
||||
return;
|
||||
}
|
||||
const plan = await getReceivablePlan(value);
|
||||
form.setFieldValue('returnTime', plan?.returnTime);
|
||||
form.setFieldValue('price', plan?.price);
|
||||
form.setFieldValue('returnType', plan?.returnType);
|
||||
},
|
||||
} as any;
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import { useVbenForm, useVbenModal } from '@vben/common-ui';
|
|||
|
||||
import { message } from 'antdv-next';
|
||||
|
||||
import { getContractSimpleList } from '#/api/crm/contract';
|
||||
import {
|
||||
createReceivable,
|
||||
getReceivable,
|
||||
|
|
@ -16,8 +17,20 @@ import { $t } from '#/locales';
|
|||
|
||||
import { useFormSchema } from '../data';
|
||||
|
||||
type ReceivablePrefillData = Partial<
|
||||
Pick<
|
||||
CrmReceivableApi.Receivable,
|
||||
'contractId' | 'customerId' | 'price' | 'returnType'
|
||||
>
|
||||
> & { id?: number };
|
||||
|
||||
type ReceivableFormModalData = ReceivablePrefillData & {
|
||||
plan?: ReceivablePrefillData;
|
||||
receivable?: Pick<CrmReceivableApi.Receivable, 'id'>;
|
||||
};
|
||||
|
||||
const emit = defineEmits(['success']);
|
||||
const formData = ref<CrmReceivableApi.Receivable>();
|
||||
const formData = ref<Partial<CrmReceivableApi.Receivable>>();
|
||||
const getTitle = computed(() => {
|
||||
return formData.value?.id
|
||||
? $t('ui.actionTitle.edit', ['回款'])
|
||||
|
|
@ -36,6 +49,32 @@ const [Form, formApi] = useVbenForm({
|
|||
showDefaultActions: false,
|
||||
});
|
||||
|
||||
/** 构建新增回款的预填表单 */
|
||||
async function buildCreateFormData(
|
||||
plan: ReceivablePrefillData,
|
||||
): Promise<Partial<CrmReceivableApi.Receivable>> {
|
||||
const values: Partial<CrmReceivableApi.Receivable> = {
|
||||
contractId: plan?.contractId,
|
||||
customerId: plan?.customerId,
|
||||
};
|
||||
// 从回款计划创建时,直接继承计划的期数、金额和回款方式
|
||||
if (plan?.id) {
|
||||
values.planId = plan.id;
|
||||
values.price = plan.price;
|
||||
values.returnType = plan.returnType;
|
||||
return values;
|
||||
}
|
||||
// 从客户/合同详情创建时,没有计划期数,按合同剩余应回款金额预填
|
||||
if (values.customerId && values.contractId) {
|
||||
const contracts = await getContractSimpleList(values.customerId);
|
||||
const contract = contracts.find((item) => item.id === values.contractId);
|
||||
if (contract) {
|
||||
values.price = contract.totalPrice - contract.totalReceivablePrice;
|
||||
}
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
const [Modal, modalApi] = useVbenModal({
|
||||
async onConfirm() {
|
||||
const { valid } = await formApi.validate();
|
||||
|
|
@ -63,31 +102,26 @@ const [Modal, modalApi] = useVbenModal({
|
|||
return;
|
||||
}
|
||||
// 加载数据
|
||||
const data = modalApi.getData();
|
||||
formData.value = undefined;
|
||||
await formApi.resetForm();
|
||||
const data = modalApi.getData() as null | ReceivableFormModalData;
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
const { receivable, plan } = data;
|
||||
const { receivable } = data;
|
||||
const plan =
|
||||
data.plan ?? (data.customerId || data.contractId ? data : undefined);
|
||||
modalApi.lock();
|
||||
try {
|
||||
if (receivable) {
|
||||
if (receivable?.id) {
|
||||
formData.value = await getReceivable(receivable.id!);
|
||||
} 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,
|
||||
} as any);
|
||||
formData.value = await buildCreateFormData(plan);
|
||||
}
|
||||
if (formData.value) {
|
||||
// 设置到 values
|
||||
await formApi.setValues(formData.value as any);
|
||||
}
|
||||
// 设置到 values
|
||||
await formApi.setValues(formData.value as any);
|
||||
} finally {
|
||||
modalApi.unlock();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -176,6 +176,7 @@ const [Modal, modalApi] = useVbenModal({
|
|||
<Modal
|
||||
:title="getTitle"
|
||||
class="w-3/4"
|
||||
:close-on-click-modal="false"
|
||||
:show-confirm-button="formType !== 'detail'"
|
||||
>
|
||||
<Form class="mx-3">
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||
},
|
||||
gridOptions: {
|
||||
columns: usePurchaseInGridColumns(),
|
||||
height: 'auto',
|
||||
height: 520,
|
||||
keepSource: true,
|
||||
proxyConfig: {
|
||||
ajax: {
|
||||
|
|
@ -95,14 +95,12 @@ defineExpose({ open: openModal });
|
|||
|
||||
<template>
|
||||
<Modal
|
||||
class="!w-[50vw]"
|
||||
v-model:open="open"
|
||||
title="选择采购入库单"
|
||||
@ok="handleOk"
|
||||
width="80%"
|
||||
@cancel.stop="open = false"
|
||||
@ok.stop="handleOk"
|
||||
>
|
||||
<Grid
|
||||
class="max-h-[600px]"
|
||||
table-title="采购入库单列表(仅展示可付款的单据)"
|
||||
/>
|
||||
<Grid table-title="采购入库单列表(仅展示可付款的单据)" />
|
||||
</Modal>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||
},
|
||||
gridOptions: {
|
||||
columns: useSaleReturnGridColumns(),
|
||||
height: 'auto',
|
||||
height: 520,
|
||||
keepSource: true,
|
||||
proxyConfig: {
|
||||
ajax: {
|
||||
|
|
@ -99,14 +99,12 @@ defineExpose({ open: openModal });
|
|||
|
||||
<template>
|
||||
<Modal
|
||||
class="!w-[50vw]"
|
||||
v-model:open="open"
|
||||
title="选择采购退货单"
|
||||
@ok="handleOk"
|
||||
width="80%"
|
||||
@cancel.stop="open = false"
|
||||
@ok.stop="handleOk"
|
||||
>
|
||||
<Grid
|
||||
class="max-h-[600px]"
|
||||
table-title="采购退货单列表(仅展示需退款的单据)"
|
||||
/>
|
||||
<Grid table-title="采购退货单列表(仅展示需退款的单据)" />
|
||||
</Modal>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -190,6 +190,7 @@ const [Modal, modalApi] = useVbenModal({
|
|||
<Modal
|
||||
:title="getTitle"
|
||||
class="w-3/4"
|
||||
:close-on-click-modal="false"
|
||||
:show-confirm-button="formType !== 'detail'"
|
||||
>
|
||||
<Form class="mx-3">
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||
},
|
||||
gridOptions: {
|
||||
columns: useSaleOutGridColumns(),
|
||||
height: 'auto',
|
||||
height: 520,
|
||||
keepSource: true,
|
||||
proxyConfig: {
|
||||
ajax: {
|
||||
|
|
@ -91,14 +91,12 @@ defineExpose({ open: openModal });
|
|||
|
||||
<template>
|
||||
<Modal
|
||||
class="!w-[50vw]"
|
||||
v-model:open="open"
|
||||
title="选择销售出库单"
|
||||
@ok="handleOk"
|
||||
width="80%"
|
||||
@cancel.stop="open = false"
|
||||
@ok.stop="handleOk"
|
||||
>
|
||||
<Grid
|
||||
class="max-h-[600px]"
|
||||
table-title="销售出库单列表(仅展示可收款的单据)"
|
||||
/>
|
||||
<Grid table-title="销售出库单列表(仅展示可收款的单据)" />
|
||||
</Modal>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||
},
|
||||
gridOptions: {
|
||||
columns: useSaleReturnGridColumns(),
|
||||
height: 'auto',
|
||||
height: 520,
|
||||
keepSource: true,
|
||||
proxyConfig: {
|
||||
ajax: {
|
||||
|
|
@ -95,14 +95,12 @@ defineExpose({ open: openModal });
|
|||
|
||||
<template>
|
||||
<Modal
|
||||
class="!w-[50vw]"
|
||||
v-model:open="open"
|
||||
title="选择销售退货单"
|
||||
@ok="handleOk"
|
||||
width="80%"
|
||||
@cancel.stop="open = false"
|
||||
@ok.stop="handleOk"
|
||||
>
|
||||
<Grid
|
||||
class="max-h-[600px]"
|
||||
table-title="销售退货单列表(仅展示可退款的单据)"
|
||||
/>
|
||||
<Grid table-title="销售退货单列表(仅展示可退款的单据)" />
|
||||
</Modal>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -206,6 +206,7 @@ const [Modal, modalApi] = useVbenModal({
|
|||
<Modal
|
||||
:title="getTitle"
|
||||
class="w-3/4"
|
||||
:close-on-click-modal="false"
|
||||
:show-confirm-button="formType !== 'detail'"
|
||||
>
|
||||
<Form class="mx-3">
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ const [Grid] = useVbenVxeGrid({
|
|||
},
|
||||
gridOptions: {
|
||||
columns: useOrderGridColumns(),
|
||||
height: 'auto',
|
||||
height: 520,
|
||||
keepSource: true,
|
||||
proxyConfig: {
|
||||
ajax: {
|
||||
|
|
@ -108,12 +108,13 @@ function handleOk() {
|
|||
</template>
|
||||
</Input>
|
||||
<Modal
|
||||
class="!w-[50vw]"
|
||||
v-model:open="open"
|
||||
title="选择关联订单"
|
||||
@ok="handleOk"
|
||||
width="80%"
|
||||
@cancel.stop="open = false"
|
||||
@ok.stop="handleOk"
|
||||
>
|
||||
<Grid class="max-h-[600px]" table-title="采购订单列表(仅展示可退货)" />
|
||||
<Grid table-title="采购订单列表(仅展示可退货)" />
|
||||
</Modal>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -206,6 +206,7 @@ const [Modal, modalApi] = useVbenModal({
|
|||
<Modal
|
||||
:title="getTitle"
|
||||
class="w-3/4"
|
||||
:close-on-click-modal="false"
|
||||
:show-confirm-button="formType !== 'detail'"
|
||||
>
|
||||
<Form class="mx-3">
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ const [Grid] = useVbenVxeGrid({
|
|||
},
|
||||
gridOptions: {
|
||||
columns: useOrderGridColumns(),
|
||||
height: 'auto',
|
||||
height: 520,
|
||||
keepSource: true,
|
||||
proxyConfig: {
|
||||
ajax: {
|
||||
|
|
@ -108,12 +108,13 @@ function handleOk() {
|
|||
</template>
|
||||
</Input>
|
||||
<Modal
|
||||
class="!w-[50vw]"
|
||||
v-model:open="open"
|
||||
title="选择关联订单"
|
||||
@ok="handleOk"
|
||||
width="80%"
|
||||
@cancel.stop="open = false"
|
||||
@ok.stop="handleOk"
|
||||
>
|
||||
<Grid class="max-h-[600px]" table-title="采购订单列表(仅展示可退货)" />
|
||||
<Grid table-title="采购订单列表(仅展示可退货)" />
|
||||
</Modal>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -201,6 +201,7 @@ const [Modal, modalApi] = useVbenModal({
|
|||
<Modal
|
||||
:title="getTitle"
|
||||
class="w-3/4"
|
||||
:close-on-click-modal="false"
|
||||
:show-confirm-button="formType !== 'detail'"
|
||||
>
|
||||
<Form class="mx-3">
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ const [Grid] = useVbenVxeGrid({
|
|||
},
|
||||
gridOptions: {
|
||||
columns: useOrderGridColumns(),
|
||||
height: 'auto',
|
||||
height: 520,
|
||||
keepSource: true,
|
||||
proxyConfig: {
|
||||
ajax: {
|
||||
|
|
@ -108,12 +108,13 @@ function handleOk() {
|
|||
</template>
|
||||
</Input>
|
||||
<Modal
|
||||
class="!w-[50vw]"
|
||||
v-model:open="open"
|
||||
title="选择关联订单"
|
||||
@ok="handleOk"
|
||||
width="80%"
|
||||
@cancel.stop="open = false"
|
||||
@ok.stop="handleOk"
|
||||
>
|
||||
<Grid class="max-h-[600px]" table-title="销售订单列表(仅展示可出库)" />
|
||||
<Grid table-title="销售订单列表(仅展示可出库)" />
|
||||
</Modal>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -206,6 +206,7 @@ const [Modal, modalApi] = useVbenModal({
|
|||
<Modal
|
||||
:title="getTitle"
|
||||
class="w-3/4"
|
||||
:close-on-click-modal="false"
|
||||
:show-confirm-button="formType !== 'detail'"
|
||||
>
|
||||
<Form class="mx-3">
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ const [Grid] = useVbenVxeGrid({
|
|||
},
|
||||
gridOptions: {
|
||||
columns: useOrderGridColumns(),
|
||||
height: 'auto',
|
||||
height: 520,
|
||||
keepSource: true,
|
||||
proxyConfig: {
|
||||
ajax: {
|
||||
|
|
@ -108,12 +108,13 @@ function handleOk() {
|
|||
</template>
|
||||
</Input>
|
||||
<Modal
|
||||
class="!w-[50vw]"
|
||||
v-model:open="open"
|
||||
title="选择关联订单"
|
||||
@ok="handleOk"
|
||||
width="80%"
|
||||
@cancel.stop="open = false"
|
||||
@ok.stop="handleOk"
|
||||
>
|
||||
<Grid class="max-h-[600px]" table-title="销售订单列表(仅展示可退货)" />
|
||||
<Grid table-title="销售订单列表(仅展示可退货)" />
|
||||
</Modal>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
Loading…
Reference in New Issue