From b937241a2c20f62f45b31b232b6cebdec03d41d7 Mon Sep 17 00:00:00 2001
From: spring <2396852758@qq.com>
Date: 星期二, 31 三月 2026 15:57:42 +0800
Subject: [PATCH] fix: 销售批号
---
src/views/procurementManagement/procurementLedger/index.vue | 13 ++
src/views/salesManagement/salesLedger/index.vue | 304 +++++++++++++++++++++++++++++++++++++++-----------
src/api/inventoryManagement/stockInventory.js | 11 +
3 files changed, 261 insertions(+), 67 deletions(-)
diff --git a/src/api/inventoryManagement/stockInventory.js b/src/api/inventoryManagement/stockInventory.js
index 92b3892c..750f638 100644
--- a/src/api/inventoryManagement/stockInventory.js
+++ b/src/api/inventoryManagement/stockInventory.js
@@ -65,4 +65,13 @@
url: "/stockInventory/getMaterials",
method: "get",
});
-}
\ No newline at end of file
+}
+
+// 鑾峰彇搴撳瓨鏍戯紙浜у搧->瑙勬牸/鍨嬪彿->鎵瑰彿->渚涘簲鍟嗭級
+export const getStockInventoryAll = (params = {}) => {
+ return request({
+ url: "/stockInventory/getStockInventoryAll",
+ method: "get",
+ params,
+ });
+};
\ No newline at end of file
diff --git a/src/views/procurementManagement/procurementLedger/index.vue b/src/views/procurementManagement/procurementLedger/index.vue
index 3ac30e6..5efc890 100644
--- a/src/views/procurementManagement/procurementLedger/index.vue
+++ b/src/views/procurementManagement/procurementLedger/index.vue
@@ -410,6 +410,7 @@
prop="unit"
width="70" />
<el-table-column label="UID鐮�" prop="uidNo" />
+ <el-table-column label="鎵规鍙�" prop="batchNo" />
<el-table-column label="鏁伴噺"
prop="quantity"
width="70" />
@@ -580,6 +581,17 @@
</el-form-item>
</el-col>
</el-row>
+ <el-row :gutter="30">
+ <el-col :span="24">
+ <el-form-item label="鎵规鍙凤細"
+ prop="batchNo">
+ <el-input v-model="productForm.batchNo"
+ placeholder="璇疯緭鍏�"
+ disabled />
+ </el-form-item>
+ </el-col>
+ </el-row>
+
<el-row :gutter="30">
<el-col :span="12">
<el-form-item label="鍗曚綅锛�"
@@ -964,6 +976,7 @@
productCategory: "",
productModelId: "",
uidNo: "",
+ batchNo: "",
specificationModel: "",
unit: "",
quantity: "",
diff --git a/src/views/salesManagement/salesLedger/index.vue b/src/views/salesManagement/salesLedger/index.vue
index 8475b25..4e1f8ee 100644
--- a/src/views/salesManagement/salesLedger/index.vue
+++ b/src/views/salesManagement/salesLedger/index.vue
@@ -376,8 +376,25 @@
<el-row :gutter="30">
<el-col :span="24">
<el-form-item label="鎵瑰彿锛�" prop="batchNo">
- <el-select v-model="productForm.batchNo" placeholder="璇烽�夋嫨" clearable filterable>
+ <el-select v-model="productForm.batchNo"
+ placeholder="璇烽�夋嫨"
+ clearable
+ filterable
+ @change="handleBatchNoChange">
<el-option v-for="item in batchNoOptions" :key="item.value" :label="item.label" :value="item.value" />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="30">
+ <el-col :span="24">
+ <el-form-item label="渚涘簲鍟嗭細" prop="customer">
+ <el-select v-model="productForm.customer"
+ placeholder="璇烽�夋嫨"
+ clearable
+ filterable
+ :disabled="!supplierOptions.length">
+ <el-option v-for="item in supplierOptions" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
</el-col>
@@ -697,11 +714,11 @@
delProduct,
delLedgerFile, getProductInventory, saleOutboundExport,
} from "@/api/salesManagement/salesLedger.js";
-import { modelList, productTreeList } from "@/api/basicData/product.js";
+import { getStockInventoryAll } from "@/api/inventoryManagement/stockInventory.js";
import useFormData from "@/hooks/useFormData.js";
import dayjs from "dayjs";
import { getCurrentDate } from "@/utils/index.js";
-import {getProductOrderBatchNoOptions} from "@/api/productionManagement/productionOrder.js";
+// 鐢� /stockInventory/getStockInventoryAll 椹卞姩鈥滄壒鍙�/渚涘簲鍟嗏�濊仈鍔�
import {safeTrainingExport} from "@/api/safeProduction/safetyTrainingAssessment.js";
const userStore = useUserStore();
@@ -714,6 +731,7 @@
const customerOption = ref([]);
const productOptions = ref([]);
const modelOptions = ref([]);
+const supplierOptions = ref([]);
const tableLoading = ref(false);
const page = reactive({
current: 1,
@@ -762,6 +780,7 @@
const productFormData = reactive({
productForm: {
productCategory: "",
+ customer: "",
specificationModel: "",
uidNo: "",
unit: "",
@@ -777,6 +796,7 @@
productCategory: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
productModelId: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
batchNo: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+ customer: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
specificationModel: [
{ required: true, message: "璇烽�夋嫨", trigger: "change" },
],
@@ -945,64 +965,202 @@
tableLoading.value = false;
});
};
-// 鑾峰彇浜у搧澶х被tree鏁版嵁
-const getProductOptions = () => {
+let stockInventoryAllTree = [];
+let batchNodeByBatchNo = new Map();
+
+const normalizeStockInventoryTree = (nodes = []) => {
+ const normalizeNodeValue = (node) => {
+ // 鍚庣鏈夋椂浼氬嚭鐜� id=null 鐨勫眰绾э紝杩欓噷缁欎竴涓彲鐢ㄧ殑 key
+ if (node?.id !== null && node?.id !== undefined) return String(node.id);
+ if (node?.nodeType === "batch") return String(node.batchNo ?? node.label ?? "");
+ if (node?.nodeType === "customer") return String(node.customer ?? node.label ?? "");
+ if (node?.nodeType === "model") return String(node.model ?? node.label ?? "");
+ return String(node.productName ?? node.label ?? "");
+ };
+
+ const normalized = (list) =>
+ (list || []).map((n) => {
+ const value = normalizeNodeValue(n);
+ const label = n.label ?? n.productName ?? n.model ?? n.batchNo ?? n.customer ?? "";
+ return {
+ ...n,
+ value,
+ label,
+ children: normalized(n.children),
+ };
+ });
+
+ return normalized(nodes);
+};
+
+// 浠呭睍绀烘渶澶� 3 涓眰绾э細绗� 1 灞�(product) -> 绗� 2 灞�(model) -> 绗� 3 灞�(batch)锛屾洿娣辩殑鑺傜偣涓嶅睍绀�
+const filterStockInventoryFirst3Levels = (nodes = []) => {
+ const MAX_LEVEL = 3;
+
+ const cloneAndFilterByLevel = (list = [], level = 1) => {
+ return (list || [])
+ .map((n) => {
+ // 鍚庣画灞傜骇閲屽鏋滆繕鏈� customer锛岀洿鎺ュ墧闄�
+ if (n.nodeType === "customer") return null;
+
+ // 鍒拌揪灞曠ず娣卞害鍚庯紝涓嶅啀鍚戜笅鎸傚瓙鑺傜偣
+ if (level >= MAX_LEVEL) {
+ return { ...n, children: [] };
+ }
+
+ // 鐗逛緥锛歜atch 鑺傜偣鏈韩涔熶笉鍐嶅睍绀� children锛堜繚鎸佷笌鎺ュ彛鑺傜偣璇箟涓�鑷达級
+ if (n.nodeType === "batch") {
+ return { ...n, children: [] };
+ }
+
+ return { ...n, children: cloneAndFilterByLevel(n.children, level + 1) };
+ })
+ .filter(Boolean);
+ };
+
+ return cloneAndFilterByLevel(nodes, 1);
+};
+
+const findNodeObjByValue = (nodes = [], value) => {
+ for (let i = 0; i < (nodes || []).length; i++) {
+ const node = nodes[i];
+ if (String(node?.value) === String(value)) return node;
+ const children = node?.children || [];
+ if (children.length) {
+ const found = findNodeObjByValue(children, value);
+ if (found) return found;
+ }
+ }
+ return null;
+};
+
+// 鑾峰彇搴撳瓨鏍戯紙鐢ㄤ簬浜у搧澶х被/瑙勬牸鍨嬪彿鑱斿姩锛�
+const getProductOptions = async () => {
// 杩斿洖 Promise锛屼究浜庡湪缂栬緫浜у搧鏃剁瓑寰呭姞杞藉畬鎴�
- return productTreeList().then((res) => {
- productOptions.value = convertIdToValue(res);
- return productOptions.value;
- });
+ const res = await getStockInventoryAll();
+ const data = res?.data || [];
+ stockInventoryAllTree = normalizeStockInventoryTree(data);
+ productOptions.value = filterStockInventoryFirst3Levels(stockInventoryAllTree);
+ return productOptions.value;
};
const formattedNumber = (row, column, cellValue) => {
return parseFloat(cellValue).toFixed(2);
};
-// 鑾峰彇tree瀛愭暟鎹�
+// 鑾峰彇tree瀛愭暟鎹紙鍏堥�変骇鍝侊紝鍐嶉�夎鏍煎瀷鍙凤級
const getModels = (value) => {
- productForm.value.productCategory = findNodeById(productOptions.value, value);
- modelList({ id: value }).then((res) => {
- modelOptions.value = res;
- });
+ const node = findNodeObjByValue(stockInventoryAllTree, value);
+ if (!node) return;
+ if (node.nodeType !== "product") return;
+
+ // 閫夋嫨浜у搧鍚庯紝閲嶇疆涓嬫父瀛楁
+ productForm.value.productCategory = node.label;
+ modelOptions.value = (node.children || [])
+ .filter((c) => c.nodeType === "model")
+ .map((m) => ({
+ id: m.value,
+ model: m.model ?? m.label ?? "",
+ unit: m.unit ?? "",
+ uidNo: m.uidNo ?? m.identifierCode ?? "",
+ }));
+
+ productForm.value.productModelId = null;
+ productForm.value.specificationModel = "";
+ productForm.value.uidNo = "";
+ productForm.value.unit = "";
+ productForm.value.batchNo = "";
+ productForm.value.customer = "";
+ productForm.value.taxInclusiveUnitPrice = "";
+ productForm.value.taxInclusiveTotalPrice = "";
+ productForm.value.taxExclusiveTotalPrice = "";
+
+ modelOptions.value = modelOptions.value || [];
+ batchNoOptions.value = [];
+ supplierOptions.value = [];
+ batchNodeByBatchNo = new Map();
};
+
+// 瑙勬牸鍨嬪彿閫夋嫨鍚庯細鍥炴樉 UID锛屽苟鐢熸垚鈥滄壒鍙蜂笅鎷夆��
const getProductModel = (value) => {
- const index = modelOptions.value.findIndex((item) => item.id === value);
- if (index !== -1) {
- productForm.value.specificationModel = modelOptions.value[index].model;
- productForm.value.unit = modelOptions.value[index].unit;
- productForm.value.uidNo = modelOptions.value[index].uidNo || "";
+ const modelNode = findNodeObjByValue(stockInventoryAllTree, value);
+ if (!modelNode || modelNode.nodeType !== "model") return;
+
+ const prevBatchNo = productForm.value.batchNo;
+ const prevCustomer = productForm.value.customer;
+
+ productForm.value.specificationModel = modelNode.model ?? modelNode.label ?? "";
+ // 鏈変簺鎺ュ彛/鏍戞暟鎹噷鍙兘涓嶅寘鍚� unit锛岃繖绉嶆儏鍐典笅涓嶈瑕嗙洊缂栬緫鏃跺凡鍥炴樉鐨勫��
+ const nextUnit = modelNode.unit ?? "";
+ if (nextUnit !== null && nextUnit !== undefined && String(nextUnit).trim() !== "") {
+ productForm.value.unit = nextUnit;
+ }
+ // 鏈変簺鎺ュ彛/鏍戞暟鎹噷鍙兘涓嶅寘鍚� uidNo锛岃繖绉嶆儏鍐典笅涓嶈瑕嗙洊缂栬緫鏃跺凡鍥炴樉鐨勫��
+ const nextUidNo = modelNode.uidNo ?? modelNode.identifierCode ?? "";
+ if (nextUidNo !== null && nextUidNo !== undefined && String(nextUidNo).trim() !== "") {
+ productForm.value.uidNo = nextUidNo;
+ }
+
+ const batchNodes = (modelNode.children || []).filter((b) => b.nodeType === "batch");
+ batchNodeByBatchNo = new Map(
+ batchNodes.map((b) => {
+ const key = String(b.batchNo ?? b.value ?? b.label ?? "").trim();
+ return [key, b];
+ })
+ );
+ batchNoOptions.value = batchNodes.map((b) => ({
+ label: String(b.batchNo ?? b.label ?? "").trim(),
+ value: String(b.batchNo ?? b.value ?? b.label ?? "").trim(),
+ }));
+
+ // 鎵瑰彿涓嶅啀灞炰簬鏂拌鏍兼椂锛屾竻绌�
+ const batchValues = new Set(batchNoOptions.value.map((x) => x.value));
+ if (!prevBatchNo || !batchValues.has(prevBatchNo)) {
+ productForm.value.batchNo = "";
+ }
+
+ // 闇�瑕佷緵搴斿晢锛氭壒鍙峰洖鏄惧悗鍐嶇敓鎴�
+ productForm.value.customer = "";
+ supplierOptions.value = [];
+ if (productForm.value.batchNo) {
+ handleBatchNoChange(productForm.value.batchNo, prevCustomer);
+ }
+};
+
+const handleBatchNoChange = (batchNo, prevCustomer) => {
+ const safeBatchNo = String(batchNo ?? "").trim();
+ if (!safeBatchNo || !batchNodeByBatchNo.size) {
+ productForm.value.customer = "";
+ supplierOptions.value = [];
+ return;
+ }
+
+ const batchNode = batchNodeByBatchNo.get(String(safeBatchNo));
+ if (!batchNode) {
+ productForm.value.customer = "";
+ supplierOptions.value = [];
+ return;
+ }
+
+ // UID鐮佸彲鑳芥潵婧愪簬 batch 鑺傜偣锛堜笉鍚屾帴鍙e瓧娈靛悕涓嶄竴鑷存椂灏介噺鍏滃簳锛�
+ const nextUidNo = batchNode.uidNo ?? batchNode.identifierCode ?? batchNode.uid ?? "";
+ if (nextUidNo !== null && nextUidNo !== undefined && String(nextUidNo).trim() !== "") {
+ productForm.value.uidNo = nextUidNo;
+ }
+
+ const customers = (batchNode.children || [])
+ .filter((c) => c.nodeType === "customer")
+ .map((c) => c.customer ?? c.label ?? "")
+ .filter(Boolean);
+
+ const uniq = Array.from(new Set(customers));
+ supplierOptions.value = uniq.map((s) => ({ label: s, value: s }));
+
+ // 缂栬緫鍦烘櫙灏介噺鍥炴樉锛涙柊澧炲満鏅笉鍥炴樉
+ if (prevCustomer && uniq.includes(prevCustomer)) {
+ productForm.value.customer = prevCustomer;
} else {
- productForm.value.specificationModel = null;
- productForm.value.unit = null;
- productForm.value.uidNo = null;
+ productForm.value.customer = "";
}
};
-const findNodeById = (nodes, productId) => {
- for (let i = 0; i < nodes.length; i++) {
- if (nodes[i].value === productId) {
- return nodes[i].label; // 鎵惧埌鑺傜偣锛岃繑鍥炶鑺傜偣
- }
- if (nodes[i].children && nodes[i].children.length > 0) {
- const foundNode = findNodeById(nodes[i].children, productId);
- if (foundNode) {
- return foundNode; // 鍦ㄥ瓙鑺傜偣涓壘鍒帮紝杩斿洖璇ヨ妭鐐�
- }
- }
- }
- return null; // 娌℃湁鎵惧埌鑺傜偣锛岃繑鍥瀗ull
-};
-function convertIdToValue(data) {
- return data.map((item) => {
- const { id, children, ...rest } = item;
- const newItem = {
- ...rest,
- value: id, // 灏� id 鏀逛负 value
- };
- if (children && children.length > 0) {
- newItem.children = convertIdToValue(children);
- }
-
- return newItem;
- });
-}
// 鏍规嵁鍚嶇О鍙嶆煡浜у搧澶х被 id锛屼究浜庝粎瀛樺悕绉版椂鐨勫弽鏄�
function findNodeIdByLabel(nodes, label) {
if (!label) return null;
@@ -1276,10 +1434,6 @@
};
const batchNoOptions = ref([]);
-const fetchBatchNoOptions = async () => {
- const res = await getProductOrderBatchNoOptions();
- batchNoOptions.value = res.data;
-};
// 鍏抽棴寮规
const closeDia = () => {
proxy.resetForm("formRef");
@@ -1303,25 +1457,44 @@
productIndex.value = index;
// 缂栬緫鏃舵牴鎹骇鍝佸ぇ绫诲悕绉板弽鏌� tree 鑺傜偣 id锛屽苟鍔犺浇瑙勬牸鍨嬪彿鍒楄〃
try {
- const options = productOptions.value && productOptions.value.length > 0
- ? productOptions.value
- : await getProductOptions();
- const categoryId = findNodeIdByLabel(options, productForm.value.productCategory);
- if (categoryId) {
- const models = await modelList({ id: categoryId });
- modelOptions.value = models || [];
- // 鏍规嵁褰撳墠瑙勬牸鍨嬪彿鍚嶇О鍙嶆煡骞惰缃� productModelId锛屼究浜庝笅鎷夋鏄剧ず宸查�夊��
- const currentModel = (modelOptions.value || []).find(
- (m) => m.model === productForm.value.specificationModel
- );
+ if (!productOptions.value || productOptions.value.length === 0) {
+ await getProductOptions();
+ }
+
+ // 鍥炴樉锛氭牴鎹�滀骇鍝佸ぇ绫烩�濆弽鏌ヤ骇鍝佽妭鐐�
+ const categoryKey = findNodeIdByLabel(productOptions.value, productForm.value.productCategory);
+ if (categoryKey) {
+ const categoryNode = findNodeObjByValue(stockInventoryAllTree, categoryKey);
+ const models = (categoryNode?.children || [])
+ .filter((n) => n.nodeType === "model")
+ .map((m) => ({
+ id: m.value,
+ model: m.model ?? m.label ?? "",
+ unit: m.unit ?? "",
+ uidNo: m.uidNo ?? m.identifierCode ?? "",
+ }));
+ modelOptions.value = models;
+
+ // 鏍规嵁褰撳墠瑙勬牸鍨嬪彿鍥炴樉
+ const targetSpec = String(productForm.value.specificationModel ?? "").trim();
+ const currentModel =
+ (models || []).find((m) => String(m.model ?? "").trim() === targetSpec) ||
+ (models || []).find((m) => String(m.model ?? "").trim().includes(targetSpec)) ||
+ (models || []).find((m) => targetSpec.includes(String(m.model ?? "").trim()));
if (currentModel) {
+ productForm.value.customer = productForm.value.customer || row.customer || row.supplierName || "";
productForm.value.productModelId = currentModel.id;
+ getProductModel(currentModel.id);
}
}
} catch (e) {
// 鍔犺浇澶辫触鏃朵繚鎸佸彲缂栬緫锛屼笉涓柇寮圭獥
console.error("鍔犺浇浜у搧瑙勬牸鍨嬪彿澶辫触", e);
}
+ // 鏈�缁堝厹搴曪細濡傛灉涓�旇閲嶇疆娓呯┖锛岃嚦灏戝洖鏄捐鏁版嵁閲岀殑 UID
+ productForm.value.uidNo = row.uidNo ?? productForm.value.uidNo ?? "";
+ // 鏈�缁堝厹搴曪細鍚屾牱淇濊瘉鍗曚綅涓嶄細鍥犳爲鏁版嵁缂哄け鑰岃瑕嗙洊涓虹┖
+ productForm.value.unit = row.unit ?? productForm.value.unit ?? "";
} else {
getProductOptions()
}
@@ -2251,7 +2424,6 @@
onMounted(() => {
getList();
- fetchBatchNoOptions();
userListNoPage().then(res => {
userList.value = res.data;
})
--
Gitblit v1.9.3