From be02736e1daf886882fa470e0199f93b8413ee8d Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期二, 03 二月 2026 11:11:33 +0800
Subject: [PATCH] Merge branch 'dev_New' into dev_天津军泰伟业
---
src/views/productionManagement/productionProcess/index.vue | 8
src/views/reportAnalysis/qualityAnalysis/components/center-bottom.vue | 182 ++++++--
src/views/collaborativeApproval/rulesRegulationsManagement/index.vue | 111 ++--
src/views/reportAnalysis/qualityAnalysis/components/left-top.vue | 91 ++-
src/views/qualityManagement/finalInspection/components/formDia.vue | 123 +++--
src/views/reportAnalysis/qualityAnalysis/components/center-center.vue | 101 ++--
src/views/productionManagement/processRoute/processRouteItem/index.vue | 20
src/views/salesManagement/salesLedger/index.vue | 3
src/views/productionManagement/productionProcess/Edit.vue | 6
src/views/collaborativeApproval/sealManagement/index.vue | 100 ++--
src/views/reportAnalysis/qualityAnalysis/index.vue | 3
src/views/reportAnalysis/qualityAnalysis/components/right-top.vue | 121 +++-
src/views/reportAnalysis/qualityAnalysis/components/right-bottom.vue | 227 +++------
src/api/viewIndex.js | 67 +++
src/views/productionManagement/productionOrder/index.vue | 3
src/views/reportAnalysis/qualityAnalysis/components/center-top.vue | 46 +
src/views/productionManagement/productionProcess/New.vue | 4
17 files changed, 733 insertions(+), 483 deletions(-)
diff --git a/src/api/viewIndex.js b/src/api/viewIndex.js
index 1479e0c..1ec8c49 100644
--- a/src/api/viewIndex.js
+++ b/src/api/viewIndex.js
@@ -1,6 +1,73 @@
// 棣栭〉鎺ュ彛
import request from "@/utils/request";
+// 鍘熸潗鏂欐娴�
+export const rawMaterialDetection = (query) => {
+ return request({
+ url: "/home/rawMaterialDetection",
+ method: "get",
+ params: query,
+ });
+};
+
+// 杩囩▼妫�娴�
+export const processDetection = (query) => {
+ return request({
+ url: "/home/processDetection",
+ method: "get",
+ params: query,
+ });
+};
+
+// 鎴愬搧鍑哄巶妫�娴�
+export const factoryDetection = (query) => {
+ return request({
+ url: "/home/factoryDetection",
+ method: "get",
+ params: query,
+ });
+};
+
+// 妫�楠屾暟閲�
+export const qualityInspectionCount = () => {
+ return request({
+ url: "/home/qualityInspectionCount",
+ method: "get",
+ });
+};
+
+// 涓嶅悎鏍奸璀�
+export const nonComplianceWarning = () => {
+ return request({
+ url: "/home/nonComplianceWarning",
+ method: "get",
+ });
+};
+
+// 瀹屾垚妫�楠屾暟
+export const completedInspectionCount = () => {
+ return request({
+ url: "/home/completedInspectionCount",
+ method: "get",
+ });
+};
+
+// 涓嶅悎鏍间骇鍝佹帓鍚�
+export const unqualifiedProductRanking = () => {
+ return request({
+ url: "/home/unqualifiedProductRanking",
+ method: "get",
+ });
+};
+
+// 涓嶅悎鏍兼鍝佸鐞嗗垎鏋�
+export const unqualifiedProductProcessingAnalysis = () => {
+ return request({
+ url: "/home/unqualifiedProductProcessingAnalysis",
+ method: "get",
+ });
+};
+
// 閿�鍞�-閲囪喘-搴撳瓨鏁版嵁
export const getBusiness = () => {
return request({
diff --git a/src/views/collaborativeApproval/rulesRegulationsManagement/index.vue b/src/views/collaborativeApproval/rulesRegulationsManagement/index.vue
index 6c3004d..ba8e46d 100644
--- a/src/views/collaborativeApproval/rulesRegulationsManagement/index.vue
+++ b/src/views/collaborativeApproval/rulesRegulationsManagement/index.vue
@@ -42,68 +42,15 @@
</el-button>
</el-col>
</el-row>
- <el-table :data="regulations"
- border
- v-loading="tableLoading"
- style="width: 100%">
- <el-table-column prop="regulationNum"
- label="鍒跺害缂栧彿"
- width="120" />
- <el-table-column prop="title"
- label="鍒跺害鏍囬"
- min-width="150" />
- <el-table-column prop="category"
- label="鍒嗙被"
- width="120">
- <template #default="scope">
- <el-tag>{{ getCategoryText(scope.row.category) }}</el-tag>
- </template>
- </el-table-column>
- <el-table-column prop="version"
- label="鐗堟湰"
- width="120" />
- <el-table-column prop="createUserName"
- label="鍙戝竷浜�"
- width="120" />
- <el-table-column prop="createTime"
- label="鍙戝竷鏃堕棿"
- width="180" />
- <el-table-column prop="status"
- label="鐘舵��"
- width="100">
- <template #default="scope">
- <el-tag :type="scope.row.status === 'active' ? 'success' : 'info'">
- {{ scope.row.status === 'active' ? '鐢熸晥涓�' : '宸插簾姝�' }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column prop="readCount"
- label="宸茶浜烘暟"
- width="100" />
- <el-table-column label="鎿嶄綔"
- width="320"
- fixed="right">
- <template #default="scope">
- <el-button link
- @click="viewRegulation(scope.row)">鏌ョ湅</el-button>
- <el-button link
- type="primary"
- @click="handleEdit(scope.row)">缂栬緫</el-button>
- <el-button link
- type="danger"
- @click="repealEdit(scope.row)">搴熷純</el-button>
- <el-button link
- type="success"
- @click="viewVersionHistory(scope.row)">鐗堟湰鍘嗗彶</el-button>
- <!-- <el-button link type="warning" @click="viewReadStatus(scope.row)">闃呰鐘舵��</el-button> -->
- <el-button link
- type="primary"
- @click="openFileDialog(scope.row)">闄勪欢</el-button>
- </template>
- </el-table-column>
- </el-table>
- <pagination v-show="page.total > 0" :total="page.total" layout="total, sizes, prev, pager, next, jumper"
- :page="page.current" :limit="page.size" @pagination="paginationChange" />
+ <PIMTable
+ rowKey="id"
+ :column="regulationTableColumn"
+ :tableData="regulations"
+ :tableLoading="tableLoading"
+ :page="page"
+ :isShowPagination="true"
+ @pagination="paginationChange"
+ />
</div>
</el-card>
<!-- 鐢ㄥ嵃鐢宠瀵硅瘽妗嗭紙宸茬Щ闄わ級 -->
@@ -295,6 +242,7 @@
delRuleFile,
addRuleFile,
} from "@/api/collaborativeApproval/rulesRegulationsManagementFile.js";
+ import PIMTable from "@/components/PIMTable/PIMTable.vue";
// 鍝嶅簲寮忔暟鎹�
const operationType = ref("add");
@@ -363,6 +311,45 @@
const regulations = ref([]);
+ // 琛ㄦ牸鍒楅厤缃�
+ const regulationTableColumn = ref([
+ { label: "鍒跺害缂栧彿", prop: "regulationNum"},
+ { label: "鍒跺害鏍囬", prop: "title" },
+ {
+ label: "鍒嗙被",
+ prop: "category",
+ dataType: "tag",
+ formatData: (v) => getCategoryText(v),
+ formatType: () => "info",
+ },
+ { label: "鐗堟湰", prop: "version", width: 120 },
+ { label: "鍙戝竷浜�", prop: "createUserName", width: 120 },
+ { label: "鍙戝竷鏃堕棿", prop: "createTime", width: 180 },
+ {
+ label: "鐘舵��",
+ prop: "status",
+ width: 100,
+ dataType: "tag",
+ formatData: (v) => (v === "active" ? "鐢熸晥涓�" : "宸插簾姝�"),
+ formatType: (v) => (v === "active" ? "success" : "info"),
+ },
+ { label: "宸茶浜烘暟", prop: "readCount", width: 100 },
+ {
+ dataType: "action",
+ label: "鎿嶄綔",
+ width: 320,
+ fixed: "right",
+ align: "center",
+ operation: [
+ { name: "鏌ョ湅", clickFun: (row) => viewRegulation(row) },
+ { name: "缂栬緫", clickFun: (row) => handleEdit(row) },
+ { name: "搴熷純", clickFun: (row) => repealEdit(row) },
+ { name: "鐗堟湰鍘嗗彶", clickFun: (row) => viewVersionHistory(row) },
+ { name: "闄勪欢", clickFun: (row) => openFileDialog(row) },
+ ],
+ },
+ ]);
+
const versionHistory = ref([]);
const readStatusList = ref([]);
diff --git a/src/views/collaborativeApproval/sealManagement/index.vue b/src/views/collaborativeApproval/sealManagement/index.vue
index f3599f7..b4a1886 100644
--- a/src/views/collaborativeApproval/sealManagement/index.vue
+++ b/src/views/collaborativeApproval/sealManagement/index.vue
@@ -36,48 +36,15 @@
</el-col>
</el-row>
- <el-table :data="sealApplications" border v-loading="tableLoading" style="width: 100%">
- <el-table-column prop="applicationNum" label="鐢宠缂栧彿" width="120" />
- <el-table-column prop="title" label="鐢宠鏍囬" min-width="200" />
- <el-table-column prop="createUserName" label="鐢宠浜�" width="120" />
- <el-table-column prop="department" label="鎵�灞為儴闂�" width="150" />
- <el-table-column prop="sealType" label="鐢ㄥ嵃绫诲瀷" width="120">
- <template #default="scope">
- {{ getSealTypeText(scope.row.sealType) }}
- </template>
- </el-table-column>
- <el-table-column prop="createTime" label="鐢宠鏃堕棿" width="180" />
- <el-table-column prop="status" label="鐘舵��" width="100">
- <template #default="scope">
- <el-tag :type="getStatusType(scope.row.status)">
- {{ getStatusText(scope.row.status) }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column label="鎿嶄綔" width="200" fixed="right">
- <template #default="scope">
- <el-button link @click="viewSealDetail(scope.row)">鏌ョ湅</el-button>
- <el-button
- v-if="scope.row.status === 'pending'"
- link
- type="primary"
- @click="approveSeal(scope.row)"
- >
- 瀹℃壒
- </el-button>
- <el-button
- v-if="scope.row.status === 'pending'"
- link
- type="danger"
- @click="rejectSeal(scope.row)"
- >
- 鎷掔粷
- </el-button>
- </template>
- </el-table-column>
- </el-table>
- <pagination v-show="page.total > 0" :total="page.total" layout="total, sizes, prev, pager, next, jumper"
- :page="page.current" :limit="page.size" @pagination="paginationChange" />
+ <PIMTable
+ rowKey="id"
+ :column="sealTableColumn"
+ :tableData="sealApplications"
+ :tableLoading="tableLoading"
+ :page="page"
+ :isShowPagination="true"
+ @pagination="paginationChange"
+ />
</div>
</el-card>
@@ -294,6 +261,7 @@
import { userLoginFacotryList } from "@/api/system/user.js"
import {staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js"
import FormDialog from '@/components/Dialog/FormDialog.vue'
+import PIMTable from '@/components/PIMTable/PIMTable.vue'
// 鍝嶅簲寮忔暟鎹�
const currentUser = ref(null)
@@ -335,7 +303,7 @@
// 鍒嗛〉鍙傛暟
const page = reactive({
current: 1,
- size: 100,
+ size: 10,
total: 0
})
// 瑙勭珷鍒跺害鐩稿叧
@@ -418,10 +386,56 @@
official: '鍏珷',
contract: '鍚堝悓涓撶敤绔�',
finance: '璐㈠姟涓撶敤绔�',
+ legal: '娉曚汉绔�',
tegal: '鎶�鏈笓鐢ㄧ珷'
}
return sealTypeMap[sealType] || '鏈煡'
}
+
+// 鐢ㄥ嵃鐢宠琛ㄦ牸鍒楅厤缃紙闇�鍦� getStatusText/getSealTypeText 绛変箣鍚庡畾涔夛級
+const sealTableColumn = ref([
+ { label: '鐢宠缂栧彿', prop: 'applicationNum',},
+ { label: '鐢宠鏍囬', prop: 'title', showOverflowTooltip: true },
+ { label: '鐢宠浜�', prop: 'createUserName', },
+ { label: '鎵�灞為儴闂�', prop: 'department', width: 150 },
+ {
+ label: '鐢ㄥ嵃绫诲瀷',
+ prop: 'sealType',
+ dataType: 'tag',
+ formatData: (v) => getSealTypeText(v),
+ formatType: () => 'info'
+ },
+ { label: '鐢宠鏃堕棿', prop: 'createTime', width: 180 },
+ {
+ label: '鐘舵��',
+ prop: 'status',
+ width: 100,
+ dataType: 'tag',
+ formatData: (v) => getStatusText(v),
+ formatType: (v) => getStatusType(v)
+ },
+ {
+ dataType: 'action',
+ label: '鎿嶄綔',
+ width: 200,
+ fixed: 'right',
+ align: 'center',
+ operation: [
+ { name: '鏌ョ湅', clickFun: (row) => viewSealDetail(row) },
+ {
+ name: '瀹℃壒',
+ clickFun: (row) => approveSeal(row),
+ showHide: (row) => row.status === 'pending'
+ },
+ {
+ name: '鎷掔粷',
+ clickFun: (row) => rejectSeal(row),
+ showHide: (row) => row.status === 'pending'
+ }
+ ]
+ }
+])
+
// 鍒跺害鍒嗙被
const getCategoryText = (category) => {
const categoryMap = {
diff --git a/src/views/productionManagement/processRoute/processRouteItem/index.vue b/src/views/productionManagement/processRoute/processRouteItem/index.vue
index 99d89a9..3aecfa0 100644
--- a/src/views/productionManagement/processRoute/processRouteItem/index.vue
+++ b/src/views/productionManagement/processRoute/processRouteItem/index.vue
@@ -82,6 +82,11 @@
<el-table-column label="浜у搧鍚嶇О" prop="productName" min-width="160" />
<el-table-column label="瑙勬牸鍚嶇О" prop="model" min-width="140" />
<el-table-column label="鍗曚綅" prop="unit" width="100" />
+ <el-table-column label="鏄惁璐ㄦ" prop="isQuality" width="100">
+ <template #default="scope">
+ {{scope.row.isQuality ? "鏄�" : "鍚�"}}
+ </template>
+ </el-table-column>
<el-table-column label="鎿嶄綔" align="center" fixed="right" width="150">
<template #default="scope">
<el-button type="primary" link size="small" @click="handleEdit(scope.row)" :disabled="scope.row.isComplete">缂栬緫</el-button>
@@ -130,6 +135,7 @@
{{ item.model }}
<!-- <span v-if="item.unit" class="product-unit">{{ item.unit }}</span> -->
</div>
+ <el-tag type="primary" class="product-tag" v-if="item.isQuality">璐ㄦ</el-tag>
</div>
<div v-else class="product-info empty">鏆傛棤浜у搧淇℃伅</div>
</div>
@@ -188,6 +194,10 @@
clearable
:disabled="true"
/>
+ </el-form-item>
+
+ <el-form-item label="鏄惁璐ㄦ" prop="isQuality">
+ <el-switch v-model="form.isQuality" :active-value="true" inactive-value="false"/>
</el-form-item>
</el-form>
@@ -262,6 +272,7 @@
productName: "",
model: "",
unit: "",
+ isQuality: false,
});
const rules = {
@@ -340,6 +351,7 @@
productName: row.productName || "",
model: row.model || "",
unit: row.unit || "",
+ isQuality: row.isQuality,
};
dialogVisible.value = true;
};
@@ -402,12 +414,14 @@
productRouteId: routeId.value,
processId: form.value.processId,
productModelId: form.value.productModelId,
+ isQuality: form.value.isQuality,
dragSort,
})
: addOrUpdateProcessRouteItem({
routeId: routeId.value,
processId: form.value.processId,
productModelId: form.value.productModelId,
+ isQuality: form.value.isQuality,
dragSort,
});
@@ -432,12 +446,14 @@
id: form.value.id,
processId: form.value.processId,
productModelId: form.value.productModelId,
+ isQuality: form.value.isQuality,
})
: addOrUpdateProcessRouteItem({
routeId: routeId.value,
processId: form.value.processId,
productModelId: form.value.productModelId,
id: form.value.id,
+ isQuality: form.value.isQuality,
});
updatePromise
@@ -733,6 +749,10 @@
color: #409eff;
}
+.product-tag {
+ margin: 10px 0;
+}
+
.card-footer {
display: flex;
justify-content: space-around;
diff --git a/src/views/productionManagement/productionOrder/index.vue b/src/views/productionManagement/productionOrder/index.vue
index ece5ca6..9a4620f 100644
--- a/src/views/productionManagement/productionOrder/index.vue
+++ b/src/views/productionManagement/productionOrder/index.vue
@@ -239,8 +239,9 @@
// 娣诲姞琛ㄨ绫诲悕鏂规硶
const tableRowClassName = ({ row }) => {
- const diff = row.deliveryDaysDiff;
+ if (row.isFh) return '';
+ const diff = row.deliveryDaysDiff;
if (diff === 15) {
return 'yellow';
} else if (diff === 10) {
diff --git a/src/views/productionManagement/productionProcess/Edit.vue b/src/views/productionManagement/productionProcess/Edit.vue
index f979d51..8e92403 100644
--- a/src/views/productionManagement/productionProcess/Edit.vue
+++ b/src/views/productionManagement/productionProcess/Edit.vue
@@ -28,6 +28,9 @@
<el-form-item label="宸ヨ祫瀹氶" prop="salaryQuota">
<el-input v-model="formState.salaryQuota" type="number" :step="0.001" />
</el-form-item>
+ <el-form-item label="鏄惁璐ㄦ" prop="isQuality">
+ <el-switch v-model="formState.isQuality" :active-value="true" inactive-value="false"/>
+ </el-form-item>
<el-form-item label="澶囨敞" prop="remark">
<el-input v-model="formState.remark" type="textarea" />
</el-form-item>
@@ -67,6 +70,7 @@
no: props.record.no,
remark: props.record.remark,
salaryQuota: props.record.salaryQuota,
+ isQuality: props.record.isQuality,
});
const isShow = computed({
@@ -87,6 +91,7 @@
no: newRecord.no || '',
remark: newRecord.remark || '',
salaryQuota: newRecord.salaryQuota || '',
+ isQuality: props.record.isQuality,
};
}
}, { immediate: true, deep: true });
@@ -100,6 +105,7 @@
no: props.record.no || '',
remark: props.record.remark || '',
salaryQuota: props.record.salaryQuota || '',
+ isQuality: props.record.isQuality,
};
}
});
diff --git a/src/views/productionManagement/productionProcess/New.vue b/src/views/productionManagement/productionProcess/New.vue
index 7558ba7..5443e8d 100644
--- a/src/views/productionManagement/productionProcess/New.vue
+++ b/src/views/productionManagement/productionProcess/New.vue
@@ -28,6 +28,9 @@
<el-form-item label="宸ヨ祫瀹氶" prop="salaryQuota">
<el-input v-model="formState.salaryQuota" type="number" :step="0.001" />
</el-form-item>
+ <el-form-item label="鏄惁璐ㄦ" prop="isQuality">
+ <el-switch v-model="formState.isQuality" :active-value="true" inactive-value="false"/>
+ </el-form-item>
<el-form-item label="澶囨敞" prop="remark">
<el-input v-model="formState.remark" type="textarea" />
</el-form-item>
@@ -60,6 +63,7 @@
name: '',
remark: '',
salaryQuota: '',
+ isQuality: false,
});
const isShow = computed({
diff --git a/src/views/productionManagement/productionProcess/index.vue b/src/views/productionManagement/productionProcess/index.vue
index 67430cb..4f3f3ef 100644
--- a/src/views/productionManagement/productionProcess/index.vue
+++ b/src/views/productionManagement/productionProcess/index.vue
@@ -98,12 +98,18 @@
label: "宸ュ簭鍚嶇О",
prop: "name",
},
-
{
label: "宸ヨ祫瀹氶",
prop: "salaryQuota",
},
{
+ label: "鏄惁璐ㄦ",
+ prop: "isQuality",
+ formatData: (params) => {
+ return params ? "鏄�" : "鍚�";
+ },
+ },
+ {
label: "澶囨敞",
prop: "remark",
},
diff --git a/src/views/qualityManagement/finalInspection/components/formDia.vue b/src/views/qualityManagement/finalInspection/components/formDia.vue
index 8dfd3ba..6a3e774 100644
--- a/src/views/qualityManagement/finalInspection/components/formDia.vue
+++ b/src/views/qualityManagement/finalInspection/components/formDia.vue
@@ -201,64 +201,91 @@
const openDialog = async (type, row) => {
operationType.value = type;
dialogFormVisible.value = true;
- getOptions().then((res) => {
- supplierList.value = res.data;
- });
- let userLists = await userListNoPage();
- userList.value = userLists.data;
- form.value = {}
+ // 鍏堟竻绌鸿〃鍗曢獙璇佺姸鎬侊紝閬垮厤闂儊
+ await nextTick();
+ proxy.$refs.formRef?.clearValidate();
+
+ // 骞惰鍔犺浇鍩虹鏁版嵁
+ const [userListsRes] = await Promise.all([
+ userListNoPage(),
+ getProductOptions(),
+ getOptions().then((res) => {
+ supplierList.value = res.data;
+ })
+ ]);
+ userList.value = userListsRes.data;
+
+ form.value = {}
testStandardOptions.value = [];
tableData.value = [];
- getProductOptions();
+
if (operationType.value === 'edit') {
// 鍏堜繚瀛� testStandardId锛岄伩鍏嶈娓呯┖
const savedTestStandardId = row.testStandardId;
// 鍏堣缃〃鍗曟暟鎹紝浣嗘殏鏃舵竻绌� testStandardId锛岀瓑閫夐」鍔犺浇瀹屾垚鍚庡啀璁剧疆
form.value = {...row, testStandardId: ''}
- currentProductId.value = row.productId || 0
- // 缂栬緫妯″紡涓嬶紝鍏堝姞杞芥寚鏍囬�夐」锛岀劧鍚庡姞杞藉弬鏁板垪琛�
- if (currentProductId.value) {
- // 鍏堝姞杞芥寚鏍囬�夐」
- let params = {
- productId: currentProductId.value,
- inspectType: 2
- }
- qualityInspectDetailByProductId(params).then(res => {
- testStandardOptions.value = res.data || [];
- // 浣跨敤 nextTick 鍜� setTimeout 纭繚閫夐」宸茬粡娓叉煋鍒� DOM
- nextTick(() => {
- setTimeout(() => {
- // 濡傛灉缂栬緫鏁版嵁涓湁 testStandardId锛屽垯璁剧疆骞跺姞杞藉搴旂殑鍙傛暟
- if (savedTestStandardId) {
- // 纭繚绫诲瀷鍖归厤锛坕tem.id 鍙兘鏄暟瀛楁垨瀛楃涓诧級
- const matchedOption = testStandardOptions.value.find(item =>
- item.id == savedTestStandardId || String(item.id) === String(savedTestStandardId)
- );
- if (matchedOption) {
- // 纭繚浣跨敤鍖归厤椤圭殑 id锛堜繚鎸佺被鍨嬩竴鑷达級
- form.value.testStandardId = matchedOption.id;
- // 缂栬緫鍦烘櫙淇濈暀宸叉湁妫�楠屽�硷紝鐩存帴鎷夊彇鍘熷弬鏁版暟鎹�
- getQualityInspectParamList(row.id);
- } else {
- // 濡傛灉鎵句笉鍒板尮閰嶉」锛屽皾璇曠洿鎺ヤ娇鐢ㄥ師鍊�
- console.warn('鏈壘鍒板尮閰嶇殑鎸囨爣閫夐」锛宼estStandardId:', savedTestStandardId, '鍙敤閫夐」:', testStandardOptions.value);
- form.value.testStandardId = savedTestStandardId;
- getQualityInspectParamList(row.id);
- }
- } else {
- // 鍚﹀垯浣跨敤鏃х殑閫昏緫
- getQualityInspectParamList(row.id);
- }
- }, 100);
- });
- });
- } else {
- getQualityInspectParamList(row.id);
- }
+ currentProductId.value = row.productId || 0
+ // 娓呯┖楠岃瘉鐘舵�侊紝閬垮厤鏁版嵁鍔犺浇杩囩▼涓殑鏍¢獙闂儊
+ nextTick(() => {
+ proxy.$refs.formRef?.clearValidate();
+ });
+
+ // 缂栬緫妯″紡涓嬶紝骞惰鍔犺浇瑙勬牸鍨嬪彿鍜屾寚鏍囬�夐」
+ if (currentProductId.value) {
+ // 璁剧疆浜у搧鍚嶇О
+ form.value.productName = findNodeById(productOptions.value, currentProductId.value);
+
+ // 骞惰鍔犺浇瑙勬牸鍨嬪彿鍜屾寚鏍囬�夐」
+ const params = {
+ productId: currentProductId.value,
+ inspectType: 2
+ };
+
+ Promise.all([
+ modelList({ id: currentProductId.value }),
+ qualityInspectDetailByProductId(params)
+ ]).then(([modelRes, testStandardRes]) => {
+ // 璁剧疆瑙勬牸鍨嬪彿閫夐」
+ modelOptions.value = modelRes || [];
+ // 濡傛灉琛ㄥ崟涓凡鏈� productModelId锛岃缃搴旂殑 model 鍜� unit
+ if (form.value.productModelId && modelOptions.value.length > 0) {
+ const selectedModel = modelOptions.value.find(item => item.id == form.value.productModelId);
+ if (selectedModel) {
+ form.value.model = selectedModel.model || '';
+ form.value.unit = selectedModel.unit || '';
+ }
+ }
+
+ // 璁剧疆鎸囨爣閫夐」
+ testStandardOptions.value = testStandardRes.data || [];
+
+ // 璁剧疆 testStandardId 骞跺姞杞藉弬鏁板垪琛�
+ nextTick(() => {
+ if (savedTestStandardId) {
+ // 纭繚绫诲瀷鍖归厤锛坕tem.id 鍙兘鏄暟瀛楁垨瀛楃涓诧級
+ const matchedOption = testStandardOptions.value.find(item =>
+ item.id == savedTestStandardId || String(item.id) === String(savedTestStandardId)
+ );
+ if (matchedOption) {
+ // 纭繚浣跨敤鍖归厤椤圭殑 id锛堜繚鎸佺被鍨嬩竴鑷达級
+ form.value.testStandardId = matchedOption.id;
+ } else {
+ // 濡傛灉鎵句笉鍒板尮閰嶉」锛屽皾璇曠洿鎺ヤ娇鐢ㄥ師鍊�
+ console.warn('鏈壘鍒板尮閰嶇殑鎸囨爣閫夐」锛宼estStandardId:', savedTestStandardId, '鍙敤閫夐」:', testStandardOptions.value);
+ form.value.testStandardId = savedTestStandardId;
+ }
+ }
+ // 缂栬緫鍦烘櫙淇濈暀宸叉湁妫�楠屽�硷紝鐩存帴鎷夊彇鍘熷弬鏁版暟鎹�
+ getQualityInspectParamList(row.id);
+ });
+ });
+ } else {
+ getQualityInspectParamList(row.id);
+ }
}
}
const getProductOptions = () => {
- productTreeList().then((res) => {
+ return productTreeList().then((res) => {
productOptions.value = convertIdToValue(res);
});
};
diff --git a/src/views/reportAnalysis/qualityAnalysis/components/center-bottom.vue b/src/views/reportAnalysis/qualityAnalysis/components/center-bottom.vue
index 2f2fb66..24d9552 100644
--- a/src/views/reportAnalysis/qualityAnalysis/components/center-bottom.vue
+++ b/src/views/reportAnalysis/qualityAnalysis/components/center-bottom.vue
@@ -1,6 +1,9 @@
<template>
<div>
- <PanelHeader title="宸ュ崟鎵ц鏁堢巼鍒嗘瀽" />
+ <div class="chart-header">
+ <PanelHeader title="瀹屾垚妫�楠屾暟" />
+ <div class="warn-range" @click="handleRangeClick">杩�7澶�</div>
+ </div>
<div class="main-panel panel-item-customers">
<Echarts
ref="chart"
@@ -20,7 +23,7 @@
<script setup>
import { ref, onMounted } from 'vue'
-import { qualityStatistics } from '@/api/viewIndex.js'
+import { completedInspectionCount } from '@/api/viewIndex.js'
import PanelHeader from './PanelHeader.vue'
import Echarts from '@/components/Echarts/echarts.vue'
@@ -29,21 +32,25 @@
height: '135%',
}
-const grid = { left: '3%', right: '4%', bottom: '3%', top: '10%', containLabel: true }
+const grid = { left: '8%', right: '8%', bottom: '8%', top: '15%', containLabel: true }
const barLegend = {
show: true,
- textStyle: { color: '#B8C8E0' },
- data: ['寮�宸�', '瀹屾垚'],
+ top: '5%',
+ left: 'center',
+ textStyle: { color: '#B8C8E0', fontSize: 14 },
+ itemGap: 30,
+ data: ['鍚堟牸', '涓嶅悎鏍�', '鍚堟牸鐜�'],
}
-// 鏌辩姸鍥撅細寮�宸ャ�佸畬鎴愶紱鎶樼嚎鍥撅細鑹搧鐜囷紙棰滆壊 rgba(90, 216, 166, 1)锛�
+// 鏌辩姸鍥撅細鍚堟牸锛堥粍鑹诧級銆佷笉鍚堟牸锛堢传鑹诧級锛涙姌绾垮浘锛氬悎鏍肩巼锛堣摑鑹诧級
const chartSeries = ref([
{
- name: '寮�宸�',
+ name: '鍚堟牸',
type: 'bar',
barWidth: 20,
- barGap: '40%',
+ barGap: '20%',
+ yAxisIndex: 0,
emphasis: { focus: 'series' },
itemStyle: {
color: {
@@ -53,18 +60,19 @@
x2: 0,
y2: 1,
colorStops: [
- { offset: 1, color: 'rgba(0, 164, 237, 0)' },
- { offset: 0, color: 'rgba(78, 228, 255, 1)' },
+ { offset: 0, color: 'rgba(255, 215, 0, 1)' }, // 閲戦粍鑹查《閮�
+ { offset: 1, color: 'rgba(255, 215, 0, 0.5)' }, // 鍗婇�忔槑搴曢儴
],
},
},
data: [],
},
{
- name: '瀹屾垚',
+ name: '涓嶅悎鏍�',
type: 'bar',
- barGap: '40%',
+ barGap: '20%',
barWidth: 20,
+ yAxisIndex: 0,
emphasis: { focus: 'series' },
itemStyle: {
color: {
@@ -74,9 +82,34 @@
x2: 0,
y2: 1,
colorStops: [
- { offset: 1, color: 'rgba(83, 126, 245, 0.19)' },
- { offset: 0, color: 'rgba(144, 97, 248, 1)' },
+ { offset: 0, color: 'rgba(144, 97, 248, 1)' }, // 绱壊椤堕儴
+ { offset: 1, color: 'rgba(144, 97, 248, 0.6)' }, // 鍗婇�忔槑搴曢儴
],
+ },
+ },
+ data: [],
+ },
+ {
+ name: '鍚堟牸鐜�',
+ type: 'line',
+ yAxisIndex: 1,
+ smooth: true,
+ symbol: 'circle',
+ symbolSize: 8,
+ lineStyle: {
+ color: 'rgba(78, 228, 255, 1)', // 闈掕壊
+ width: 2,
+ },
+ itemStyle: {
+ color: 'rgba(78, 228, 255, 1)',
+ borderWidth: 2,
+ borderColor: '#fff',
+ },
+ emphasis: {
+ focus: 'series',
+ itemStyle: {
+ shadowBlur: 10,
+ shadowColor: 'rgba(78, 228, 255, 0.8)',
},
},
data: [],
@@ -86,53 +119,87 @@
const tooltip = {
trigger: 'axis',
axisPointer: { type: 'cross' },
+ backgroundColor: 'rgba(0, 0, 0, 0.8)',
+ borderColor: 'rgba(78, 228, 255, 0.5)',
+ borderWidth: 1,
+ textStyle: { color: '#B8C8E0' },
formatter(params) {
let result = params[0].axisValueLabel + '<br/>'
params.forEach((item) => {
- const unit = item.seriesName === '杩�7澶�'
- result += `<div>${item.marker} ${item.seriesName}: ${item.value}${unit}</div>`
+ let unit = ''
+ if (item.seriesName === '鍚堟牸鐜�') {
+ unit = '%'
+ } else {
+ unit = '浠�'
+ }
+ result += `<div style="margin: 4px 0;">${item.marker} ${item.seriesName}: ${item.value}${unit}</div>`
})
return result
},
}
const xAxis1 = ref([
- { type: 'category', axisTick: { show: false }, axisLabel: { color: '#B8C8E0' }, data: [] },
+ {
+ type: 'category',
+ axisTick: { show: false },
+ axisLabel: { color: '#B8C8E0', fontSize: 12 },
+ axisLine: { lineStyle: { color: 'rgba(184, 200, 224, 0.3)' } },
+ data: [],
+ },
])
+
const yAxis1 = [
- { type: 'value', name: '浠�', axisLabel: { color: '#B8C8E0' }, nameTextStyle: { color: '#B8C8E0' } },
{
type: 'value',
- name: '杩�7澶�',
+ name: '鍗曚綅: 浠�',
+ nameLocation: 'start',
+ nameTextStyle: { color: '#B8C8E0', fontSize: 12, padding: [0, 0, 0, 10] },
+ axisLabel: { color: '#B8C8E0', fontSize: 12 },
+ axisLine: { show: false },
+ splitLine: {
+ show: true,
+ lineStyle: { color: 'rgba(184, 200, 224, 0.2)', type: 'dashed' },
+ },
+ },
+ {
+ type: 'value',
+ name: '鍗曚綅: %',
+ nameLocation: 'end',
+ nameTextStyle: { color: '#B8C8E0', fontSize: 12, padding: [0, 0, 0, 10] },
min: 0,
max: 100,
- axisLabel: { color: '#B8C8E0', formatter: '{value}%' },
- nameTextStyle: { color: '#B8C8E0' },
- splitLine: { lineStyle: { color: 'rgba(184, 200, 224, 0.2)' } },
+ axisLabel: { color: '#B8C8E0', fontSize: 12, formatter: '{value}' },
+ axisLine: { show: false },
+ splitLine: {
+ show: true,
+ lineStyle: { color: 'rgba(184, 200, 224, 0.2)', type: 'dashed' },
+ },
},
]
const fetchData = () => {
- qualityStatistics()
- .then((res) => {
- if (!res?.data?.item || !Array.isArray(res.data.item)) return
- const items = res.data.item
- xAxis1.value[0].data = items.map((d) => d.date)
- // 寮�宸ワ細杩囩▼妫�楠屾暟
- chartSeries.value[0].data = items.map((d) => Number(d.processNum) || 0)
- // 瀹屾垚锛氬嚭鍘傛暟
- chartSeries.value[1].data = items.map((d) => Number(d.factoryNum) || 0)
- // 鑹搧鐜囷細鍑哄巶鏁�/杩囩▼鏁�*100锛堟棤鍗曠嫭鎺ュ彛鏃剁敤姝ゅ崰浣嶏級
- chartSeries.value[2].data = items.map((d) => {
- const processNum = Number(d.processNum) || 0
- const factoryNum = Number(d.factoryNum) || 0
- if (processNum <= 0) return 0
- return Math.min(100, Math.round((factoryNum / processNum) * 100))
- })
- })
- .catch((err) => {
- console.error('鑾峰彇寮�宸ヤ笌鑹搧鐜囨暟鎹け璐�:', err)
- })
+ completedInspectionCount()
+ .then((res) => {
+ if (res?.code === 200 && Array.isArray(res?.data)) {
+ const items = res.data
+ // 鏇存柊X杞存棩鏈熸暟鎹�
+ xAxis1.value[0].data = items.map((d) => d.dateStr || '')
+ // 鏇存柊鍚堟牸鏁帮紙榛勮壊鏌辩姸鍥撅級
+ chartSeries.value[0].data = items.map((d) => Number(d.qualifiedCount) || 0)
+ // 鏇存柊涓嶅悎鏍兼暟锛堢传鑹叉煴鐘跺浘锛�
+ chartSeries.value[1].data = items.map((d) => Number(d.unqualifiedCount) || 0)
+ // 鏇存柊鍚堟牸鐜囷紙钃濊壊鎶樼嚎鍥撅級
+ chartSeries.value[2].data = items.map((d) => Number(d.passRate) || 0)
+ }
+ })
+ .catch((err) => {
+ console.error('鑾峰彇瀹屾垚妫�楠屾暟鏁版嵁澶辫触:', err)
+ })
+}
+
+const handleRangeClick = () => {
+ // 鍏堟寜鎴浘鍋氶潤鎬�"杩�7澶�"锛屽悗缁湁鐪熷疄绛涢�夐渶姹傚啀鎺ュ叆
+ fetchData()
}
onMounted(() => {
@@ -141,6 +208,35 @@
</script>
<style scoped>
+.chart-header {
+ position: relative;
+ display: flex;
+ align-items: center;
+}
+
+.warn-range {
+ position: absolute;
+ right: 0;
+ top: 0;
+ height: 32px;
+ padding: 0 14px;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ border-radius: 4px;
+ color: #ffffff;
+ font-weight: 600;
+ font-size: 14px;
+ background: linear-gradient(180deg, rgba(51, 120, 255, 1) 0%, rgba(0, 164, 237, 1) 100%);
+ border: 1px solid rgba(78, 228, 255, 0.25);
+ cursor: pointer;
+ z-index: 10;
+}
+
+.warn-range:hover {
+ background: linear-gradient(180deg, rgba(51, 140, 255, 1) 0%, rgba(0, 184, 237, 1) 100%);
+}
+
.main-panel {
display: flex;
flex-direction: column;
@@ -152,5 +248,7 @@
padding: 18px;
width: 100%;
height: 449px;
+ position: relative;
+ background: radial-gradient(circle at 50% 50%, rgba(78, 228, 255, 0.05) 0%, rgba(0, 0, 0, 0) 70%);
}
</style>
diff --git a/src/views/reportAnalysis/qualityAnalysis/components/center-center.vue b/src/views/reportAnalysis/qualityAnalysis/components/center-center.vue
index 8024092..8d28f7a 100644
--- a/src/views/reportAnalysis/qualityAnalysis/components/center-center.vue
+++ b/src/views/reportAnalysis/qualityAnalysis/components/center-center.vue
@@ -12,7 +12,8 @@
<div class="warn-body">
<div class="warn-list" role="list">
<div v-for="item in warnings" :key="item.id" class="warn-item" role="listitem" @click="openWarning(item)">
- <div class="warn-tag" :class="tagClass(item.type)">{{ item.typeText }}</div>
+ <div class="warn-tag" :class="tagClass(item.type)">{{ item.parentProductTitle }}-{{ item.productTitle }}
+ </div>
<div class="warn-text" :title="item.title">{{ item.title }}</div>
<div class="warn-action" @click.stop="openWarning(item)">鏌ョ湅</div>
<div class="warn-date">{{ item.date }}</div>
@@ -26,18 +27,18 @@
<script setup>
import { computed, getCurrentInstance, ref, onMounted } from 'vue'
import Echarts from '@/components/Echarts/echarts.vue'
-import { qualityUnqualifiedListPage } from '@/api/qualityManagement/nonconformingManagement.js'
+import { nonComplianceWarning } from '@/api/viewIndex.js'
const { proxy } = getCurrentInstance() || {}
-const warnings = ref([
- { id: '1', type: 'raw', typeText: '鍘熸潗鏂�', title: '鍏充簬浼佷笟鍘熸潗鏂欒皟鏁撮�氱煡', date: '2024.08.24' },
- { id: '2', type: 'raw', typeText: '鍘熸潗鏂�', title: '鍏充簬鍘熸潗鏂欐秷鑰楁柟妗堝缓璁剧殑閫氱煡', date: '2024.08.24' },
- { id: '3', type: 'final', typeText: '鎴愬搧', title: '鎴愬搧宸ヤ綔鍙扮郴缁熺淮鎶よ鍒掑畨鎺�', date: '2024.08.24' },
- { id: '4', type: 'final', typeText: '鎴愬搧', title: '鎴愬搧宸ヤ綔鍙扮郴缁熺淮鎶よ鍒掑畨鎺�', date: '2024.08.24' },
- { id: '5', type: 'semi', typeText: '鍗婃垚鍝�', title: 'HRM绯荤粺瀹夊叏鍗囩骇鍏憡锛氬姞寮鸿闂帶鍒垛��', date: '2024.08.24' },
- { id: '6', type: 'semi', typeText: '鍗婃垚鍝�', title: 'HRM绯荤粺瀹夊叏鍗囩骇鍏憡锛氬姞寮鸿闂帶鍒垛��', date: '2024.08.24' },
-])
+const warnings = ref([])
+
+// 鍗犳瘮鏁版嵁
+const ratios = ref({
+ rawMaterialRatio: 0,
+ semiFinishedProductRatio: 0,
+ finishedProductRatio: 0,
+})
const TAG_COLORS = {
raw: '#7C4DFF',
@@ -51,6 +52,14 @@
return 'tag-semi'
}
+// 鏍规嵁productTitle鏄犲皠绫诲瀷
+const mapProductTitleToType = (productTitle) => {
+ if (productTitle === '鍘熸潗鏂�') return 'raw'
+ if (productTitle === '鍗婃垚鍝�') return 'semi'
+ if (productTitle === '鎴愬搧') return 'final'
+ return 'raw' // 榛樿鍊�
+}
+
const pieChartStyle = { width: '100%', height: '100%' }
const pieOptions = {
@@ -60,19 +69,14 @@
const pieTooltip = {
trigger: 'item',
- formatter: (p) => `${p.name}锛�${p.value}`,
+ formatter: (p) => `${p.name}锛�${p.value}%`,
}
const pieData = computed(() => {
- const counts = { raw: 0, final: 0, semi: 0 }
- warnings.value.forEach((w) => {
- const key = w.type in counts ? w.type : 'raw'
- counts[key] += 1
- })
return [
- { name: '鍘熸潗鏂�', value: counts.raw, itemStyle: { color: TAG_COLORS.raw } },
- { name: '鍗婃垚鍝�', value: counts.semi, itemStyle: { color: TAG_COLORS.semi } },
- { name: '鎴愬搧', value: counts.final, itemStyle: { color: TAG_COLORS.final } },
+ { name: '鍘熸潗鏂�', value: ratios.value.rawMaterialRatio, itemStyle: { color: TAG_COLORS.raw } },
+ { name: '鍗婃垚鍝�', value: ratios.value.semiFinishedProductRatio, itemStyle: { color: TAG_COLORS.semi } },
+ { name: '鎴愬搧', value: ratios.value.finishedProductRatio, itemStyle: { color: TAG_COLORS.final } },
]
})
@@ -111,34 +115,42 @@
const fetchWarnings = async () => {
try {
- const res = await qualityUnqualifiedListPage({ pageNum: 1, pageSize: 6 })
- const rows = res?.rows || res?.data?.rows || res?.data || []
- if (!Array.isArray(rows) || rows.length === 0) return
+ const res = await nonComplianceWarning()
+ if (res?.code === 200 && res?.data) {
+ const data = res.data
- warnings.value = rows.slice(0, 6).map((r, idx) => {
- const typeCode = r.inspectType ?? r.modelType ?? r.type
- const mappedType = typeCode === 0 || typeCode === '0' ? 'raw' : typeCode === 1 || typeCode === '1' ? 'semi' : 'final'
- const title = r.title || r.unqualifiedTitle || r.remark || r.unqualifiedReason || '涓嶅悎鏍奸璀�'
- const date = (r.warningTime || r.createTime || r.updateTime || '').slice(0, 10).replace(/-/g, '.') || '2024.08.24'
- return {
- id: r.id ?? r.unqualifiedId ?? `${idx}`,
- type: mappedType,
- typeText: mappedType === 'raw' ? '鍘熸潗鏂�' : mappedType === 'semi' ? '鍗婃垚鍝�' : '鎴愬搧',
- title,
- date,
+ // 鏇存柊鍗犳瘮鏁版嵁
+ ratios.value = {
+ rawMaterialRatio: data.rawMaterialRatio ?? 0,
+ semiFinishedProductRatio: data.semiFinishedProductRatio ?? 0,
+ finishedProductRatio: data.finishedProductRatio ?? 0,
}
- })
+
+ // 鏇存柊璀﹀憡鍒楄〃
+ const children = data.children || []
+ warnings.value = children.map((item, idx) => {
+ const type = mapProductTitleToType(item.parentProductTitle)
+ const date = item.date ? item.date.replace(/-/g, '.') : ''
+ return {
+ id: item.id ?? `warning-${idx}`,
+ type,
+ parentProductTitle: item.parentProductTitle || '鍘熸潗鏂�',
+ productTitle: item.productTitle || '鍘熸潗鏂�',
+ title: item.description || '涓嶅悎鏍奸璀�',
+ date,
+ }
+ })
+ }
} catch (e) {
- // 鎺ュ彛澶辫触鍒欎繚鎸� mock
+ // 鎺ュ彛澶辫触鍒欎繚鎸佺┖鏁版嵁
console.error('鑾峰彇涓嶅悎鏍奸璀﹀け璐�:', e)
}
}
const openWarning = (item) => {
- const title = `銆�${item.typeText}銆�${item.title}`
- const content = `${title}鏃堕棿锛�${item.date}`
+ const title = `銆�${item.parentProductTitle}-${item.productTitle}銆�${item.title}`
if (proxy?.$modal?.alert) {
- proxy.$modal.alert(content)
+ proxy.$modal.alert(title)
return
}
// 鍏滃簳锛氭病鏈夊叏灞� modal 鏃剁敤 console
@@ -170,14 +182,11 @@
align-items: center;
justify-content: space-between;
border-bottom: 1px solid;
- border-image: linear-gradient(
- 270deg,
+ border-image: linear-gradient(270deg,
rgba(0, 126, 255, 0) 0%,
rgba(0, 126, 255, 0.4549) 35%,
#007eff 78%,
- #007eff 100%
- )
- 1;
+ #007eff 100%) 1;
padding: 10px 0 6px;
}
@@ -235,13 +244,13 @@
.warn-item {
display: grid;
- grid-template-columns: 88px 1fr auto 110px;
+ grid-template-columns: 130px 1fr auto 110px;
align-items: center;
gap: 12px;
color: #b8c8e0;
font-size: 14px;
- line-height: 1;
- padding: 6px 0;
+ line-height: 1.2;
+ padding: 8px 0;
border-radius: 4px;
transition: background-color 0.2s, color 0.2s;
}
diff --git a/src/views/reportAnalysis/qualityAnalysis/components/center-top.vue b/src/views/reportAnalysis/qualityAnalysis/components/center-top.vue
index 0937b32..3ecf799 100644
--- a/src/views/reportAnalysis/qualityAnalysis/components/center-top.vue
+++ b/src/views/reportAnalysis/qualityAnalysis/components/center-top.vue
@@ -2,11 +2,7 @@
<div>
<!-- 椤堕儴缁熻鍗$墖 -->
<div class="stats-cards">
- <div
- v-for="item in statItems"
- :key="item.name"
- class="stat-card"
- >
+ <div v-for="item in statItems" :key="item.name" class="stat-card">
<img src="@/assets/BI/icon@2x.png" alt="鍥炬爣" class="card-icon" />
<div class="card-content">
<span class="card-label">{{ item.name }}</span>
@@ -25,7 +21,7 @@
<script setup>
import { ref, onMounted } from 'vue'
-import { salesPurchaseStorageProductCount } from '@/api/viewIndex.js'
+import { qualityInspectionCount } from '@/api/viewIndex.js'
const statItems = ref([])
@@ -37,18 +33,32 @@
const compareClass = (val) => (val >= 0 ? 'compare-up' : 'compare-down')
const fetchData = () => {
- salesPurchaseStorageProductCount()
+ qualityInspectionCount()
.then((res) => {
- if (res.code === 200 && Array.isArray(res.data)) {
- statItems.value = res.data.map((item) => ({
- name: item.name,
- value: item.value,
- rate: item.rate,
- }))
+ if (res.code === 200 && res.data) {
+ const data = res.data
+
+ statItems.value = [
+ {
+ name: '鎬绘楠屾暟',
+ value: data.totalCount ?? 0,
+ rate: data.totalCountGrowthRate ?? 0,
+ },
+ {
+ name: '浠婃棩寰呭畬鎴愭暟',
+ value: data.todayPendingCount ?? 0,
+ rate: data.todayPendingCountGrowthRate ?? 0,
+ },
+ {
+ name: '浠婃棩宸插畬鎴愭暟',
+ value: data.todayCompletedCount ?? 0,
+ rate: data.todayCompletedCountGrowthRate ?? 0,
+ },
+ ]
}
})
.catch((err) => {
- console.error('鑾峰彇閿�鍞�/閲囪喘/鍌ㄥ瓨浜у搧鏁板け璐�:', err)
+ console.error('鑾峰彇璐ㄩ噺妫�楠岀粺璁″け璐�:', err)
})
}
@@ -97,7 +107,7 @@
.card-label {
font-weight: 400;
- font-size: 19px;
+ font-size: 16px;
color: rgba(208, 231, 255, 0.7);
}
@@ -109,7 +119,7 @@
color: #d0e7ff;
}
-.card-compare > span:first-child {
+.card-compare>span:first-child {
font-size: 13px;
opacity: 0.8;
}
@@ -121,7 +131,8 @@
.compare-icon {
font-size: 14px;
position: relative;
- top: -1px; /* 杞诲井涓婄Щ锛岃绠ご涓庢枃瀛楀瀭鐩村眳涓榻� */
+ top: -1px;
+ /* 杞诲井涓婄Щ锛岃绠ご涓庢枃瀛楀瀭鐩村眳涓榻� */
}
.compare-up .compare-value,
@@ -133,5 +144,4 @@
.compare-down .compare-icon {
color: #ff5252;
}
-
</style>
diff --git a/src/views/reportAnalysis/qualityAnalysis/components/left-top.vue b/src/views/reportAnalysis/qualityAnalysis/components/left-top.vue
index 7debef5..8237a3f 100644
--- a/src/views/reportAnalysis/qualityAnalysis/components/left-top.vue
+++ b/src/views/reportAnalysis/qualityAnalysis/components/left-top.vue
@@ -13,13 +13,8 @@
<div class="inspect-body">
<div class="ring">
- <Echarts
- :chartStyle="ringChartStyle"
- :series="buildRingSeries(section)"
- :tooltip="ringTooltip"
- :legend="{ show: false }"
- :options="ringOptions"
- />
+ <Echarts :chartStyle="ringChartStyle" :series="buildRingSeries(section)" :tooltip="ringTooltip"
+ :legend="{ show: false }" :options="ringOptions" />
</div>
<div class="stats">
@@ -51,42 +46,72 @@
</template>
<script setup>
-import { reactive } from 'vue'
+import { reactive, onMounted } from 'vue'
import Echarts from '@/components/Echarts/echarts.vue'
import PanelHeader from './PanelHeader.vue'
import DateTypeSwitch from './DateTypeSwitch.vue'
+import { rawMaterialDetection, processDetection, factoryDetection } from '@/api/viewIndex.js'
const QUALIFIED_COLOR = '#4EE4FF'
const UNQUALIFIED_COLOR = '#3378FF'
const TRACK_COLOR = 'rgba(78, 228, 255, 0.12)'
+
+const apiMap = {
+ raw: rawMaterialDetection,
+ process: processDetection,
+ final: factoryDetection,
+}
+
+
+const fetchSectionData = async (section) => {
+ const api = apiMap[section.key]
+ if (!api) return
+
+ try {
+ const res = await api({
+ type: section.dateType,
+ })
+
+ if (res?.code === 200 && res?.data) {
+ const data = res.data
+ section.qualifiedCount = Number(data.qualifiedCount || 0)
+ section.unqualifiedCount = Number(data.unqualifiedCount || 0)
+ section.qualifiedRate = Number(data.qualifiedRate || 0)
+ section.unqualifiedRate = Number(data.unqualifiedRate || 0)
+ }
+ } catch (err) {
+ console.error(`${section.key} 鎺ュ彛璇锋眰澶辫触`, err)
+ }
+}
+
const sections = reactive([
{
key: 'raw',
title: '鍘熸潗鏂欐娴�',
dateType: 1,
- qualifiedCount: 199,
- unqualifiedCount: 99,
- qualifiedRate: 90,
- unqualifiedRate: 10,
+ qualifiedCount: 0,
+ unqualifiedCount: 0,
+ qualifiedRate: 0,
+ unqualifiedRate: 0,
},
{
key: 'process',
title: '杩囩▼妫�娴�',
dateType: 1,
- qualifiedCount: 199,
- unqualifiedCount: 99,
- qualifiedRate: 90,
- unqualifiedRate: 10,
+ qualifiedCount: 0,
+ unqualifiedCount: 0,
+ qualifiedRate: 0,
+ unqualifiedRate: 0,
},
{
key: 'final',
title: '鎴愬搧鍑哄巶妫�娴�',
dateType: 1,
- qualifiedCount: 199,
- unqualifiedCount: 99,
- qualifiedRate: 90,
- unqualifiedRate: 10,
+ qualifiedCount: 0,
+ unqualifiedCount: 0,
+ qualifiedRate: 0,
+ unqualifiedRate: 0,
},
])
@@ -183,15 +208,15 @@
const section = sections.find((s) => s.key === key)
if (!section) return
section.dateType = dateType
- const rates = calcRates(section.qualifiedCount, section.unqualifiedCount)
- section.qualifiedRate = rates.qualifiedRate
- section.unqualifiedRate = rates.unqualifiedRate
+ // 鍒囨崲鏃ユ湡绫诲瀷鏃堕噸鏂拌幏鍙栨暟鎹�
+ fetchSectionData(section)
}
-sections.forEach((s) => {
- const rates = calcRates(s.qualifiedCount, s.unqualifiedCount)
- s.qualifiedRate = rates.qualifiedRate
- s.unqualifiedRate = rates.unqualifiedRate
+// 缁勪欢鎸傝浇鏃惰幏鍙栨墍鏈塻ection鐨勬暟鎹�
+onMounted(() => {
+ sections.forEach((section) => {
+ fetchSectionData(section)
+ })
})
</script>
@@ -248,7 +273,7 @@
width: 18px;
height: 7px;
border-radius: 8px;
- background: linear-gradient(360deg, rgba(33,133,255,0.4) 0%, rgba(33,221,255,0) 100%);
+ background: linear-gradient(360deg, rgba(33, 133, 255, 0.4) 0%, rgba(33, 221, 255, 0) 100%);
position: absolute;
top: 50%;
left: -1px;
@@ -308,7 +333,7 @@
flex: 1 1 auto;
min-height: 0;
display: flex;
- justify-content:space-around;
+ justify-content: space-around;
align-items: center;
gap: 18px;
}
@@ -329,11 +354,9 @@
position: absolute;
inset: -8px;
border-radius: 50%;
- background: repeating-conic-gradient(
- from 0deg,
- rgba(78, 228, 255, 0.75) 0 1deg,
- rgba(78, 228, 255, 0) 1deg 9deg
- );
+ background: repeating-conic-gradient(from 0deg,
+ rgba(78, 228, 255, 0.75) 0 1deg,
+ rgba(78, 228, 255, 0) 1deg 9deg);
-webkit-mask: radial-gradient(circle, transparent 62%, #000 63%);
mask: radial-gradient(circle, transparent 62%, #000 63%);
opacity: 0.35;
diff --git a/src/views/reportAnalysis/qualityAnalysis/components/right-bottom.vue b/src/views/reportAnalysis/qualityAnalysis/components/right-bottom.vue
index cd22d56..49621f3 100644
--- a/src/views/reportAnalysis/qualityAnalysis/components/right-bottom.vue
+++ b/src/views/reportAnalysis/qualityAnalysis/components/right-bottom.vue
@@ -1,43 +1,34 @@
<template>
<div>
- <PanelHeader title="浜у搧澶х被" />
+ <PanelHeader title="涓嶅悎鏍兼鍝佸鐞嗗垎鏋�" />
<div class="panel-item-customers">
<div class="pie-chart-wrapper" ref="pieWrapperRef">
<div class="pie-background" ref="pieBackgroundRef"></div>
- <Echarts
- ref="chart"
- :chartStyle="chartStyle"
- :legend="landLegend"
- :series="landSeries"
- :tooltip="landTooltip"
- :color="landColors"
- :options="pieOptions"
- style="height: 100%"
- class="land-chart"
- />
+ <Echarts ref="chart" :chartStyle="chartStyle" :legend="landLegend" :series="computedSeries"
+ :tooltip="landTooltip" :color="landColors" :options="pieOptions" style="height: 100%" class="land-chart" />
</div>
</div>
</div>
</template>
<script setup>
-import { ref, onMounted, onBeforeUnmount } from 'vue'
+import { ref, computed, onMounted, onBeforeUnmount } from 'vue'
import Echarts from '@/components/Echarts/echarts.vue'
import PanelHeader from './PanelHeader.vue'
-import { productCategoryDistribution } from '@/api/viewIndex.js'
+import { unqualifiedProductProcessingAnalysis } from '@/api/viewIndex.js'
import { useChartBackground } from '@/hooks/useChartBackground.js'
const pieWrapperRef = ref(null)
const pieBackgroundRef = ref(null)
const chart = ref(null)
-// 鏁版嵁鍒楄〃锛堟潵鑷帴鍙o級
+// 鏁版嵁鍒楄〃
const dataList = ref([])
-// 棰滆壊鍒楄〃
+// 棰滆壊鍒楄〃
const landColors = ['#26FFCB', '#24CBFF', '#35FBF4', '#2651FF', '#D1E4F5', '#5782F7', '#2F67EF', '#82BAFF']
-// label 瀵屾枃鏈細涓烘瘡涓鑹茬敓鎴愪竴涓皬鍦嗙偣鏍峰紡锛堢‘淇濆湪 label 涓彲瑙侊級
+// label 瀵屾枃鏈牱寮�
const dotRich = landColors.reduce((acc, color, idx) => {
acc[`dot${idx}`] = {
width: 8,
@@ -49,163 +40,113 @@
return acc
}, {})
-// 鍥句緥閰嶇疆锛堝彸渚х珫鎺掞級
-const landLegend = {
+// 鍥句緥閰嶇疆
+const landLegend = ref({
show: false,
icon: 'circle',
data: [],
right: '8%',
top: '40%',
orient: 'vertical',
- itemGap: 14,
- itemWidth: 6,
- itemHeight: 6,
textStyle: {
- fontSize: 12,
+ color: '#fff',
rich: {
- unit: {
- color: '#fff',
- fontSize: 12,
- padding: [0, 10, 0, 0],
- },
- text: {
- width: 60,
- color: '#fff',
- fontSize: 12,
- },
- },
- },
- formatter: function (name) {
- const list = dataList.value || []
- const item = list.find((d) => d.name === name)
- if (!item) return name
- const val = Number(item.value || 0)
- const totalValue = list.reduce((sum, it) => sum + Number(it.value || 0), 0)
- const percent = totalValue ? ((val / totalValue) * 100).toFixed(2) : '0.00'
- return `{text|${name}}${val}{unit| 鍏》}${percent}{unit|%}`
- },
-}
+ unit: { color: '#fff', fontSize: 12, padding: [0, 10, 0, 0] },
+ text: { width: 60, color: '#fff', fontSize: 12 },
+ }
+ }
+})
-// 鎻愮ず妗�
+// 鎻愮ず妗嗛厤缃�
const landTooltip = {
- // triggerOn: 'hover',
- alwaysShowContent: true,
+ trigger: 'item',
+ alwaysShowContent: false,
position: function (pt) {
return [pt[0], 130]
},
formatter: function (params) {
- return `${params.name} (${params.value}绫�)`
+ // 纭繚 params.data 瀛樺湪
+ if (!params.data) return ''
+ const { name, value, rate } = params.data
+ return `${name}<br/>鏁伴噺锛�${value}涓�<br/>鍗犳瘮锛�${rate}%`
},
}
-// 鍙屽眰鐜舰楗煎浘
-const landSeries = ref([
- {
- name: '浜у搧澶х被',
- type: 'pie',
- radius: ['35%', '55%'],
- center: ['50%', '50%'],
- label: {
- show: true,
- position: 'outside',
- color: '#fff',
- fontSize: 12,
- lineHeight: 18,
- rich: {
- ...dotRich,
- parent: { fontSize: 14, fontWeight: 600, color: '#fff', lineHeight: 20, overflow: 'break' },
- child: { fontSize: 12, color: '#fff', lineHeight: 18 },
+// 浣跨敤璁$畻灞炴�у鐞� Series
+const computedSeries = computed(() => {
+ return [
+ {
+ name: '涓嶅悎鏍兼鍝佸鐞嗗垎鏋�',
+ type: 'pie',
+ radius: ['35%', '55%'],
+ center: ['50%', '50%'],
+ label: {
+ show: true,
+ position: 'outside',
+ color: '#fff',
+ rich: {
+ ...dotRich,
+ parent: { fontSize: 14, fontWeight: 600, color: '#fff', lineHeight: 20 },
+ child: { fontSize: 12, color: '#fff', lineHeight: 18 },
+ },
+ formatter: function (params) {
+ if (!params.data) return ''
+ const dotKey = `dot${params.dataIndex % landColors.length}`
+ return `{${dotKey}|} {parent|${params.data.name} (${params.data.value}涓�)}`
+ },
},
- formatter: function (params) {
- const children = params?.data?.children || []
- const parentName = params?.data?.name || ''
- const rawVal = params?.data?.value
- const parentValue = typeof rawVal === 'number' && !Number.isNaN(rawVal) ? rawVal : (Number(rawVal) || 0)
- const dotKey = `dot${(params?.dataIndex || 0) % landColors.length}`
- const dot = `{${dotKey}|} `
- const parentLine = `${dot}{parent|${parentName} (${parentValue}绫�)}`
- if (!children.length) return parentLine
- // 鐖剁骇鍏ㄩ儴鏄剧ず锛涘瓙绾ф渶澶� 5 涓紝瓒呭嚭鏄剧ず鐪佺暐鍙�
- const displayed = children.slice(0, 5).map((c) => `{child|${c.name}}`)
- if (children.length > 5) displayed.push('{child|鈥')
- return [parentLine, ...displayed].join('\n')
+ labelLine: {
+ show: true,
+ length: 20,
+ lineStyle: { color: '#B8C8E0' },
},
+ data: dataList.value,
},
- labelLine: {
- show: true,
- length: 20,
- length2: 20,
- lineStyle: {
- color: '#B8C8E0',
- },
+ {
+ // 鍐呭湀瑁呴グ
+ type: 'pie',
+ radius: ['35%', '40%'],
+ center: ['50%', '50%'],
+ silent: true,
+ label: { show: false },
+ itemStyle: { color: 'rgba(0, 127, 255, 0.25)' },
+ data: [1],
},
- itemStyle: {
- color: function (params) {
- return landColors[params.dataIndex % landColors.length]
- },
- },
- data: dataList.value,
- },
- {
- // 鍐呭湀
- type: 'pie',
- radius: ['35%', '40%'],
- center: ['50%', '50%'],
- silent: true,
- label: {
- show: false,
- },
- labelLine: {
- show: false,
- },
- itemStyle: {
- color: 'rgba(0, 127, 255, 0.25)',
- },
- data: [1],
- },
-])
+ ]
+})
-const chartStyle = {
- width: '100%',
- height: '126%',
-}
+const chartStyle = { width: '100%', height: '126%' }
+const pieOptions = { backgroundColor: 'transparent' }
-const pieOptions = {
- backgroundColor: 'transparent',
- textStyle: { color: '#B8C8E0' },
-}
-
-// 浣跨敤灏佽鐨勮儗鏅綅缃皟鏁存柟娉曪紝鍙嚜瀹氫箟鍋忕Щ鍊�
+// 鑳屾櫙澶勭悊閽╁瓙
const { adjustBackgroundPosition, init: initBackground, cleanup: cleanupBackground } = useChartBackground({
wrapperRef: pieWrapperRef,
backgroundRef: pieBackgroundRef,
- offsetX: '-51.5%', // X 杞村亸绉伙紝鍙姩鎬佽皟鏁�
- offsetY: '-39%', // Y 杞村亸绉伙紝鍙姩鎬佽皟鏁�
- watchData: dataList // 鐩戝惉鏁版嵁鍙樺寲锛岃嚜鍔ㄨ皟鏁翠綅缃�
+ offsetX: '-51.5%',
+ offsetY: '-39%',
+ watchData: dataList
})
const loadData = async () => {
try {
- const res = await productCategoryDistribution()
- const items = res?.data?.items || []
- dataList.value = items.map((it) => ({
- name: it.name,
- value: Number(it.value || 0),
- rate: it.rate,
- children: Array.isArray(it.children) ? it.children : [],
- }))
- landLegend.data = dataList.value.map((d) => d.name)
- landSeries.value[0].data = dataList.value
- // 鏁版嵁鍔犺浇瀹屾垚鍚庤皟鏁磋儗鏅綅缃�
- adjustBackgroundPosition()
+ const res = await unqualifiedProductProcessingAnalysis()
+ if (res && res.code === 200) {
+ dataList.value = (res.data || []).map((it) => ({
+ name: it.name,
+ value: Number(it.value || 0),
+ rate: it.rate,
+ }))
+ landLegend.value.data = dataList.value.map((d) => d.name)
+
+ // 鏁版嵁鏇存柊鍚庡井璋冭儗鏅�
+ setTimeout(() => {
+ adjustBackgroundPosition()
+ }, 100)
+ }
} catch (e) {
- console.error('鑾峰彇浜у搧澶х被鍒嗗竷澶辫触:', e)
- dataList.value = []
- landLegend.data = []
- landSeries.value[0].data = []
+ console.error('鑾峰彇鏁版嵁澶辫触:', e)
}
}
-
onMounted(() => {
loadData()
@@ -229,7 +170,6 @@
position: relative;
width: 100%;
height: 320px;
- background: transparent;
}
.pie-background {
@@ -242,9 +182,8 @@
background-repeat: no-repeat;
z-index: 1;
pointer-events: none;
- /* 榛樿灞呬腑锛屼細鍦� JS 涓姩鎬佽皟鏁� */
left: 50%;
top: 50%;
transform: translate(-51.5%, -39%);
}
-</style>
+</style>
\ No newline at end of file
diff --git a/src/views/reportAnalysis/qualityAnalysis/components/right-top.vue b/src/views/reportAnalysis/qualityAnalysis/components/right-top.vue
index 1400cb2..890e99a 100644
--- a/src/views/reportAnalysis/qualityAnalysis/components/right-top.vue
+++ b/src/views/reportAnalysis/qualityAnalysis/components/right-top.vue
@@ -1,83 +1,121 @@
<template>
<div>
- <PanelHeader title="宸ュ崟鎵ц鏁堢巼鍒嗘瀽" />
+ <PanelHeader title="涓嶅悎鏍间骇鍝佹帓鍚�" />
<div class="main-panel panel-item-customers">
<div class="main-panel-container">
- <div
- style="color: white"
- class="main-panel-box"
- v-for="(item, index) in panelList"
- :key="index"
- >
- <div style="flex: 1" class="main-panel-box-left">Top{{ index + 1 }}</div>
- <div style="flex: 3" class="main-panel-box-right">
- <div class="main-panel-box-right-text">
- <span>鎬绘暟閲忥細{{ item.total }}</span>
- <span>宸插畬鎴愶細{{ item.finished }}</span>
- <span>鍚堟牸鐜囷細{{ item.qualifiedRate }}</span>
- </div>
- <div class="main-panel-box-right-progress">
- <el-progress :percentage="item.percentage" :format="format" />
+ <div style="color: white" class="main-panel-box" v-for="(item, index) in panelList" :key="index">
+ <!-- <div style="flex: 1" class="main-panel-box-left">{{ item.rank }}</div> -->
+ <div style="flex: 1" class="main-panel-box-left">{{ item.productName }}</div>
+ <div style="flex: 3" class="main-panel-box-right">
+ <!-- <div class="main-panel-box-right-title">{{ item.productName }}</div> -->
+ <div class="main-panel-box-right-text">
+ <span>鎬绘暟閲忥細{{ item.total }}</span>
+ <span>宸插畬鎴愶細{{ item.finished }}</span>
+ <span>鍚堟牸鐜囷細{{ item.qualifiedRate }}%</span>
+ </div>
+ <div class="main-panel-box-right-progress">
+ <el-progress :percentage="item.percentage" :format="format" />
+ </div>
+ </div>
</div>
</div>
- </div>
- </div>
</div>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
+import { unqualifiedProductRanking } from '@/api/viewIndex.js'
import PanelHeader from './PanelHeader.vue'
-const panelList = [
- { total: 100, finished: 100, qualifiedRate: 100, percentage: 100 }, // Top1
- { total: 200, finished: 180, qualifiedRate: 90, percentage: 90 }, // Top2
- { total: 200, finished: 180, qualifiedRate: 90, percentage: 90 }, // Top2
- { total: 200, finished: 180, qualifiedRate: 90, percentage: 90 }, // Top2
- { total: 200, finished: 180, qualifiedRate: 90, percentage: 90 }, // Top2
- { total: 200, finished: 180, qualifiedRate: 90, percentage: 90 }, // Top2
- { total: 200, finished: 180, qualifiedRate: 90, percentage: 90 }, // Top2
- { total: 200, finished: 180, qualifiedRate: 90, percentage: 90 }, // Top2
- { total: 200, finished: 180, qualifiedRate: 90, percentage: 90 }, // Top2
- { total: 150, finished: 120, qualifiedRate: 80, percentage: 80 } // Top3
- ]
- const format = (percentage) => {
- return `${percentage}%`;
- }
+
+const panelList = ref([])
+
+const format = (percentage) => {
+ return `${percentage}%`
+}
+
+const fetchData = () => {
+ unqualifiedProductRanking()
+ .then((res) => {
+ if (res?.code === 200 && Array.isArray(res?.data)) {
+ const data = res.data
+ panelList.value = data.map((item, index) => {
+ const total = Number(item.totalCount) || 0
+ const finished = Number(item.completedCount) || 0
+ const passRate = Number(item.passRate) || 0
+
+ return {
+ rank: `Top${index + 1}`,
+ productName: item.productName || `浜у搧${index + 1}`,
+ total: total.toFixed(2),
+ finished: finished.toFixed(2),
+ qualifiedRate: passRate.toFixed(2),
+ percentage: Math.min(100, Math.max(0, passRate)), // 纭繚鐧惧垎姣斿湪0-100涔嬮棿
+ }
+ })
+ }
+ })
+ .catch((err) => {
+ console.error('鑾峰彇宸ュ崟鎵ц鏁堢巼鍒嗘瀽鏁版嵁澶辫触:', err)
+ })
+}
+
onMounted(() => {
- // fetchData()
+ fetchData()
})
</script>
<style scoped>
-.main-panel-box{
+.main-panel-box {
display: flex;
flex-direction: row;
align-items: center;
height: 40px;
- .main-panel-box-left{
+
+ .main-panel-box-left {
background: red;
border-radius: 20px;
text-align: center;
line-height: 32px;
- margin: 0 20px;
+ margin: 0 20px;
}
- .main-panel-box-right{
+
+ .main-panel-box-right {
display: flex;
flex-direction: column;
- .main-panel-box-right-text{
+ flex: 1;
+
+ .main-panel-box-right-title {
+ font-size: 14px;
+ font-weight: 600;
+ color: #ffffff;
+ margin-bottom: 6px;
+ }
+
+ .main-panel-box-right-text {
font-size: 12px;
display: flex;
justify-content: space-between;
padding-right: 60px;
+ margin-bottom: 4px;
}
- .main-panel-box-right-progress{
- :deep(.el-progress__text){
+
+ .main-panel-box-right-progress {
+ :deep(.el-progress__text) {
color: white !important;
}
}
}
}
+
+.main-panel-container {
+ display: flex;
+ flex-direction: column;
+ gap: 12px;
+ height: 100%;
+ overflow-y: auto;
+}
+
.main-panel {
display: flex;
flex-direction: column;
@@ -89,5 +127,6 @@
padding: 18px;
width: 100%;
height: 449px;
+ overflow: hidden;
}
</style>
diff --git a/src/views/reportAnalysis/qualityAnalysis/index.vue b/src/views/reportAnalysis/qualityAnalysis/index.vue
index 759bf03..1163154 100644
--- a/src/views/reportAnalysis/qualityAnalysis/index.vue
+++ b/src/views/reportAnalysis/qualityAnalysis/index.vue
@@ -13,7 +13,7 @@
<!-- 椤堕儴鏍囬鏍� -->
<div class="dashboard-header">
- <div class="factory-name">鐢熶骇鏁版嵁鍒嗘瀽</div>
+ <div class="factory-name">杩涢攢璐ㄩ噺绫诲垎鏋�</div>
</div>
<!-- 涓昏鍐呭鍖哄煙 -->
@@ -32,7 +32,6 @@
<!-- 鍙充晶鍖哄煙 -->
<div class="right-panel">
-
<RightTop />
<RightBottom />
</div>
diff --git a/src/views/salesManagement/salesLedger/index.vue b/src/views/salesManagement/salesLedger/index.vue
index 5cf762c..8b7b17c 100644
--- a/src/views/salesManagement/salesLedger/index.vue
+++ b/src/views/salesManagement/salesLedger/index.vue
@@ -1004,8 +1004,9 @@
// 娣诲姞琛ㄨ绫诲悕鏂规硶
const tableRowClassName = ({ row }) => {
- const diff = row.deliveryDaysDiff;
+ if (row.isFh) return '';
+ const diff = row.deliveryDaysDiff;
if (diff === 15) {
return 'yellow';
} else if (diff === 10) {
--
Gitblit v1.9.3