From 3ffdb76baf74089912a23c1f8f8112d5c8c1063b Mon Sep 17 00:00:00 2001
From: spring <2396852758@qq.com>
Date: 星期五, 20 三月 2026 14:56:24 +0800
Subject: [PATCH] fix: 生产详情接口联调90%
---
src/views/procurementManagement/procurementLedger/index.vue | 16 +++
src/api/productionManagement/workOrder.js | 8 +
src/api/productionManagement/productionProductMain.js | 8 +
src/views/productionManagement/productionOrder/Detail/index.vue | 217 +++++++++++++++++++++++++++---------------
4 files changed, 171 insertions(+), 78 deletions(-)
diff --git a/src/api/productionManagement/productionProductMain.js b/src/api/productionManagement/productionProductMain.js
index 0493f8b..aa2e4c3 100644
--- a/src/api/productionManagement/productionProductMain.js
+++ b/src/api/productionManagement/productionProductMain.js
@@ -9,3 +9,11 @@
params: query,
});
}
+
+// 鏍规嵁宸ュ簭宸ュ崟 id 鏌ヨ鎶ュ伐淇℃伅
+export function getByProductWorkOrderId(productWorkOrderId) {
+ return request({
+ url: `/productionProductMain/getByProductWorkOrderId/${productWorkOrderId}`,
+ method: "get",
+ });
+}
diff --git a/src/api/productionManagement/workOrder.js b/src/api/productionManagement/workOrder.js
index 7e8bd86..3a0e9a2 100644
--- a/src/api/productionManagement/workOrder.js
+++ b/src/api/productionManagement/workOrder.js
@@ -8,6 +8,14 @@
});
}
+// 鏍规嵁鐢熶骇璁㈠崟 id 鏌ヨ宸ュ簭宸ュ崟鍒楄〃
+export function getByProductOrderId(productOrderId) {
+ return request({
+ url: `/productWorkOrder/getByProductOrderId/${productOrderId}`,
+ method: "get",
+ });
+}
+
export function updateProductWorkOrder(data) {
return request({
url: "/productWorkOrder/updateProductWorkOrder",
diff --git a/src/views/procurementManagement/procurementLedger/index.vue b/src/views/procurementManagement/procurementLedger/index.vue
index b333e8d..0ebff95 100644
--- a/src/views/procurementManagement/procurementLedger/index.vue
+++ b/src/views/procurementManagement/procurementLedger/index.vue
@@ -1474,6 +1474,22 @@
if (type === "edit") {
// 澶嶅埗琛屾暟鎹�
productForm.value = { ...row };
+
+ // el-radio-group 鐨� value 鏄竷灏� true/false
+ // 鍚庣/琛ㄦ牸鏁版嵁鍙兘鏄� 0/1 鎴栧瓧绗︿覆锛岄渶鍋氫竴娆″綊涓�鍖栵紝閬垮厤涓嶅洖鏄�/鎻愪氦榛樿鈥滃惁鈥�
+ const normalizeIsChecked = (val) => {
+ if (val === true) return true;
+ if (val === false) return false;
+ if (val === 1 || val === "1") return true;
+ if (val === 0 || val === "0") return false;
+ if (typeof val === "string") {
+ const s = val.trim().toLowerCase();
+ if (["鏄�", "yes", "true", "y"].includes(s)) return true;
+ if (["鍚�", "no", "false", "n"].includes(s)) return false;
+ }
+ return !!val;
+ };
+ productForm.value.isChecked = normalizeIsChecked(row?.isChecked);
// 濡傛灉鏄粠妯℃澘鍔犺浇鐨勬暟鎹紝鍙兘娌℃湁 productId 鍜� productModelId
// 闇�瑕佹牴鎹� productCategory 鍜� specificationModel 鏉ユ煡鎵惧搴旂殑 ID
diff --git a/src/views/productionManagement/productionOrder/Detail/index.vue b/src/views/productionManagement/productionOrder/Detail/index.vue
index ae30acd..7b7c2e2 100644
--- a/src/views/productionManagement/productionOrder/Detail/index.vue
+++ b/src/views/productionManagement/productionOrder/Detail/index.vue
@@ -112,7 +112,7 @@
</div>
<div v-else class="right-content">
- <el-table :data="mockReports" border height="420">
+ <el-table :data="reports" border height="420" v-loading="reportLoading">
<el-table-column label="搴忓彿" type="index" width="60" align="center" />
<el-table-column label="鎶ュ伐鍗曞彿" prop="reportNo" min-width="140" show-overflow-tooltip />
<el-table-column label="鎶ュ伐浜哄憳" prop="reportUser" min-width="120" show-overflow-tooltip />
@@ -120,7 +120,7 @@
<el-table-column label="浜у嚭鏁伴噺" prop="outputQty" min-width="110" />
<el-table-column label="鍚堟牸鏁伴噺" prop="qualifiedQty" min-width="110" />
<el-table-column label="涓嶈壇鏁伴噺" prop="badQty" min-width="110" />
- <el-table-column label="澶囨敞" prop="remark" min-width="160" show-overflow-tooltip />
+ <el-table-column label="涓嶅悎鏍煎鐞�" prop="remark" min-width="160" show-overflow-tooltip />
<el-table-column label="鎿嶄綔" width="150" fixed="right">
<template #default="{ row }">
<el-button type="primary" link @click="viewReportRecord(row)">
@@ -153,8 +153,10 @@
</template>
<script setup>
-import { computed, ref, watch } from "vue";
+import { computed, onMounted, ref, watch } from "vue";
import { useRoute } from "vue-router";
+import { getByProductOrderId } from "@/api/productionManagement/workOrder.js";
+import { getByProductWorkOrderId } from "@/api/productionManagement/productionProductMain.js";
const route = useRoute();
@@ -166,45 +168,72 @@
specificationModel: route.query.specificationModel,
}));
-// 妯℃嫙宸ュ簭鏁版嵁锛堝悗缁敤鎺ュ彛鏇挎崲锛�
-const processes = computed(() => [
- {
- processCode: "GX-001",
- processName: "澶囨枡",
- inputQty: 1000,
- outputQty: 980,
- qualifiedQty: 970,
- badQty: 10,
- status: "success",
- },
- {
- processCode: "GX-002",
- processName: "鎴愬瀷",
- inputQty: 980,
- outputQty: 960,
- qualifiedQty: 948,
- badQty: 12,
- status: "process",
- },
- {
- processCode: "GX-003",
- processName: "鐑樺共",
- inputQty: 960,
- outputQty: 950,
- qualifiedQty: 948,
- badQty: 2,
- status: "wait",
- },
- {
- processCode: "GX-004",
- processName: "鍖呰鍏ュ簱",
- inputQty: 950,
- outputQty: 920,
- qualifiedQty: 918,
- badQty: 2,
- status: "wait",
- },
-]);
+// 宸ュ簭鏁版嵁锛堟帴鍙f浛鎹級
+const processes = ref([]);
+
+const normalizeStatus = (statusText, completionStatus, inputQty, outputQty) => {
+ const s = statusText === null || statusText === undefined ? "" : String(statusText).trim();
+ const lower = s.toLowerCase();
+
+ // 甯歌涓枃鐘舵�佸厹搴曪細杩涜涓�/宸插畬鎴�/绛夊緟
+ if (s.includes("杩涜") || lower.includes("process") || lower.includes("doing") || lower.includes("running")) return "process";
+ if (s.includes("瀹屾垚") || s.includes("宸插畬") || lower.includes("success") || lower.includes("done") || lower.includes("completed")) return "success";
+ if (s.includes("寰�") || s.includes("鏈紑濮�") || lower.includes("wait") || lower.includes("pending") || lower.includes("not_start")) return "wait";
+
+ // 鐢� completionStatus 鍋氬厹搴曪紙涓�鑸负 0~100锛�
+ const cs = Number(completionStatus);
+ if (Number.isFinite(cs)) {
+ if (cs >= 100) return "success";
+ if (cs > 0) return "process";
+ return "wait";
+ }
+
+ // 鏈�鍚庡啀鐢ㄦ暟閲忓厹搴�
+ if (Number.isFinite(inputQty) && inputQty > 0 && Number.isFinite(outputQty) && outputQty >= inputQty) return "success";
+ if (Number.isFinite(outputQty) && outputQty > 0) return "process";
+ return "wait";
+};
+
+const normalizeProcess = (item) => {
+ // 瀛楁浠ユ帴鍙g害瀹氫负鍑嗭紙浣犵粰鐨勬埅鍥惧瓧娈垫槧灏勶級
+ // 宸ュ簭锛歝ompletionStatus/statusText/processNo/scrapRate/planQuantity/completeQuantity/completeQty/scrapQty
+ const inputQty = Number(item?.planQuantity ?? item?.inputQty ?? 0);
+ const outputQty = Number(item?.completeQuantity ?? item?.outputQty ?? 0);
+ const qualifiedQty = Number(item?.completeQty ?? item?.qualifiedQty ?? item?.goodQty ?? 0);
+ const badQty = Number(item?.scrapQty ?? item?.badQty ?? item?.defectQty ?? 0);
+ const completionStatus = Number(item?.completionStatus ?? 0);
+ const scrapRate = Number(item?.scrapRate ?? NaN);
+
+ const status = normalizeStatus(item?.statusText ?? item?.status ?? item?.workStatus ?? item?.processStatus ?? item?.state, completionStatus, inputQty, outputQty);
+
+ return {
+ processCode: item?.processNo ?? item?.processCode ?? item?.processWorkOrderCode ?? "",
+ processName: item?.processName ?? item?.processWorkOrderName ?? item?.processNo ?? "",
+ productWorkOrderId: item?.productWorkOrderId ?? item?.workOrderId ?? item?.id ?? null,
+ inputQty: Number.isFinite(inputQty) ? inputQty : 0,
+ outputQty: Number.isFinite(outputQty) ? outputQty : 0,
+ qualifiedQty: Math.max(0, Number.isFinite(qualifiedQty) ? qualifiedQty : 0),
+ badQty: Math.max(0, Number.isFinite(badQty) ? badQty : 0),
+ completionStatus: Number.isFinite(completionStatus) ? completionStatus : 0,
+ scrapRate: Number.isFinite(scrapRate) ? scrapRate : null,
+ status,
+ };
+};
+
+onMounted(async () => {
+ const productOrderId = header.value?.orderId;
+ if (!productOrderId) return;
+
+ try {
+ const res = await getByProductOrderId(productOrderId);
+ const payload = res?.data;
+ const list = Array.isArray(payload) ? payload : payload?.records || payload?.data || [];
+ processes.value = list.map((it) => normalizeProcess(it));
+ } catch (e) {
+ console.error("鑾峰彇宸ュ簭宸ュ崟鍒楄〃澶辫触锛�", e);
+ processes.value = [];
+ }
+});
// 榛樿閫変腑绗竴閬撳簭锛堟帴鍙f暟鎹氨缁悗浠嶅彲浠� 0 寮�濮嬶級
const selectedIndex = ref(0);
@@ -233,42 +262,60 @@
return list[idx] || null;
});
-// 妯℃嫙鎶ュ伐淇℃伅锛堝悗缁敤鎺ュ彛鏇挎崲锛�
-const mockReports = computed(() => {
- const p = selectedProcess.value;
- if (!p) return [];
- const code = p.processCode || "GX";
- const reports = [
- {
- reportNo: `${code}-BG-0001`,
- reportUser: "寮犱笁",
- reportTime: "2026-03-14 09:20",
- outputQty: Math.floor((p.outputQty ?? 0) * 0.4),
- badQty: Math.floor((p.badQty ?? 0) * 0.4),
- remark: "姝e父鎶ュ伐",
- },
- {
- reportNo: `${code}-BG-0002`,
- reportUser: "鏉庡洓",
- reportTime: "2026-03-14 13:45",
- outputQty: Math.floor((p.outputQty ?? 0) * 0.35),
- badQty: Math.floor((p.badQty ?? 0) * 0.35),
- remark: "璁惧璋冭瘯鍚庢仮澶�",
- },
- {
- reportNo: `${code}-BG-0003`,
- reportUser: "鐜嬩簲",
- reportTime: "2026-03-14 17:10",
- outputQty: Math.max(0, (p.outputQty ?? 0) - Math.floor((p.outputQty ?? 0) * 0.75)),
- badQty: Math.max(0, (p.badQty ?? 0) - Math.floor((p.badQty ?? 0) * 0.75)),
- remark: "鏀跺熬",
- },
- ];
- return reports.map((item) => ({
- ...item,
- qualifiedQty: Math.max(0, Number(item.outputQty ?? 0) - Number(item.badQty ?? 0)),
- }));
-});
+const reports = ref([]);
+const reportLoading = ref(false);
+
+const normalizeReport = (item) => {
+ // 鎶ュ伐璁板綍锛歱roductNo/userName/createTime/quantity/qualifiedQty/scrapQty
+ const outputQty = Number(item?.quantity ?? item?.outputQty ?? 0);
+ const qualifiedQty = Number(item?.qualifiedQty ?? item?.completeQty ?? item?.goodQty ?? 0);
+ const badQty = Number(item?.scrapQty ?? item?.badQty ?? 0);
+
+ return {
+ reportNo: item?.productNo ?? item?.reportNo ?? item?.productionReportNo ?? item?.id ?? "",
+ reportUser: item?.userName ?? item?.reportUser ?? item?.createdByName ?? item?.reportUserName ?? "",
+ reportTime: item?.createTime ?? item?.reportTime ?? item?.createdAt ?? item?.reportDate ?? "",
+ outputQty: Number.isFinite(outputQty) ? outputQty : 0,
+ qualifiedQty: Math.max(0, Number.isFinite(qualifiedQty) ? qualifiedQty : 0),
+ badQty: Number.isFinite(badQty) ? Math.max(0, badQty) : 0,
+ remark: item?.remark ?? item?.remarkText ?? item?.description ?? "",
+ };
+};
+
+const fetchReportsForProcess = async (p) => {
+ if (!p) {
+ reports.value = [];
+ return;
+ }
+ const productWorkOrderId = p.productWorkOrderId ?? p.id ?? p.workOrderId ?? null;
+ if (!productWorkOrderId) {
+ reports.value = [];
+ return;
+ }
+
+ reportLoading.value = true;
+ try {
+ const res = await getByProductWorkOrderId(productWorkOrderId);
+ const payload = res?.data;
+ const list = Array.isArray(payload)
+ ? payload
+ : payload?.records || payload?.data || payload?.list || [];
+ reports.value = list.map((it) => normalizeReport(it));
+ } catch (e) {
+ console.error("鑾峰彇鎶ュ伐淇℃伅澶辫触锛�", e);
+ reports.value = [];
+ } finally {
+ reportLoading.value = false;
+ }
+};
+
+watch(
+ () => selectedProcess.value,
+ (val) => {
+ fetchReportsForProcess(val);
+ },
+ { immediate: true }
+);
const viewReportRecord = (row) => {
if (!row?.reportNo) return;
@@ -297,6 +344,11 @@
// 宸ュ簭杩涘害锛氱敤浜у嚭/鎶曞叆浼扮畻锛圲I 鍏堣窇閫氾紝鍚庣画鎸夌湡瀹炶鍒欐浛鎹級
const processPercentage = (p) => {
if (!p) return 0;
+ // 浼樺厛浣跨敤鎺ュ彛瀛楁 completionStatus锛堜綘缁欑殑鎴浘鈥滃伐搴忚繘搴︹�濓級
+ const cs = Number(p?.completionStatus ?? NaN);
+ if (Number.isFinite(cs)) return clampPercentage(cs);
+
+ // 鍏滃簳锛氱敤浜у嚭/鎶曞叆浼扮畻
const input = Number(p.inputQty ?? 0);
const output = Number(p.outputQty ?? 0);
if (!Number.isFinite(input) || input <= 0) return 0;
@@ -314,6 +366,15 @@
// 涓嶈壇鐜囷細涓嶈壇鏁伴噺 / 浜у嚭鏁伴噺锛堝厛鎸夋鍙e緞锛屽悗缁鎺ユ帴鍙e彲璋冩暣锛�
const defectRateText = (p) => {
+ // 浼樺厛浣跨敤鎺ュ彛瀛楁 scrapRate锛堜綘缁欑殑鎴浘鈥滀笉鑹巼鈥濓級
+ const scrapRate = Number(p?.scrapRate ?? NaN);
+ if (Number.isFinite(scrapRate)) {
+ // 鏈変簺鎺ュ彛 scrapRate 鍙兘鏄� 0~1 鎴� 0~100锛岃繖閲屽仛涓�涓畝鍗曞垽鏂�
+ const percent = scrapRate <= 1 ? scrapRate * 100 : scrapRate;
+ return `${percent.toFixed(2)}%`;
+ }
+
+ // 鍏滃簳锛氫笉鑹暟閲� / 浜у嚭鏁伴噺
const bad = Number(p?.badQty ?? 0);
const output = Number(p?.outputQty ?? 0);
if (!Number.isFinite(bad) || bad <= 0) return "0%";
--
Gitblit v1.9.3