diff --git a/src/pages/fulfillment/OrderFulfillmentCreate.vue b/src/pages/fulfillment/OrderFulfillmentCreate.vue index e39e651..6e20cb6 100644 --- a/src/pages/fulfillment/OrderFulfillmentCreate.vue +++ b/src/pages/fulfillment/OrderFulfillmentCreate.vue @@ -159,7 +159,7 @@ const sourceItems = computed(() => (order.value?.itemList | && 0 < comparePackageQuantity(item.availableBaseQuantity ?? "0", "0"))); const unitPickerOptions = computed(() => { const item = sourceItems.value.find(value => value.id === unitPickerSourceItemId.value); - return item ? getSellableUnitList(item).map(unit => ({ label: unit.name, value: unit.id || "" })) : []; + return item ? getFulfillmentUnitList(item).map(unit => ({ label: unit.name, value: unit.id || "" })) : []; }); const canFulfillByPayment = computed(() => order.value?.paymentStatus === "PAID" || userStore.hasRoles(gaoRoleCodes.storeManager)); @@ -191,8 +191,8 @@ async function loadFulfillmentSkuList(): Promise { if (!item.id || fulfillmentUnitMap[item.id]) { continue; } - const originalUnit = getSellableUnitList(item).find(unit => unit.id === item.skuUnitId); - const defaultUnit = getFulfillmentUnitForAvailableQuantity(item, originalUnit || getSellableUnitList(item)[0]); + const originalUnit = getFulfillmentUnitList(item).find(unit => unit.id === item.skuUnitId); + const defaultUnit = getFulfillmentUnitForAvailableQuantity(item, originalUnit || getFulfillmentUnitList(item)[0]); if (defaultUnit?.id) { fulfillmentUnitMap[item.id] = defaultUnit.id; } @@ -222,7 +222,7 @@ function getBaseUnitName(item: GaoSalesOrderItem): string { } function getBaseUnit(item: GaoSalesOrderItem): ProductSkuUnit | undefined { - return getSellableUnitList(item).find(unit => unit.isBase); + return getFulfillmentUnitList(item).find(unit => unit.isBase); } function shouldDowngradeUnit(item: GaoSalesOrderItem, unit?: ProductSkuUnit): boolean { @@ -254,12 +254,25 @@ function fillAllQuantity(item: GaoSalesOrderItem): void { quantityMap[item.id] = quantity; } -function getSellableUnitList(item: GaoSalesOrderItem): ProductSkuUnit[] { - return (item.skuId ? fulfillmentSkuMap[item.skuId]?.unitList : [])?.filter(unit => unit.allowSale !== false && !!unit.id) || []; +function getFulfillmentUnitList(item: GaoSalesOrderItem): ProductSkuUnit[] { + const unitList = (item.skuId ? fulfillmentSkuMap[item.skuId]?.unitList : [])?.filter(unit => !!unit.id) || []; + if (!item.skuUnitId) { + return unitList; + } + const originalUnit: ProductSkuUnit = { + ...(unitList.find(unit => unit.id === item.skuUnitId) || {}), + id: item.skuUnitId, + skuId: item.skuId, + name: item.unitSnapshot || "成交单位", + baseQuantityPerUnit: item.baseQuantityPerUnitSnapshot ?? "1", + allowPurchase: false, + allowSale: false + }; + return [originalUnit, ...unitList.filter(unit => unit.id !== item.skuUnitId)]; } function getFulfillmentUnit(item: GaoSalesOrderItem): ProductSkuUnit | undefined { - return getSellableUnitList(item).find(unit => unit.id === fulfillmentUnitMap[item.id || ""]); + return getFulfillmentUnitList(item).find(unit => unit.id === fulfillmentUnitMap[item.id || ""]); } function setFulfillmentUnit(item: GaoSalesOrderItem, unit: ProductSkuUnit): void { @@ -282,19 +295,19 @@ function openUnitPicker(item: GaoSalesOrderItem): void { if (!item.id) { return; } - if (!getSellableUnitList(item).length) { - Message.warning("当前 SKU 没有可用于履约的销售单位"); + if (!getFulfillmentUnitList(item).length) { + Message.warning("当前 SKU 没有可用于履约的单位"); return; } unitPickerSourceItemId.value = item.id; - unitPickerDraft.value = [fulfillmentUnitMap[item.id] || getSellableUnitList(item)[0]?.id || ""]; + unitPickerDraft.value = [fulfillmentUnitMap[item.id] || getFulfillmentUnitList(item)[0]?.id || ""]; unitPickerVisible.value = true; } function confirmUnitPicker(value: Array): void { const skuUnitId = String(value[0] || ""); const item = sourceItems.value.find(sourceItem => sourceItem.id === unitPickerSourceItemId.value); - const selectedUnit = item ? getSellableUnitList(item).find(unit => unit.id === skuUnitId) : undefined; + const selectedUnit = item ? getFulfillmentUnitList(item).find(unit => unit.id === skuUnitId) : undefined; const fulfillmentUnit = item ? getFulfillmentUnitForAvailableQuantity(item, selectedUnit) : selectedUnit; if (item?.id && fulfillmentUnit?.id) { setFulfillmentUnit(item, fulfillmentUnit); diff --git a/src/pages/product/ProductEdit.vue b/src/pages/product/ProductEdit.vue index 23f8e40..6055103 100644 --- a/src/pages/product/ProductEdit.vue +++ b/src/pages/product/ProductEdit.vue @@ -418,11 +418,19 @@ function closeBatchUnitEditor(): void { function applyBatchUnitTemplate(): void { const templateList = batchUnitList.value; + for (const sku of form.skuList) { + const templateNameSet = new Set(templateList.map(unit => unit.name.trim())); + if (sku.unitList.some(unit => !!unit.id && !templateNameSet.has(unit.name.trim()))) { + Message.warning("统一配置不能删除或重命名已保存单位,请在 SKU 明细中停售"); + return; + } + } form.skuList.forEach(sku => { const oldUnitList = sku.unitList; + const oldUnitMap = new Map(oldUnitList.filter(unit => !!unit.id).map(unit => [unit.name.trim(), unit])); sku.unitList = templateList.map((unit, unitIndex) => ({ ...unit, - id: oldUnitList[unitIndex]?.id, + id: oldUnitMap.get(unit.name.trim())?.id, skuId: sku.id, clientKey: window.crypto.randomUUID(), sort: unitIndex diff --git a/src/pages/product/component/ProductSkuUnitEditor.vue b/src/pages/product/component/ProductSkuUnitEditor.vue index a400099..fd4bd74 100644 --- a/src/pages/product/component/ProductSkuUnitEditor.vue +++ b/src/pages/product/component/ProductSkuUnitEditor.vue @@ -28,7 +28,15 @@
- +
@@ -134,6 +142,13 @@ function removeUnit(index: number): void { Message.warning("每个 SKU 至少需要一个单位"); return; } + const unit = sku.value.unitList[index]; + if (unit?.id) { + unit.allowSale = false; + unit.allowPurchase = false; + Message.success("单位已停售并禁止采购,历史订单仍可履约"); + return; + } const wasBase = sku.value.unitList[index]?.isBase; sku.value.unitList.splice(index, 1); if (wasBase && sku.value.unitList[0]) {