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