feat:【antd】【erp 系统】sale/out 部分重构(form 部分重构 +1)

This commit is contained in:
YunaiV
2025-10-04 10:21:14 +08:00
parent c603b7002c
commit 86e701ba3a
3 changed files with 79 additions and 66 deletions

View File

@@ -52,7 +52,7 @@ const [Form, formApi] = useVbenForm({
}, },
}); });
/** 更新商品项 */ /** 更新销售订单项 */
const handleUpdateItems = (items: ErpSaleOrderApi.SaleOrderItem[]) => { const handleUpdateItems = (items: ErpSaleOrderApi.SaleOrderItem[]) => {
formData.value = modalApi.getData<ErpSaleOrderApi.SaleOrder>(); formData.value = modalApi.getData<ErpSaleOrderApi.SaleOrder>();
formData.value.items = items; formData.value.items = items;

View File

@@ -2,7 +2,7 @@
import type { ErpSaleOrderApi } from '#/api/erp/sale/order'; import type { ErpSaleOrderApi } from '#/api/erp/sale/order';
import type { ErpSaleOutApi } from '#/api/erp/sale/out'; import type { ErpSaleOutApi } from '#/api/erp/sale/out';
import { computed, nextTick, ref, watch } from 'vue'; import { computed, nextTick, ref } from 'vue';
import { useVbenModal } from '@vben/common-ui'; import { useVbenModal } from '@vben/common-ui';
import { $t } from '@vben/locales'; import { $t } from '@vben/locales';
@@ -67,25 +67,46 @@ const [Form, formApi] = useVbenForm({
schema: useFormSchema(formType.value), schema: useFormSchema(formType.value),
showDefaultActions: false, showDefaultActions: false,
handleValuesChange: (values, changedFields) => { handleValuesChange: (values, changedFields) => {
if (formData.value && changedFields.includes('otherPrice')) { // 目的:同步到 item-form 组件,触发整体的价格计算
if (formData.value) {
if (changedFields.includes('otherPrice')) {
formData.value.otherPrice = values.otherPrice; formData.value.otherPrice = values.otherPrice;
formData.value.totalPrice = }
(formData.value.discountedPrice || 0) + if (changedFields.includes('discountPercent')) {
(formData.value.otherPrice || 0); formData.value.discountPercent = values.discountPercent;
// TODO @芋艿:是否需要,去掉? }
formApi.setValues(formData.value, false);
} }
}, },
}); });
/** 更新销售出库项 */ /** 更新销售出库项 */
const handleUpdateItems = async (items: ErpSaleOutApi.SaleOutItem[]) => { const handleUpdateItems = (items: ErpSaleOutApi.SaleOutItem[]) => {
if (formData.value) { formData.value.items = items;
const data = await formApi.getValues(); formApi.setValues({
formData.value = { ...data, items }; items,
// TODO @芋艿:是否需要,去掉? });
await formApi.setValues(formData.value, false); };
}
/** 更新其他费用 */
const handleUpdateOtherPrice = (otherPrice: number) => {
formApi.setValues({
otherPrice,
});
};
/** 更新优惠金额 */
const handleUpdateDiscountPrice = (discountPrice: number) => {
formApi.setValues({
discountPrice,
});
};
/** 更新总金额 */
const handleUpdateTotalPrice = (totalPrice: number) => {
formApi.setValues({
totalPrice,
});
formData.value.totalPrice = totalPrice;
}; };
/** 选择销售订单 */ /** 选择销售订单 */
@@ -115,42 +136,6 @@ const handleUpdateOrder = (order: ErpSaleOrderApi.SaleOrder) => {
formApi.setValues(formData.value, false); formApi.setValues(formData.value, false);
}; };
// TODO @AI不确定
// watch(
// () => formData.value.items!,
// (newItems: ErpSaleOutApi.SaleOutItem[]) => {
// if (newItems && newItems.length > 0) {
// // 计算每个产品的总价、税额和总价
// newItems.forEach((item) => {
// item.totalProductPrice = (item.productPrice || 0) * (item.count || 0);
// item.taxPrice =
// (item.totalProductPrice || 0) * ((item.taxPercent || 0) / 100);
// item.totalPrice = (item.totalProductPrice || 0) + (item.taxPrice || 0);
// });
// // 计算总价
// formData.value.totalPrice = newItems.reduce((sum, item) => {
// return sum + (item.totalProductPrice || 0) + (item.taxPrice || 0);
// }, 0);
// } else {
// formData.value.totalPrice = 0;
// }
// // 优惠金额
// formData.value.discountPrice =
// ((formData.value.totalPrice || 0) *
// (formData.value.discountPercent || 0)) /
// 100;
// // 优惠后价格
// formData.value.discountedPrice =
// formData.value.totalPrice - formData.value.discountPrice;
//
// // 计算最终价格(包含其他费用)
// formData.value.totalPrice =
// formData.value.discountedPrice + (formData.value.otherPrice || 0);
// formApi.setValues(formData.value, false);
// },
// { immediate: true },
// );
/** 创建或更新销售出库 */ /** 创建或更新销售出库 */
const [Modal, modalApi] = useVbenModal({ const [Modal, modalApi] = useVbenModal({
async onConfirm() { async onConfirm() {
@@ -168,21 +153,9 @@ const [Modal, modalApi] = useVbenModal({
return; return;
} }
// 验证产品清单不能为空
// TODO @芋艿:需要校验么?
if (!formData.value?.items || formData.value.items.length === 0) {
message.error('产品清单不能为空,请至少添加一个产品');
return;
}
modalApi.lock(); modalApi.lock();
// 提交表单 // 提交表单
const data = (await formApi.getValues()) as ErpSaleOutApi.SaleOut; const data = (await formApi.getValues()) as ErpSaleOutApi.SaleOut;
data.items = formData.value?.items?.map((item) => ({
...item,
// 解决新增销售出库报错
id: undefined,
}));
try { try {
await (formType.value === 'create' await (formType.value === 'create'
? createSaleOut(data) ? createSaleOut(data)
@@ -211,7 +184,7 @@ const [Modal, modalApi] = useVbenModal({
otherPrice: 0, otherPrice: 0,
items: [], items: [],
}; };
await formApi.setValues(formData.value, false); // await formApi.setValues(formData.value, false);
return; return;
} }
// 加载数据 // 加载数据
@@ -283,7 +256,12 @@ defineExpose({ modalApi });
ref="itemFormRef" ref="itemFormRef"
:items="formData?.items ?? []" :items="formData?.items ?? []"
:disabled="formType === 'detail'" :disabled="formType === 'detail'"
:discount-percent="formData?.discountPercent ?? 0"
:other-price="formData?.otherPrice ?? 0"
@update:items="handleUpdateItems" @update:items="handleUpdateItems"
@update:discount-price="handleUpdateDiscountPrice"
@update:other-price="handleUpdateOtherPrice"
@update:total-price="handleUpdateTotalPrice"
/> />
</template> </template>
<template #orderNo> <template #orderNo>

View File

@@ -17,14 +17,23 @@ import { useFormItemColumns } from '../data';
interface Props { interface Props {
items?: ErpSaleOutApi.SaleOutItem[]; items?: ErpSaleOutApi.SaleOutItem[];
disabled?: boolean; disabled?: boolean;
discountPercent?: number;
otherPrice?: number;
} }
const props = withDefaults(defineProps<Props>(), { const props = withDefaults(defineProps<Props>(), {
items: () => [], items: () => [],
disabled: false, disabled: false,
discountPercent: 0,
otherPrice: 0,
}); });
const emit = defineEmits(['update:items', 'update:totalPrice']); const emit = defineEmits([
'update:items',
'update:discount-price',
'update:other-price',
'update:total-price',
]);
const tableData = ref<ErpSaleOutApi.SaleOutItem[]>([]); const tableData = ref<ErpSaleOutApi.SaleOutItem[]>([]);
const productOptions = ref<any[]>([]); const productOptions = ref<any[]>([]);
@@ -73,6 +82,32 @@ watch(
}, },
); );
/** 计算 discountPrice、totalPrice 价格 */
watch(
() => [tableData.value, props.discountPercent, props.otherPrice],
() => {
if (!tableData.value || tableData.value.length === 0) {
return;
}
const totalPrice = tableData.value.reduce(
(prev, curr) => prev + (curr.totalPrice || 0),
0,
);
const discountPrice =
props.discountPercent === null
? 0
: erpPriceMultiply(totalPrice, props.discountPercent / 100);
const discountedPrice = totalPrice - discountPrice!;
const finalTotalPrice = discountedPrice + (props.otherPrice || 0);
// 通知父组件更新
emit('update:discount-price', discountPrice);
emit('update:other-price', props.otherPrice || 0);
emit('update:total-price', finalTotalPrice);
},
{ deep: true },
);
/** 初始化 */ /** 初始化 */
onMounted(async () => { onMounted(async () => {
productOptions.value = await getProductSimpleList(); productOptions.value = await getProductSimpleList();