feat(wms):优化 antd、ele 的 order receipt 迁移

pull/345/head
YunaiV 2026-05-17 23:56:05 +08:00
parent 41d5aa93d6
commit f8c2d4b1ff
7 changed files with 51 additions and 31 deletions

View File

@ -397,13 +397,17 @@ interface ReceiptOrderDetailFooterRow {
quantity?: number;
totalPrice?: number;
}
type ReceiptOrderDetailFooterColumn = Pick<
NonNullable<NonNullable<VxeTableGridOptions['columns']>[number]>,
'field'
>;
/** 明细表格的合计行 */
export function getDetailFooter({
columns,
data,
}: {
columns: Array<{ field?: string }>;
columns: ReceiptOrderDetailFooterColumn[];
data: ReceiptOrderDetailFooterRow[];
}) {
return [

View File

@ -53,8 +53,16 @@ const [DetailModal, detailModalApi] = useVbenModal({
destroyOnClose: true,
});
/** 清空展开明细缓存 */
function clearDetailMap() {
for (const id of Object.keys(detailMap)) {
delete detailMap[Number(id)];
}
}
/** 刷新表格 */
function handleRefresh() {
clearDetailMap();
gridApi.query();
}
@ -162,7 +170,6 @@ const [Grid, gridApi] = useVbenVxeGrid({
columns: useGridColumns(),
expandConfig: {
padding: true,
trigger: 'default',
},
height: 'auto',
keepSource: true,

View File

@ -15,12 +15,10 @@ import { useDescription } from '#/components/description';
import {
formatPrice,
formatQuantity,
formatSumPrice,
formatSumQuantity,
multiplyPrice,
} from '#/views/wms/utils/format';
import { useDetailSchema } from '../data';
import { getDetailFooter, useDetailSchema } from '../data';
interface DetailRow extends WmsReceiptOrderDetailApi.ReceiptOrderDetail {
totalPrice?: number;
@ -80,7 +78,9 @@ const [Modal, modalApi] = useVbenModal({
:data="detailRows"
border
empty-text="暂无商品明细"
:footer-method="getDetailFooter"
:show-overflow="true"
show-footer
size="small"
>
<VxeColumn title="商品信息" min-width="220">
@ -99,7 +99,7 @@ const [Modal, modalApi] = useVbenModal({
</div>
</template>
</VxeColumn>
<VxeColumn title="数量" align="right" width="120">
<VxeColumn field="quantity" title="数量" align="right" width="120">
<template #default="{ row }">
{{ formatQuantity(row.quantity) || '-' }}
</template>
@ -110,16 +110,12 @@ const [Modal, modalApi] = useVbenModal({
{{ formatPrice(row.price) || '-' }}
</template>
</VxeColumn>
<VxeColumn title="总价" align="right" width="140">
<VxeColumn field="totalPrice" title="总价" align="right" width="140">
<template #default="{ row }">
{{ formatPrice(row.totalPrice) || '-' }}
</template>
</VxeColumn>
</VxeTable>
<div class="flex justify-end gap-6 text-sm">
<span>合计数量{{ formatSumQuantity(detailRows, (detail) => detail.quantity) }}</span>
<span>合计金额{{ formatSumPrice(detailRows, (detail) => detail.totalPrice) }}</span>
</div>
</div>
</Modal>
</template>

View File

@ -7,6 +7,7 @@ import type { WmsReceiptOrderDetailApi } from '#/api/wms/order/receipt/detail';
import { computed, nextTick, ref } from 'vue';
import { confirm, useVbenModal } from '@vben/common-ui';
import { isEqual } from '@vben/utils';
import { InputNumber, message } from 'ant-design-vue';
@ -46,9 +47,9 @@ defineOptions({ name: 'WmsReceiptOrderForm' });
const emit = defineEmits(['success']);
const formData = ref<WmsReceiptOrderApi.ReceiptOrder>();
const formData = ref<WmsReceiptOrderApi.ReceiptOrder>({});
const formMode = ref<FormMode>('create');
const originalSubmitData = ref('');
const originalSubmitData = ref<WmsReceiptOrderApi.ReceiptOrder>();
const details = ref<DetailRow[]>([]);
const detailTableRef = ref<VxeTableInstance>();
const skuSelectRef = ref<InstanceType<typeof WmsItemSkuSelect>>();
@ -237,7 +238,7 @@ async function buildSubmitData(): Promise<WmsReceiptOrderApi.ReceiptOrder> {
totalPrice: _totalPrice,
totalQuantity: _totalQuantity,
...order
} = formData.value || {};
} = formData.value;
return {
...order,
...values,
@ -255,7 +256,7 @@ async function handleFormComplete() {
modalApi.lock();
try {
const data = await buildSubmitData();
if (JSON.stringify(data) !== originalSubmitData.value) {
if (!isEqual(data, originalSubmitData.value)) {
await updateReceiptOrder(data);
}
await completeReceiptOrder(formData.value.id);
@ -307,8 +308,8 @@ const [Modal, modalApi] = useVbenModal({
},
async onOpenChange(isOpen: boolean) {
if (!isOpen) {
formData.value = undefined;
originalSubmitData.value = '';
formData.value = {};
originalSubmitData.value = undefined;
setDetails([]);
return;
}
@ -329,7 +330,7 @@ const [Modal, modalApi] = useVbenModal({
setDetails(orderDetails);
// values
await formApi.setValues(formData.value);
originalSubmitData.value = JSON.stringify(await buildSubmitData());
originalSubmitData.value = await buildSubmitData();
} finally {
modalApi.unlock();
}
@ -343,14 +344,18 @@ const [Modal, modalApi] = useVbenModal({
};
setDetails([]);
await formApi.setValues(formData.value);
originalSubmitData.value = JSON.stringify(await buildSubmitData());
originalSubmitData.value = await buildSubmitData();
await nextTick();
},
});
</script>
<template>
<Modal :title="getTitle" class="w-3/4">
<Modal
:title="getTitle"
class="w-3/4"
:show-confirm-button="isPrepareOrder"
>
<div class="mx-4">
<Form />
<div class="mt-4">

View File

@ -397,13 +397,17 @@ interface ReceiptOrderDetailFooterRow {
quantity?: number;
totalPrice?: number;
}
type ReceiptOrderDetailFooterColumn = Pick<
NonNullable<NonNullable<VxeTableGridOptions['columns']>[number]>,
'field'
>;
/** 明细表格的合计行 */
export function getDetailFooter({
columns,
data,
}: {
columns: Array<{ field?: string }>;
columns: ReceiptOrderDetailFooterColumn[];
data: ReceiptOrderDetailFooterRow[];
}) {
return [

View File

@ -169,7 +169,6 @@ const [Grid, gridApi] = useVbenVxeGrid({
columns: useGridColumns(),
expandConfig: {
padding: true,
trigger: 'default',
},
height: 'auto',
keepSource: true,

View File

@ -7,6 +7,7 @@ import type { WmsReceiptOrderDetailApi } from '#/api/wms/order/receipt/detail';
import { computed, nextTick, ref } from 'vue';
import { confirm, useVbenModal } from '@vben/common-ui';
import { isEqual } from '@vben/utils';
import { ElInputNumber, ElMessage } from 'element-plus';
@ -46,9 +47,9 @@ defineOptions({ name: 'WmsReceiptOrderForm' });
const emit = defineEmits(['success']);
const formData = ref<WmsReceiptOrderApi.ReceiptOrder>();
const formData = ref<WmsReceiptOrderApi.ReceiptOrder>({});
const formMode = ref<FormMode>('create');
const originalSubmitData = ref('');
const originalSubmitData = ref<WmsReceiptOrderApi.ReceiptOrder>();
const details = ref<DetailRow[]>([]);
const detailTableRef = ref<VxeTableInstance>();
const skuSelectRef = ref<InstanceType<typeof WmsItemSkuSelect>>();
@ -237,7 +238,7 @@ async function buildSubmitData(): Promise<WmsReceiptOrderApi.ReceiptOrder> {
totalPrice: _totalPrice,
totalQuantity: _totalQuantity,
...order
} = formData.value || {};
} = formData.value;
return {
...order,
...values,
@ -255,7 +256,7 @@ async function handleFormComplete() {
modalApi.lock();
try {
const data = await buildSubmitData();
if (JSON.stringify(data) !== originalSubmitData.value) {
if (!isEqual(data, originalSubmitData.value)) {
await updateReceiptOrder(data);
}
await completeReceiptOrder(formData.value.id);
@ -307,8 +308,8 @@ const [Modal, modalApi] = useVbenModal({
},
async onOpenChange(isOpen: boolean) {
if (!isOpen) {
formData.value = undefined;
originalSubmitData.value = '';
formData.value = {};
originalSubmitData.value = undefined;
setDetails([]);
return;
}
@ -329,7 +330,7 @@ const [Modal, modalApi] = useVbenModal({
setDetails(orderDetails);
// values
await formApi.setValues(formData.value);
originalSubmitData.value = JSON.stringify(await buildSubmitData());
originalSubmitData.value = await buildSubmitData();
} finally {
modalApi.unlock();
}
@ -343,14 +344,18 @@ const [Modal, modalApi] = useVbenModal({
};
setDetails([]);
await formApi.setValues(formData.value);
originalSubmitData.value = JSON.stringify(await buildSubmitData());
originalSubmitData.value = await buildSubmitData();
await nextTick();
},
});
</script>
<template>
<Modal :title="getTitle" class="w-3/4">
<Modal
:title="getTitle"
class="w-3/4"
:show-confirm-button="isPrepareOrder"
>
<div class="mx-4">
<Form />
<div class="mt-4">