From 87d86e5816558d1e9989b0cea9046478284eff89 Mon Sep 17 00:00:00 2001
From: huminmin <mac@MacBook-Pro.local>
Date: 星期二, 20 一月 2026 17:43:40 +0800
Subject: [PATCH] Merge branch 'dev_New' of http://114.132.189.42:9002/r/product-inventory-management into dev_New
---
src/assets/images/chartCard3.svg | 1
src/views/qualityManagement/processInspection/components/formDia.vue | 180 ++
src/views/collaborativeApproval/shipmentReview/fileList.vue | 43
src/views/qualityManagement/finalInspection/components/formDia.vue | 112 +
src/views/reportAnalysis/dataDashboard/index.vue | 596 +++++++
src/assets/images/chartCard.svg | 1
src/components/PIMTable/PIMTable.vue | 4
src/views/salesManagement/salesLedger/index.vue | 485 ++----
src/api/qualityManagement/metricMaintenance.js | 14
src/views/qualityManagement/metricBinding/index.vue | 36
src/api/collaborativeApproval/shipmentReview.js | 21
src/api/personnelManagement/employeeRecord.js | 27
src/assets/images/chartCard2.svg | 1
src/views/reportAnalysis/reportManagement/index.vue | 1997 +++++++++++++++++++---------
src/views/qualityManagement/rawMaterialInspection/components/formDia.vue | 109 +
src/views/collaborativeApproval/shipmentReview/index.vue | 340 ++++
src/views/qualityManagement/metricMaintenance/index.vue | 83 +
src/views/salesManagement/salesLedger/fileList.vue | 43
18 files changed, 3,029 insertions(+), 1,064 deletions(-)
diff --git a/src/api/collaborativeApproval/shipmentReview.js b/src/api/collaborativeApproval/shipmentReview.js
new file mode 100644
index 0000000..64fac69
--- /dev/null
+++ b/src/api/collaborativeApproval/shipmentReview.js
@@ -0,0 +1,21 @@
+// 鍙戣揣瀹℃壒
+import request from "@/utils/request";
+
+// 鑾峰彇鍙戣揣瀹℃壒鍒楄〃
+export function getShipmentApprovalList(query) {
+ return request({
+ url: '/shipmentApproval/listPage',
+ method: 'get',
+ params: query,
+ })
+}
+
+// 鍙戣揣鐢宠鎵瑰噯
+// /shipmentApproval/update
+export function approveShipment(query) {
+ return request({
+ url: '/shipmentApproval/update',
+ method: 'post',
+ data: query,
+ })
+}
\ No newline at end of file
diff --git a/src/api/personnelManagement/employeeRecord.js b/src/api/personnelManagement/employeeRecord.js
new file mode 100644
index 0000000..a4ad34b
--- /dev/null
+++ b/src/api/personnelManagement/employeeRecord.js
@@ -0,0 +1,27 @@
+import request from '@/utils/request'
+
+// 鏌ヨ鍦ㄨ亴鍛樺伐鍙拌处
+export function staffOnJobListPage(query) {
+ return request({
+ url: '/staff/staffOnJob/listPage',
+ method: 'get',
+ params: query,
+ })
+}
+// 鏌ヨ鍛樺伐鍏ヨ亴淇℃伅
+export function staffOnJobInfo(query) {
+ return request({
+ url: '/staff/staffOnJob/staffNo',
+ method: 'get',
+ params: query,
+ })
+}
+
+// 瀵煎嚭鍚堝悓鍓湰
+export function staffOnJobExportCopy(data) {
+ return request({
+ url: '/staff/staffOnJob/exportCopy',
+ method: 'post',
+ data: data,
+ })
+}
\ No newline at end of file
diff --git a/src/api/qualityManagement/metricMaintenance.js b/src/api/qualityManagement/metricMaintenance.js
index 53ca650..1ee9cad 100644
--- a/src/api/qualityManagement/metricMaintenance.js
+++ b/src/api/qualityManagement/metricMaintenance.js
@@ -37,10 +37,11 @@
}
// 鍒犻櫎鎸囨爣鍒楄〃
-export function qualityInspectDetailByProductId(productId) {
+export function qualityInspectDetailByProductId(params) {
return request({
- url: "/qualityTestStandard/product/" + productId,
+ url: "/qualityTestStandard/getQualityTestStandardByProductId",
method: "get",
+ params: params,
});
}
@@ -98,3 +99,12 @@
data: ids,
});
}
+
+// 鏍规嵁鏍囧噯ID鑾峰彇鏍囧噯鍙傛暟
+export function getQualityTestStandardParamByTestStandardId(testStandardId) {
+ return request({
+ url: "/qualityTestStandard/getQualityTestStandardParamByTestStandardId",
+ method: "get",
+ params: { testStandardId },
+ });
+}
diff --git a/src/assets/images/chartCard.svg b/src/assets/images/chartCard.svg
new file mode 100644
index 0000000..32d48b1
--- /dev/null
+++ b/src/assets/images/chartCard.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="40" height="40" viewBox="0 0 40 40"><defs><mask id="master_svg0_88_35670" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="40" height="40"><ellipse cx="20" cy="20" rx="20" ry="20" fill="#FFFFFF" fill-opacity="1"/></mask><clipPath id="master_svg1_88_35666"><rect x="7" y="7" width="27" height="27" rx="0"/></clipPath><linearGradient x1="0.5" y1="0" x2="0.5" y2="1" id="master_svg2_88_26531"><stop offset="0%" stop-color="#FFFFFF" stop-opacity="1"/><stop offset="98.57142567634583%" stop-color="#F0FBFF" stop-opacity="1"/></linearGradient><linearGradient x1="0.5" y1="0" x2="0.5" y2="1" id="master_svg3_88_26531"><stop offset="0%" stop-color="#FFFFFF" stop-opacity="1"/><stop offset="98.57142567634583%" stop-color="#F0FBFF" stop-opacity="1"/></linearGradient></defs><g mask="url(#master_svg0_88_35670)"><ellipse cx="20" cy="20" rx="20" ry="20" fill="#0092FF" fill-opacity="1"/><g clip-path="url(#master_svg1_88_35666)"><path d="M21.175671875,27.58515925L14.263672875000001,27.58515925C13.750673275,27.58515925,13.426672974999999,27.24765625,13.426672974999999,26.74815725C13.426672974999999,26.23515525,13.764173075,25.911160250000002,14.263672875000001,25.911160250000002L21.351173875,25.911160250000002C21.688676875,24.89865825,22.188173875,23.88615425,22.863174875,23.211156250000002L14.263672875000001,23.211156250000002C13.750673275,23.211156250000002,13.426672974999999,22.87365525,13.426672974999999,22.37415225C13.426672974999999,21.87465325,13.764173075,21.537155249999998,14.263672875000001,21.537155249999998L25.738675875,21.537155249999998C26.251674875,21.37515325,26.751174875,21.37515325,27.088676875,21.37515325C28.438678875,21.37515325,29.626676875,21.88815525,30.625678875,22.549656249999998L30.625678875,13.072656349999999C30.625678875,11.38515625,29.275674875,10.03515625,27.588174875,10.03515625L27.075177875,10.03515625L27.075177875,13.24815675C27.075177875,14.935656550000001,25.725173875,16.285657450000002,24.037676875000002,16.285657450000002L16.113174475,16.285657450000002C14.425674475000001,16.272157149999998,13.075673375000001,14.922158249999999,13.075673375000001,13.23465635L13.075673375000001,10.03515625L12.238672475,10.03515625C10.551171974999999,10.03515625,9.201171875,11.38515625,9.201171875,13.072656349999999L9.201171875,29.94765825C9.201171875,31.63515625,10.551171974999999,32.985161250000004,12.238672475,32.985161250000004L25.576673875,32.985161250000004C23.200674875,32.485662250000004,21.337675875000002,30.28515825,21.175671875,27.58515925Z" fill="url(#master_svg2_88_26531)" fill-opacity="1" style="mix-blend-mode:passthrough"/><path d="M16.1124145625,14.764538762499999L24.0504169625,14.764538762499999C24.8874170625,14.764538762499999,25.5624140625,14.0895385625,25.5624140625,13.252537762500001L25.5624140625,10.0395388625L22.5249171625,10.0395388625C22.3629159625,8.8650390625,21.3369150625,7.8525390625,19.986915562500002,7.8525390625C18.7989153625,7.8525390625,17.7864150625,8.8650390625,17.6244149625,10.0395388625L14.5869140625,10.0395388625L14.5869140625,13.252537762500001C14.5869140625,14.0895385625,15.2619143725,14.764538762499999,16.1124145625,14.764538762499999ZM30.7869150625,24.3900370625C29.9499160625,23.3775360625,28.5999220625,22.7025380625,27.2499170625,22.7025380625L26.412916062500003,22.7025380625C25.8999180625,22.7025380625,25.5759160625,22.8780390625,25.0629190625,23.2155400625C24.0504169625,23.7285370625,23.1999158625,24.7275330625,22.700415562499998,25.9155390625C22.5384173625,26.4285390625,22.5384173625,26.9280380625,22.5384173625,27.4275380625L22.5384173625,27.5895390625C22.700415562499998,30.1275410625,24.7254170625,31.9770390625,27.1014200625,31.9770390625C28.4514180625,31.9770390625,29.8014230625,31.3020400625,30.6384180625,30.2895320625C31.3134210625,29.4525340625,31.6509170625,28.4265380625,31.6509170625,27.2520330625C31.8129160625,26.2395310625,31.2999250625,25.2270370625,30.7869150625,24.3900370625ZM29.7879200625,26.5770380625L27.0879160625,29.2770390625C26.7504160625,29.6145400625,26.412916062500003,29.6145400625,26.0754160625,29.2770390625L24.387915562499998,27.5895390625C24.0504169625,27.2520370625,24.0504169625,26.9145390625,24.387915562499998,26.5770380625C24.725415062499998,26.2395380625,25.0629150625,26.2395400625,25.4004160625,26.5770380625L26.2374170625,27.4140400625L26.5749150625,27.7515370625L28.7619150625,25.5645350625C29.0994140625,25.2270370625,29.4369190625,25.2270370625,29.774416062500002,25.5645350625C30.1119160625,25.9020370625,30.1119160625,26.2395380625,29.7879200625,26.5770380625Z" fill="url(#master_svg3_88_26531)" fill-opacity="1" style="mix-blend-mode:passthrough"/></g></g></svg>
\ No newline at end of file
diff --git a/src/assets/images/chartCard2.svg b/src/assets/images/chartCard2.svg
new file mode 100644
index 0000000..ff67331
--- /dev/null
+++ b/src/assets/images/chartCard2.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="40" height="40" viewBox="0 0 40 40"><defs><mask id="master_svg0_88_35670" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="40" height="40"><ellipse cx="20" cy="20" rx="20" ry="20" fill="#FFFFFF" fill-opacity="1"/></mask><clipPath id="master_svg1_88_35666"><rect x="7" y="7" width="27" height="27" rx="0"/></clipPath><linearGradient x1="0.5" y1="0" x2="0.5" y2="1" id="master_svg2_88_26531"><stop offset="0%" stop-color="#FFFFFF" stop-opacity="1"/><stop offset="98.57142567634583%" stop-color="#F0FBFF" stop-opacity="1"/></linearGradient><linearGradient x1="0.5" y1="0" x2="0.5" y2="1" id="master_svg3_88_26531"><stop offset="0%" stop-color="#FFFFFF" stop-opacity="1"/><stop offset="98.57142567634583%" stop-color="#F0FBFF" stop-opacity="1"/></linearGradient></defs><g mask="url(#master_svg0_88_35670)"><ellipse cx="20" cy="20" rx="20" ry="20" fill="#5EB334" fill-opacity="1"/><g clip-path="url(#master_svg1_88_35666)"><path d="M21.175671875,27.58515925L14.263672875000001,27.58515925C13.750673275,27.58515925,13.426672974999999,27.24765625,13.426672974999999,26.74815725C13.426672974999999,26.23515525,13.764173075,25.911160250000002,14.263672875000001,25.911160250000002L21.351173875,25.911160250000002C21.688676875,24.89865825,22.188173875,23.88615425,22.863174875,23.211156250000002L14.263672875000001,23.211156250000002C13.750673275,23.211156250000002,13.426672974999999,22.87365525,13.426672974999999,22.37415225C13.426672974999999,21.87465325,13.764173075,21.537155249999998,14.263672875000001,21.537155249999998L25.738675875,21.537155249999998C26.251674875,21.37515325,26.751174875,21.37515325,27.088676875,21.37515325C28.438678875,21.37515325,29.626676875,21.88815525,30.625678875,22.549656249999998L30.625678875,13.072656349999999C30.625678875,11.38515625,29.275674875,10.03515625,27.588174875,10.03515625L27.075177875,10.03515625L27.075177875,13.24815675C27.075177875,14.935656550000001,25.725173875,16.285657450000002,24.037676875000002,16.285657450000002L16.113174475,16.285657450000002C14.425674475000001,16.272157149999998,13.075673375000001,14.922158249999999,13.075673375000001,13.23465635L13.075673375000001,10.03515625L12.238672475,10.03515625C10.551171974999999,10.03515625,9.201171875,11.38515625,9.201171875,13.072656349999999L9.201171875,29.94765825C9.201171875,31.63515625,10.551171974999999,32.985161250000004,12.238672475,32.985161250000004L25.576673875,32.985161250000004C23.200674875,32.485662250000004,21.337675875000002,30.28515825,21.175671875,27.58515925Z" fill="url(#master_svg2_88_26531)" fill-opacity="1" style="mix-blend-mode:passthrough"/><path d="M16.1124145625,14.764538762499999L24.0504169625,14.764538762499999C24.8874170625,14.764538762499999,25.5624140625,14.0895385625,25.5624140625,13.252537762500001L25.5624140625,10.0395388625L22.5249171625,10.0395388625C22.3629159625,8.8650390625,21.3369150625,7.8525390625,19.986915562500002,7.8525390625C18.7989153625,7.8525390625,17.7864150625,8.8650390625,17.6244149625,10.0395388625L14.5869140625,10.0395388625L14.5869140625,13.252537762500001C14.5869140625,14.0895385625,15.2619143725,14.764538762499999,16.1124145625,14.764538762499999ZM30.7869150625,24.3900370625C29.9499160625,23.3775360625,28.5999220625,22.7025380625,27.2499170625,22.7025380625L26.412916062500003,22.7025380625C25.8999180625,22.7025380625,25.5759160625,22.8780390625,25.0629190625,23.2155400625C24.0504169625,23.7285370625,23.1999158625,24.7275330625,22.700415562499998,25.9155390625C22.5384173625,26.4285390625,22.5384173625,26.9280380625,22.5384173625,27.4275380625L22.5384173625,27.5895390625C22.700415562499998,30.1275410625,24.7254170625,31.9770390625,27.1014200625,31.9770390625C28.4514180625,31.9770390625,29.8014230625,31.3020400625,30.6384180625,30.2895320625C31.3134210625,29.4525340625,31.6509170625,28.4265380625,31.6509170625,27.2520330625C31.8129160625,26.2395310625,31.2999250625,25.2270370625,30.7869150625,24.3900370625ZM29.7879200625,26.5770380625L27.0879160625,29.2770390625C26.7504160625,29.6145400625,26.412916062500003,29.6145400625,26.0754160625,29.2770390625L24.387915562499998,27.5895390625C24.0504169625,27.2520370625,24.0504169625,26.9145390625,24.387915562499998,26.5770380625C24.725415062499998,26.2395380625,25.0629150625,26.2395400625,25.4004160625,26.5770380625L26.2374170625,27.4140400625L26.5749150625,27.7515370625L28.7619150625,25.5645350625C29.0994140625,25.2270370625,29.4369190625,25.2270370625,29.774416062500002,25.5645350625C30.1119160625,25.9020370625,30.1119160625,26.2395380625,29.7879200625,26.5770380625Z" fill="url(#master_svg3_88_26531)" fill-opacity="1" style="mix-blend-mode:passthrough"/></g></g></svg>
\ No newline at end of file
diff --git a/src/assets/images/chartCard3.svg b/src/assets/images/chartCard3.svg
new file mode 100644
index 0000000..0e8ce16
--- /dev/null
+++ b/src/assets/images/chartCard3.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="40" height="40" viewBox="0 0 40 40"><defs><mask id="master_svg0_88_35670" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="40" height="40"><ellipse cx="20" cy="20" rx="20" ry="20" fill="#FFFFFF" fill-opacity="1"/></mask><clipPath id="master_svg1_88_35666"><rect x="7" y="7" width="27" height="27" rx="0"/></clipPath><linearGradient x1="0.5" y1="0" x2="0.5" y2="1" id="master_svg2_88_26531"><stop offset="0%" stop-color="#FFFFFF" stop-opacity="1"/><stop offset="98.57142567634583%" stop-color="#F0FBFF" stop-opacity="1"/></linearGradient><linearGradient x1="0.5" y1="0" x2="0.5" y2="1" id="master_svg3_88_26531"><stop offset="0%" stop-color="#FFFFFF" stop-opacity="1"/><stop offset="98.57142567634583%" stop-color="#F0FBFF" stop-opacity="1"/></linearGradient></defs><g mask="url(#master_svg0_88_35670)"><ellipse cx="20" cy="20" rx="20" ry="20" fill="#8000FF" fill-opacity="1"/><g clip-path="url(#master_svg1_88_35666)"><path d="M21.175671875,27.58515925L14.263672875000001,27.58515925C13.750673275,27.58515925,13.426672974999999,27.24765625,13.426672974999999,26.74815725C13.426672974999999,26.23515525,13.764173075,25.911160250000002,14.263672875000001,25.911160250000002L21.351173875,25.911160250000002C21.688676875,24.89865825,22.188173875,23.88615425,22.863174875,23.211156250000002L14.263672875000001,23.211156250000002C13.750673275,23.211156250000002,13.426672974999999,22.87365525,13.426672974999999,22.37415225C13.426672974999999,21.87465325,13.764173075,21.537155249999998,14.263672875000001,21.537155249999998L25.738675875,21.537155249999998C26.251674875,21.37515325,26.751174875,21.37515325,27.088676875,21.37515325C28.438678875,21.37515325,29.626676875,21.88815525,30.625678875,22.549656249999998L30.625678875,13.072656349999999C30.625678875,11.38515625,29.275674875,10.03515625,27.588174875,10.03515625L27.075177875,10.03515625L27.075177875,13.24815675C27.075177875,14.935656550000001,25.725173875,16.285657450000002,24.037676875000002,16.285657450000002L16.113174475,16.285657450000002C14.425674475000001,16.272157149999998,13.075673375000001,14.922158249999999,13.075673375000001,13.23465635L13.075673375000001,10.03515625L12.238672475,10.03515625C10.551171974999999,10.03515625,9.201171875,11.38515625,9.201171875,13.072656349999999L9.201171875,29.94765825C9.201171875,31.63515625,10.551171974999999,32.985161250000004,12.238672475,32.985161250000004L25.576673875,32.985161250000004C23.200674875,32.485662250000004,21.337675875000002,30.28515825,21.175671875,27.58515925Z" fill="url(#master_svg2_88_26531)" fill-opacity="1" style="mix-blend-mode:passthrough"/><path d="M16.1124145625,14.764538762499999L24.0504169625,14.764538762499999C24.8874170625,14.764538762499999,25.5624140625,14.0895385625,25.5624140625,13.252537762500001L25.5624140625,10.0395388625L22.5249171625,10.0395388625C22.3629159625,8.8650390625,21.3369150625,7.8525390625,19.986915562500002,7.8525390625C18.7989153625,7.8525390625,17.7864150625,8.8650390625,17.6244149625,10.0395388625L14.5869140625,10.0395388625L14.5869140625,13.252537762500001C14.5869140625,14.0895385625,15.2619143725,14.764538762499999,16.1124145625,14.764538762499999ZM30.7869150625,24.3900370625C29.9499160625,23.3775360625,28.5999220625,22.7025380625,27.2499170625,22.7025380625L26.412916062500003,22.7025380625C25.8999180625,22.7025380625,25.5759160625,22.8780390625,25.0629190625,23.2155400625C24.0504169625,23.7285370625,23.1999158625,24.7275330625,22.700415562499998,25.9155390625C22.5384173625,26.4285390625,22.5384173625,26.9280380625,22.5384173625,27.4275380625L22.5384173625,27.5895390625C22.700415562499998,30.1275410625,24.7254170625,31.9770390625,27.1014200625,31.9770390625C28.4514180625,31.9770390625,29.8014230625,31.3020400625,30.6384180625,30.2895320625C31.3134210625,29.4525340625,31.6509170625,28.4265380625,31.6509170625,27.2520330625C31.8129160625,26.2395310625,31.2999250625,25.2270370625,30.7869150625,24.3900370625ZM29.7879200625,26.5770380625L27.0879160625,29.2770390625C26.7504160625,29.6145400625,26.412916062500003,29.6145400625,26.0754160625,29.2770390625L24.387915562499998,27.5895390625C24.0504169625,27.2520370625,24.0504169625,26.9145390625,24.387915562499998,26.5770380625C24.725415062499998,26.2395380625,25.0629150625,26.2395400625,25.4004160625,26.5770380625L26.2374170625,27.4140400625L26.5749150625,27.7515370625L28.7619150625,25.5645350625C29.0994140625,25.2270370625,29.4369190625,25.2270370625,29.774416062500002,25.5645350625C30.1119160625,25.9020370625,30.1119160625,26.2395380625,29.7879200625,26.5770380625Z" fill="url(#master_svg3_88_26531)" fill-opacity="1" style="mix-blend-mode:passthrough"/></g></g></svg>
\ No newline at end of file
diff --git a/src/components/PIMTable/PIMTable.vue b/src/components/PIMTable/PIMTable.vue
index 1480893..dfbc231 100644
--- a/src/components/PIMTable/PIMTable.vue
+++ b/src/components/PIMTable/PIMTable.vue
@@ -130,7 +130,7 @@
</div>
<!-- 鎸夐挳 -->
- <div v-else-if="item.dataType == 'action'">
+ <div v-else-if="item.dataType == 'action'" @click.stop>
<template v-for="(o, key) in item.operation" :key="key">
<el-button
v-show="o.type != 'upload'"
@@ -145,7 +145,7 @@
: o.color,
}"
link
- @click="o.clickFun(scope.row)"
+ @click.stop="o.clickFun(scope.row)"
:key="key"
>
{{ o.name }}
diff --git a/src/views/collaborativeApproval/shipmentReview/fileList.vue b/src/views/collaborativeApproval/shipmentReview/fileList.vue
new file mode 100644
index 0000000..da37db2
--- /dev/null
+++ b/src/views/collaborativeApproval/shipmentReview/fileList.vue
@@ -0,0 +1,43 @@
+<template>
+ <el-dialog v-model="dialogVisible" title="闄勪欢" width="40%" :before-close="handleClose">
+ <el-table :data="tableData" border height="40vh">
+ <el-table-column label="闄勪欢鍚嶇О" prop="name" min-width="400" show-overflow-tooltip />
+ <el-table-column fixed="right" label="鎿嶄綔" width="100" align="center">
+ <template #default="scope">
+ <el-button link type="primary" size="small" @click="downLoadFile(scope.row)">涓嬭浇</el-button>
+ <el-button link type="primary" size="small" @click="lookFile(scope.row)">棰勮</el-button>
+ </template>
+ </el-table-column>
+ </el-table>
+ </el-dialog>
+ <filePreview ref="filePreviewRef" />
+</template>
+
+<script setup>
+import { ref } from 'vue'
+import filePreview from '@/components/filePreview/index.vue'
+
+const dialogVisible = ref(false)
+const tableData = ref([])
+const { proxy } = getCurrentInstance();
+const filePreviewRef = ref()
+const handleClose = () => {
+ dialogVisible.value = false
+}
+const open = (list) => {
+ dialogVisible.value = true
+ tableData.value = list
+}
+const downLoadFile = (row) => {
+ proxy.$download.name(row.url);
+
+}
+const lookFile = (row) => {
+ filePreviewRef.value.open(row.url)
+}
+defineExpose({
+ open
+})
+</script>
+
+<style></style>
\ No newline at end of file
diff --git a/src/views/collaborativeApproval/shipmentReview/index.vue b/src/views/collaborativeApproval/shipmentReview/index.vue
new file mode 100644
index 0000000..ac2b790
--- /dev/null
+++ b/src/views/collaborativeApproval/shipmentReview/index.vue
@@ -0,0 +1,340 @@
+<template>
+ <div class="app-container">
+ <div class="search_form">
+ <div>
+ <span class="search_title">閿�鍞悎鍚屽彿锛�</span>
+ <el-input
+ v-model="searchForm.salesContractNo"
+ style="width: 240px"
+ placeholder="璇疯緭鍏ラ攢鍞悎鍚屽彿鎼滅储"
+ @change="handleQuery"
+ clearable
+ :prefix-icon="Search"
+ />
+ <span class="search_title ml10">瀹℃壒鐘舵�侊細</span>
+ <el-select v-model="searchForm.approveStatus" clearable @change="handleQuery" style="width: 240px">
+ <el-option label="寰呭鏍�" :value="2" />
+ <el-option label="瀹℃牳鎴愬姛" :value="3" />
+ <el-option label="瀹℃牳澶辫触" :value="4" />
+ </el-select>
+ <el-button type="primary" @click="handleQuery" style="margin-left: 10px"
+ >鎼滅储</el-button
+ >
+ </div>
+ <div>
+<!-- <el-button type="primary" @click="openForm('add')">鏂板</el-button>-->
+ <el-button @click="handleOut">瀵煎嚭</el-button>
+<!-- <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>-->
+ </div>
+ </div>
+ <div class="table_list">
+ <PIMTable
+ rowKey="id"
+ :column="tableColumn"
+ :tableData="tableData"
+ :page="page"
+ :isSelection="true"
+ @selection-change="handleSelectionChange"
+ :tableLoading="tableLoading"
+ @pagination="pagination"
+ :total="page.total"
+ ></PIMTable>
+ </div>
+ <info-form-dia ref="infoFormDia" @close="handleQuery" :approveType="approveType"></info-form-dia>
+ <approval-dia ref="approvalDia" @close="handleQuery"></approval-dia>
+ <FileList ref="fileListRef" />
+ </div>
+</template>
+
+<script setup>
+import FileList from "./fileList.vue";
+import { Search } from "@element-plus/icons-vue";
+import {onMounted, ref} from "vue";
+import {ElMessageBox} from "element-plus";
+import InfoFormDia from "@/views/collaborativeApproval/approvalProcess/components/infoFormDia.vue";
+import ApprovalDia from "@/views/collaborativeApproval/approvalProcess/components/approvalDia.vue";
+import {getShipmentApprovalList, approveShipment} from "@/api/collaborativeApproval/shipmentReview.js";
+// import {approveProcessDelete, approveProcessListPage} from "@/api/collaborativeApproval/approvalProcess.js";
+import useUserStore from "@/store/modules/user";
+import { userListNoPage } from "@/api/system/user.js";
+
+// 瀹氫箟缁勪欢鎺ユ敹鐨刾rops
+const props = defineProps({
+ approveType: {
+ type: [Number, String],
+ default: 6
+ }
+});
+
+const userList = ref([]);
+
+const userStore = useUserStore();
+
+
+const data = reactive({
+ searchForm: {
+ approveId: "",
+ approveStatus: "",
+ },
+});
+const { searchForm } = toRefs(data);
+const tableColumn = ref([
+ {
+ label: "瀹℃壒鐘舵��",
+ prop: "approveStatus",
+ dataType: "tag",
+ width: 100,
+ formatData: (params) => {
+ if (params === 2) {
+ return "寰呭鏍�";
+ } else if (params === 3) {
+ return "瀹℃牳瀹屾垚";
+ } else if (params === 4) {
+ return "瀹℃牳椹冲洖";
+ } else {
+ return '鏈煡鐘舵��';
+ }
+ },
+ formatType: (params) => {
+ if (params === 0) {
+ return "warning";
+ } else if (params === 2) {
+ return "info";
+ } else if (params === 3) {
+ return "success";
+ } else if (params === 4) {
+ return "danger";
+ } else {
+ return 'danger';
+ }
+ },
+ },
+ {
+ label: "閿�鍞悎鍚屽彿",
+ prop: "salesContractNo",
+ width: 170
+ },
+ {
+ label: "瀹㈡埛鍚嶇О",
+ prop: "customerName",
+ width: 200
+ },
+ {
+ label: "浜у搧澶х被",
+ prop: "productCategory",
+ width: 200
+ },
+ {
+ label: "瑙勬牸鍨嬪彿",
+ prop: "specificationModel",
+ width: 220
+ },
+ {
+ label: "鐢宠浜�",
+ prop: "approveUserId",
+ width: 120,
+ align: "center",
+ formatData:(params)=>{
+ const user = userList.value.find(item => item.userId === params)
+ return user ? user.nickName : '--'
+ }
+ },
+ {
+ label: "杞︾墝鍙�",
+ prop: "shippingCarNumber",
+ width: 120,
+ },
+ {
+ label: "鐢宠浜�",
+ prop: "approveUserId",
+ width: 120,
+ },
+ {
+ label: "鐢宠鏃ユ湡",
+ prop: "executionDate",
+ width: 200
+ },
+ {
+ label: "褰撳墠瀹℃壒浜�",
+ prop: "salesman",
+ width: 120
+ },
+ {
+ dataType: "action",
+ label: "鎿嶄綔",
+ align: "center",
+ fixed: "right",
+ width: 120,
+ operation: [
+ {
+ name: "閫氳繃",
+ type: "text",
+ clickFun: (row) => {
+ handleApproval("閫氳繃", row);
+ },
+ disabled: (row) => row.approveStatus !== 2
+ },
+ {
+ name: "椹冲洖",
+ type: "text",
+ clickFun: (row) => {
+ handleApproval("椹冲洖", row);
+ },
+ disabled: (row) => row.approveStatus !== 2
+ },
+ // {
+ // name: "缂栬緫",
+ // type: "text",
+ // clickFun: (row) => {
+ // openForm("edit", row);
+ // },
+ // disabled: (row) => row.approveStatus == 2 || row.approveStatus == 1 || row.approveStatus == 4
+ // },
+ // {
+ // name: "瀹℃牳",
+ // type: "text",
+ // clickFun: (row) => {
+ // openApprovalDia("approval", row);
+ // },
+ // disabled: (row) => row.approveUserCurrentId == null || row.approveStatus == 2 || row.approveStatus == 3 || row.approveStatus == 4 || row.approveUserCurrentId !== userStore.id
+ // },
+ // {
+ // name: "璇︽儏",
+ // type: "text",
+ // clickFun: (row) => {
+ // openApprovalDia('view', row);
+ // },
+ // },
+ // {
+ // name: "闄勪欢",
+ // type: "text",
+ // clickFun: (row) => {
+ // downLoadFile(row);
+ // },
+ // },
+ ],
+ },
+]);
+const tableData = ref([]);
+const selectedRows = ref([]);
+const tableLoading = ref(false);
+const page = reactive({
+ current: 1,
+ size: 100,
+ total: 0
+});
+const infoFormDia = ref()
+const approvalDia = ref()
+const { proxy } = getCurrentInstance()
+
+// 鏌ヨ鍒楄〃
+/** 鎼滅储鎸夐挳鎿嶄綔 */
+const handleQuery = () => {
+ page.current = 1;
+ getList();
+};
+const fileListRef = ref(null)
+const downLoadFile = (row) => {
+ fileListRef.value.open(row.commonFileList)
+
+}
+const pagination = (obj) => {
+ page.current = obj.page;
+ page.size = obj.limit;
+ getList();
+};
+const getList =async () => {
+ let userLists = await userListNoPage();
+ userList.value = userLists.data;
+ tableLoading.value = true;
+ getShipmentApprovalList({...page, ...searchForm.value,approveType:props.approveType}).then(res => {
+ tableLoading.value = false;
+ tableData.value = res.data.records
+ page.total = res.data.total;
+ }).catch(err => {
+ tableLoading.value = false;
+ })
+};
+// 瀵煎嚭
+const handleOut = () => {
+ const type = Number(props.approveType || 6)
+ const urlMap = {
+ 0: "/shipmentApproval/export",
+ }
+ const url = urlMap[type] || urlMap[0]
+ const nameMap = {
+ 0: "鍙戣揣瀹℃牳琛�",
+ }
+ const fileName = nameMap[type] || nameMap[0]
+ proxy.download(url, {}, `${fileName}.xlsx`)
+}
+// 琛ㄦ牸閫夋嫨鏁版嵁
+const handleSelectionChange = (selection) => {
+ selectedRows.value = selection;
+};
+
+// 鎵撳紑鏂板銆佺紪杈戝脊妗�
+const openForm = (type, row) => {
+ nextTick(() => {
+ infoFormDia.value?.openDialog(type, row)
+ })
+};
+// 鎵撳紑鏂板妫�楠屽脊妗�
+const openApprovalDia = (type, row) => {
+ nextTick(() => {
+ approvalDia.value?.openDialog(type, row)
+ })
+};
+
+// 瀹℃牳閫氳繃/椹冲洖
+const handleApproval = (name = "瀹℃牳",row) => {
+ ElMessageBox.confirm(`閫変腑鐨勫唴瀹瑰皢琚�${name}锛屾槸鍚︾‘璁�${name}锛焋, "鎻愮ず", {
+ confirmButtonText: "纭",
+ cancelButtonText: "鍙栨秷",
+ type: "warning",
+ }).then(async()=>{
+ let res = await approveShipment({
+ id: row.id,
+ approveStatus: name === "閫氳繃" ? 3 : 4
+ });
+ if(res.code === 200){
+ proxy.$modal.msgSuccess(`${name}鎴愬姛`);
+ }else{
+ proxy.$modal.msgError(`${name}澶辫触`);
+ }
+ await getList()
+ }).catch(err=>{
+ proxy.$modal.msgError(`鏈煡閿欒,璇疯仈绯荤鐞嗗憳`);
+ })
+};
+
+// 鍒犻櫎
+const handleDelete = () => {
+ let ids = [];
+ if (selectedRows.value.length > 0) {
+ ids = selectedRows.value.map((item) => item.approveId);
+ } else {
+ proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
+ return;
+ }
+ ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "瀵煎嚭", {
+ confirmButtonText: "纭",
+ cancelButtonText: "鍙栨秷",
+ type: "warning",
+ })
+ .then(() => {
+ approveProcessDelete(ids).then((res) => {
+ proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+ getList();
+ });
+ })
+ .catch(() => {
+ proxy.$modal.msg("宸插彇娑�");
+ });
+};
+onMounted(() => {
+ getList();
+});
+</script>
+
+<style scoped></style>
diff --git a/src/views/qualityManagement/finalInspection/components/formDia.vue b/src/views/qualityManagement/finalInspection/components/formDia.vue
index 057781c..5bd847f 100644
--- a/src/views/qualityManagement/finalInspection/components/formDia.vue
+++ b/src/views/qualityManagement/finalInspection/components/formDia.vue
@@ -27,6 +27,24 @@
<el-input v-model="form.model" placeholder="璇疯緭鍏�" clearable/>
</el-form-item>
</el-col>
+ <el-col :span="12">
+ <el-form-item label="鎸囨爣閫夋嫨锛�" prop="testStandardId">
+ <el-select
+ v-model="form.testStandardId"
+ placeholder="璇烽�夋嫨鎸囨爣"
+ clearable
+ @change="handleTestStandardChange"
+ style="width: 100%"
+ >
+ <el-option
+ v-for="item in testStandardOptions"
+ :key="item.id"
+ :label="item.standardName || item.standardNo"
+ :value="item.id"
+ />
+ </el-select>
+ </el-form-item>
+ </el-col>
</el-row>
<el-row :gutter="30">
<el-col :span="12">
@@ -101,12 +119,12 @@
</template>
<script setup>
-import {ref} from "vue";
+import {ref, reactive, toRefs, getCurrentInstance, nextTick} from "vue";
import {getOptions} from "@/api/procurementManagement/procurementLedger.js";
import {productTreeList} from "@/api/basicData/product.js";
import {qualityInspectAdd, qualityInspectUpdate} from "@/api/qualityManagement/rawMaterialInspection.js";
import {userListNoPage} from "@/api/system/user.js";
-import {qualityInspectDetailByProductId} from "@/api/qualityManagement/metricMaintenance.js";
+import {qualityInspectDetailByProductId, getQualityTestStandardParamByTestStandardId} from "@/api/qualityManagement/metricMaintenance.js";
import {qualityInspectParamInfo} from "@/api/qualityManagement/qualityInspectParam.js";
const { proxy } = getCurrentInstance()
const emit = defineEmits(['close'])
@@ -121,6 +139,7 @@
productName: "",
productId: "",
model: "",
+ testStandardId: "",
unit: "",
quantity: "",
checkCompany: "",
@@ -132,6 +151,7 @@
checkName: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
productId: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
model: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
+ testStandardId: [{required: true, message: "璇烽�夋嫨鎸囨爣", trigger: "change"}],
unit: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
quantity: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
checkCompany: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
@@ -169,6 +189,7 @@
const tableLoading = ref(false);
const userList = ref([]);
const currentProductId = ref(0);
+const testStandardOptions = ref([]); // 鎸囨爣閫夋嫨涓嬫媺妗嗘暟鎹�
// 鎵撳紑寮规
const openDialog = async (type, row) => {
@@ -180,11 +201,54 @@
let userLists = await userListNoPage();
userList.value = userLists.data;
form.value = {}
+ testStandardOptions.value = [];
+ tableData.value = [];
getProductOptions();
if (operationType.value === 'edit') {
- form.value = {...row}
+ // 鍏堜繚瀛� testStandardId锛岄伩鍏嶈娓呯┖
+ const savedTestStandardId = row.testStandardId;
+ // 鍏堣缃〃鍗曟暟鎹紝浣嗘殏鏃舵竻绌� testStandardId锛岀瓑閫夐」鍔犺浇瀹屾垚鍚庡啀璁剧疆
+ form.value = {...row, testStandardId: ''}
currentProductId.value = row.productId || 0
- getQualityInspectParamList(row.id)
+ // 缂栬緫妯″紡涓嬶紝鍏堝姞杞芥寚鏍囬�夐」锛岀劧鍚庡姞杞藉弬鏁板垪琛�
+ 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;
+ console.log(22222,form.value.testStandardId);
+ handleTestStandardChange(matchedOption.id);
+ } else {
+ // 濡傛灉鎵句笉鍒板尮閰嶉」锛屽皾璇曠洿鎺ヤ娇鐢ㄥ師鍊�
+ console.warn('鏈壘鍒板尮閰嶇殑鎸囨爣閫夐」锛宼estStandardId:', savedTestStandardId, '鍙敤閫夐」:', testStandardOptions.value);
+ form.value.testStandardId = savedTestStandardId;
+ handleTestStandardChange(savedTestStandardId);
+ }
+ } else {
+ // 鍚﹀垯浣跨敤鏃х殑閫昏緫
+ getQualityInspectParamList(row.id);
+ }
+ }, 100);
+ });
+ });
+ } else {
+ getQualityInspectParamList(row.id);
+ }
}
}
const getProductOptions = () => {
@@ -195,7 +259,7 @@
const getModels = (value) => {
currentProductId.value = value
form.value.productName = findNodeById(productOptions.value, value);
- if (currentProductId) {
+ if (currentProductId.value) {
getList();
}
};
@@ -253,9 +317,40 @@
})
}
const getList = () => {
- qualityInspectDetailByProductId(currentProductId.value).then(res => {
- tableData.value = res.data;
+ if (!currentProductId.value) {
+ testStandardOptions.value = [];
+ tableData.value = [];
+ return;
+ }
+ let params = {
+ productId: currentProductId.value,
+ inspectType: 2
+ }
+ qualityInspectDetailByProductId(params).then(res => {
+ // 淇濆瓨涓嬫媺妗嗛�夐」鏁版嵁
+ testStandardOptions.value = res.data || [];
+ // 娓呯┖琛ㄦ牸鏁版嵁锛岀瓑寰呯敤鎴烽�夋嫨鎸囨爣
+ tableData.value = [];
+ // 娓呯┖鎸囨爣閫夋嫨
+ form.value.testStandardId = '';
})
+}
+
+// 鎸囨爣閫夋嫨鍙樺寲澶勭悊
+const handleTestStandardChange = (testStandardId) => {
+ if (!testStandardId) {
+ tableData.value = [];
+ return;
+ }
+ tableLoading.value = true;
+ getQualityTestStandardParamByTestStandardId(testStandardId).then(res => {
+ tableData.value = res.data || [];
+ }).catch(error => {
+ console.error('鑾峰彇鏍囧噯鍙傛暟澶辫触:', error);
+ tableData.value = [];
+ }).finally(() => {
+ tableLoading.value = false;
+ })
}
const getQualityInspectParamList = (id) => {
qualityInspectParamInfo(id).then(res => {
@@ -265,6 +360,9 @@
// 鍏抽棴寮规
const closeDia = () => {
proxy.resetForm("formRef");
+ tableData.value = [];
+ testStandardOptions.value = [];
+ form.value.testStandardId = '';
dialogFormVisible.value = false;
emit('close')
};
diff --git a/src/views/qualityManagement/metricBinding/index.vue b/src/views/qualityManagement/metricBinding/index.vue
index d32a5df..ac67474 100644
--- a/src/views/qualityManagement/metricBinding/index.vue
+++ b/src/views/qualityManagement/metricBinding/index.vue
@@ -10,6 +10,7 @@
:isSelection="false"
:rowClassName="rowClassNameCenter"
:tableLoading="tableLoading"
+ :rowClick="handleTableRowClick"
@pagination="handlePagination"
:total="page.total"
>
@@ -197,12 +198,13 @@
}
const standardColumns = ref([
- { label: '鏍囧噯缂栧彿', prop: 'standardNo', dataType: 'slot', slot: 'standardNoCell', minWidth: 160, headerSlot: 'standardNoHeader' },
- { label: '鏍囧噯鍚嶇О', prop: 'standardName', minWidth: 180, headerSlot: 'standardNameHeader' },
+ { label: '鏍囧噯缂栧彿', prop: 'standardNo', dataType: 'slot', slot: 'standardNoCell', minWidth: 160, align: 'center', headerSlot: 'standardNoHeader' },
+ { label: '鏍囧噯鍚嶇О', prop: 'standardName', minWidth: 180, align: 'center', headerSlot: 'standardNameHeader' },
{
label: '绫诲埆',
prop: 'inspectType',
headerSlot: 'inspectTypeHeader',
+ align: 'center',
dataType: 'tag',
formatData: (val) => {
const map = { 0: '鍘熸潗鏂欐楠�', 1: '杩囩▼妫�楠�', 2: '鍑哄巶妫�楠�' }
@@ -212,6 +214,7 @@
{
label: '宸ュ簭',
prop: 'processId',
+ align: 'center',
dataType: 'tag',
formatData: (val) => {
const target = processOptions.value.find(
@@ -223,7 +226,8 @@
{
label: '澶囨敞',
prop: 'remark',
- minWidth: 160
+ minWidth: 160,
+ align: 'center'
}
// {
// label: '鐘舵��',
@@ -304,6 +308,13 @@
})
}
+// 琛ㄦ牸琛岀偣鍑伙紝鍔犺浇鍙充晶缁戝畾鍒楄〃
+const handleTableRowClick = (row) => {
+ currentStandard.value = row
+ loadBindingList()
+}
+
+// 宸︿晶琛岀偣鍑伙紝鍔犺浇鍙充晶缁戝畾鍒楄〃锛堜繚鐣欑敤浜庢爣鍑嗙紪鍙峰垪鐨勭偣鍑伙級
const handleStandardRowClick = (row) => {
currentStandard.value = row
loadBindingList()
@@ -471,4 +482,23 @@
:deep(.center-table .el-table__body-wrapper td .cell) {
text-align: center !important;
}
+
+/* PIMTable 琛ㄥご灞呬腑 */
+:deep(.lims-table .pim-table-header-cell) {
+ text-align: center;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+}
+
+:deep(.lims-table .pim-table-header-title) {
+ text-align: center;
+ width: 100%;
+}
+
+:deep(.lims-table .pim-table-header-extra) {
+ width: 100%;
+ margin-top: 4px;
+}
</style>
diff --git a/src/views/qualityManagement/metricMaintenance/index.vue b/src/views/qualityManagement/metricMaintenance/index.vue
index f152a04..44d3fae 100644
--- a/src/views/qualityManagement/metricMaintenance/index.vue
+++ b/src/views/qualityManagement/metricMaintenance/index.vue
@@ -19,6 +19,7 @@
:isSelection="true"
:tableLoading="tableLoading"
:rowClassName="rowClassNameCenter"
+ :rowClick="handleTableRowClick"
@selection-change="handleSelectionChange"
@pagination="handlePagination"
:total="page.total"
@@ -212,7 +213,7 @@
standardNo: [{ required: true, message: '璇疯緭鍏ユ爣鍑嗙紪鍙�', trigger: 'blur' }],
standardName: [{ required: true, message: '璇疯緭鍏ユ爣鍑嗗悕绉�', trigger: 'blur' }],
inspectType: [{ required: true, message: '璇烽�夋嫨妫�娴嬬被鍨�', trigger: 'change' }],
- processId: [{ required: true, message: '璇烽�夋嫨宸ュ簭', trigger: 'change' }]
+ processId: [{ required: false, message: '璇烽�夋嫨宸ュ簭', trigger: 'change' }]
}
})
@@ -277,18 +278,21 @@
dataType: 'slot',
slot: 'standardNoCell',
minWidth: 160,
+ align: 'center',
headerSlot: 'standardNoHeader'
},
{
label: '鏍囧噯鍚嶇О',
prop: 'standardName',
minWidth: 180,
+ align: 'center',
headerSlot: 'standardNameHeader'
},
{
label: '绫诲埆',
prop: 'inspectType',
headerSlot: 'inspectTypeHeader',
+ align: 'center',
dataType: 'tag',
formatData: (val) => {
const map = {
@@ -302,6 +306,7 @@
{
label: '宸ュ簭',
prop: 'processId',
+ align: 'center',
dataType: 'tag',
formatData: (val) => {
const target = processOptions.value.find(
@@ -314,6 +319,7 @@
label: '鐘舵��',
prop: 'state',
headerSlot: 'stateHeader',
+ align: 'center',
dataType: 'tag',
formatData: (val) => {
const map = {
@@ -332,7 +338,8 @@
{
label: '澶囨敞',
prop: 'remark',
- minWidth: 160
+ minWidth: 160,
+ align: 'center'
},
{
dataType: 'action',
@@ -447,7 +454,13 @@
getStandardList()
}
-// 宸︿晶琛岀偣鍑伙紝鍔犺浇鍙充晶鍙傛暟
+// 琛ㄦ牸琛岀偣鍑伙紝鍔犺浇鍙充晶鍙傛暟
+const handleTableRowClick = (row) => {
+ currentStandard.value = row
+ loadDetail(row.id)
+}
+
+// 宸︿晶琛岀偣鍑伙紝鍔犺浇鍙充晶鍙傛暟锛堜繚鐣欑敤浜庢爣鍑嗙紪鍙峰垪鐨勭偣鍑伙級
const handleStandardRowClick = (row) => {
currentStandard.value = row
loadDetail(row.id)
@@ -567,14 +580,23 @@
processId: ''
})
} else if (type === 'edit' && row) {
- Object.assign(standardForm.value, row)
+ Object.assign(standardForm.value, {
+ ...row,
+ // 纭繚 inspectType 鍜� state 杞崲涓哄瓧绗︿覆锛屼互鍖归厤 el-select 鐨� value 绫诲瀷
+ inspectType: row.inspectType !== null && row.inspectType !== undefined ? String(row.inspectType) : '',
+ state: row.state !== null && row.state !== undefined ? String(row.state) : '0',
+ // 纭繚 processId 杞崲涓哄瓧绗︿覆鎴栨暟瀛楋紙鏍规嵁瀹為檯闇�瑕侊級
+ processId: row.processId !== null && row.processId !== undefined ? row.processId : ''
+ })
} else if (type === 'copy' && row) {
const { id, ...rest } = row
Object.assign(standardForm.value, {
...rest,
id: undefined,
standardNo: '',
- state: '0'
+ state: '0',
+ // 纭繚 inspectType 杞崲涓哄瓧绗︿覆
+ inspectType: rest.inspectType !== null && rest.inspectType !== undefined ? String(rest.inspectType) : ''
})
}
standardDialogVisible.value = true
@@ -673,14 +695,41 @@
.metric-maintenance {
display: flex;
gap: 16px;
+ min-width: 0; /* 鍏佽 flex 瀛愬厓绱犳敹缂� */
}
.left-panel,
.right-panel {
flex: 1;
+ min-width: 0; /* 鍏佽 flex 瀛愬厓绱犳敹缂� */
background: #ffffff;
padding: 16px;
box-sizing: border-box;
+ overflow: hidden; /* 闃叉鍐呭婧㈠嚭 */
+}
+
+/* 浣庡垎杈ㄧ巼閫傞厤 */
+@media (max-width: 1400px) {
+ .metric-maintenance {
+ flex-direction: column;
+ }
+
+ .left-panel,
+ .right-panel {
+ width: 100%;
+ min-width: 0;
+ }
+}
+
+@media (max-width: 768px) {
+ .metric-maintenance {
+ gap: 12px;
+ }
+
+ .left-panel,
+ .right-panel {
+ padding: 12px;
+ }
}
.toolbar {
@@ -688,6 +737,8 @@
justify-content: space-between;
align-items: center;
margin-bottom: 12px;
+ flex-wrap: wrap;
+ gap: 8px;
}
.toolbar-left {
@@ -699,6 +750,9 @@
.toolbar-right {
flex-shrink: 0;
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
}
.search-label {
@@ -758,4 +812,23 @@
:deep(.center-table .el-table__body-wrapper td .cell) {
text-align: center !important;
}
+
+/* PIMTable 琛ㄥご灞呬腑 */
+:deep(.lims-table .pim-table-header-cell) {
+ text-align: center;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+}
+
+:deep(.lims-table .pim-table-header-title) {
+ text-align: center;
+ width: 100%;
+}
+
+:deep(.lims-table .pim-table-header-extra) {
+ width: 100%;
+ margin-top: 4px;
+}
</style>
\ No newline at end of file
diff --git a/src/views/qualityManagement/processInspection/components/formDia.vue b/src/views/qualityManagement/processInspection/components/formDia.vue
index 6126e6b..4821db2 100644
--- a/src/views/qualityManagement/processInspection/components/formDia.vue
+++ b/src/views/qualityManagement/processInspection/components/formDia.vue
@@ -9,8 +9,21 @@
<el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
<el-row :gutter="30">
<el-col :span="12">
- <el-form-item label="宸ュ簭锛�" prop="process">
- <el-input v-model="form.process" placeholder="璇疯緭鍏�" clearable/>
+ <el-form-item label="宸ュ簭锛�" prop="processId">
+ <el-select
+ v-model="form.processId"
+ placeholder="璇烽�夋嫨宸ュ簭"
+ clearable
+ @change="handleProcessChange"
+ style="width: 100%"
+ >
+ <el-option
+ v-for="item in processOptions"
+ :key="item.value"
+ :label="item.label"
+ :value="item.value"
+ />
+ </el-select>
</el-form-item>
</el-col>
<el-col :span="12">
@@ -32,6 +45,24 @@
<el-col :span="12">
<el-form-item label="瑙勬牸鍨嬪彿锛�" prop="model">
<el-input v-model="form.model" placeholder="璇疯緭鍏�" clearable/>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="鎸囨爣閫夋嫨锛�" prop="testStandardId">
+ <el-select
+ v-model="form.testStandardId"
+ placeholder="璇烽�夋嫨鎸囨爣"
+ clearable
+ @change="handleTestStandardChange"
+ style="width: 100%"
+ >
+ <el-option
+ v-for="item in testStandardOptions"
+ :key="item.id"
+ :label="item.standardName || item.standardNo"
+ :value="item.id"
+ />
+ </el-select>
</el-form-item>
</el-col>
</el-row>
@@ -108,11 +139,12 @@
</template>
<script setup>
-import {ref} from "vue";
+import {ref, reactive, toRefs, getCurrentInstance, nextTick} from "vue";
import {getOptions} from "@/api/procurementManagement/procurementLedger.js";
import {productTreeList} from "@/api/basicData/product.js";
+import {productProcessListPage} from "@/api/basicData/productProcess.js";
import {qualityInspectAdd, qualityInspectUpdate} from "@/api/qualityManagement/rawMaterialInspection.js";
-import {qualityInspectDetailByProductId} from "@/api/qualityManagement/metricMaintenance.js";
+import {qualityInspectDetailByProductId, getQualityTestStandardParamByTestStandardId} from "@/api/qualityManagement/metricMaintenance.js";
import {userListNoPage} from "@/api/system/user.js";
import {qualityInspectParamInfo} from "@/api/qualityManagement/qualityInspectParam.js";
const { proxy } = getCurrentInstance()
@@ -123,11 +155,12 @@
const data = reactive({
form: {
checkTime: "",
- process: "",
+ processId: "",
checkName: "",
productName: "",
productId: "",
model: "",
+ testStandardId: "",
unit: "",
quantity: "",
checkCompany: "",
@@ -135,10 +168,11 @@
},
rules: {
checkTime: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" },],
- process: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+ processId: [{ required: true, message: "璇烽�夋嫨宸ュ簭", trigger: "change" }],
checkName: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
productId: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
model: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
+ testStandardId: [{required: true, message: "璇烽�夋嫨鎸囨爣", trigger: "change"}],
unit: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
quantity: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
checkCompany: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
@@ -176,6 +210,24 @@
const tableData = ref([]);
const tableLoading = ref(false);
const currentProductId = ref(0);
+const processOptions = ref([]); // 宸ュ簭涓嬫媺妗嗘暟鎹�
+const testStandardOptions = ref([]); // 鎸囨爣閫夋嫨涓嬫媺妗嗘暟鎹�
+
+// 鑾峰彇宸ュ簭鍒楄〃
+const getProcessList = async () => {
+ try {
+ const res = await productProcessListPage({ current: 1, size: 1000 })
+ if (res?.code === 200) {
+ const records = res?.data?.records || []
+ processOptions.value = records.map(item => ({
+ label: item.processName || item.name || item.label,
+ value: item.id || item.processId || item.value
+ }))
+ }
+ } catch (error) {
+ console.error('鑾峰彇宸ュ簭鍒楄〃澶辫触:', error)
+ }
+}
// 鎵撳紑寮规
const openDialog = async (type, row) => {
@@ -187,11 +239,64 @@
let userLists = await userListNoPage();
userList.value = userLists.data;
form.value = {}
+ testStandardOptions.value = [];
+ tableData.value = [];
getProductOptions();
+ // 鍏堝姞杞藉伐搴忓垪琛�
+ await getProcessList();
if (operationType.value === 'edit') {
- form.value = {...row}
+ // 鍏堜繚瀛� testStandardId锛岄伩鍏嶈娓呯┖
+ const savedTestStandardId = row.testStandardId;
+ // 鍏堣缃〃鍗曟暟鎹紝浣嗘殏鏃舵竻绌� testStandardId锛岀瓑閫夐」鍔犺浇瀹屾垚鍚庡啀璁剧疆
+ form.value = {...row, testStandardId: ''}
+ // 鍏煎鏃ф暟鎹細濡傛灉 row 涓湁 process 瀛楁锛岃浆鎹负 processId
+ if (row.process && !row.processId) {
+ // 灏濊瘯浠� processOptions 涓煡鎵惧尮閰嶇殑宸ュ簭
+ const processOption = processOptions.value.find(p => p.label === row.process);
+ if (processOption) {
+ form.value.processId = processOption.value;
+ }
+ }
currentProductId.value = row.productId || 0
- getQualityInspectParamList(row.id)
+ // 缂栬緫妯″紡涓嬶紝鍏堝姞杞芥寚鏍囬�夐」锛岀劧鍚庡姞杞藉弬鏁板垪琛�
+ if (currentProductId.value) {
+ // 鍏堝姞杞芥寚鏍囬�夐」
+ let params = {
+ productId: currentProductId.value,
+ inspectType: 1,
+ process: form.value.processId ? processOptions.value.find(p => p.value === form.value.processId)?.label : ''
+ }
+ 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;
+ handleTestStandardChange(matchedOption.id);
+ } else {
+ // 濡傛灉鎵句笉鍒板尮閰嶉」锛屽皾璇曠洿鎺ヤ娇鐢ㄥ師鍊�
+ console.warn('鏈壘鍒板尮閰嶇殑鎸囨爣閫夐」锛宼estStandardId:', savedTestStandardId, '鍙敤閫夐」:', testStandardOptions.value);
+ form.value.testStandardId = savedTestStandardId;
+ handleTestStandardChange(savedTestStandardId);
+ }
+ } else {
+ // 鍚﹀垯浣跨敤鏃х殑閫昏緫
+ getQualityInspectParamList(row.id);
+ }
+ }, 100);
+ });
+ });
+ } else {
+ getQualityInspectParamList(row.id);
+ }
}
}
const getProductOptions = () => {
@@ -202,7 +307,7 @@
const getModels = (value) => {
currentProductId.value = value
form.value.productName = findNodeById(productOptions.value, value);
- if (currentProductId) {
+ if (currentProductId.value) {
getList();
}
};
@@ -234,17 +339,31 @@
return newItem;
});
}
+// 宸ュ簭鍙樺寲澶勭悊
+const handleProcessChange = () => {
+ // 宸ュ簭鍙樺寲鏃讹紝濡傛灉宸查�夋嫨浜у搧锛岄噸鏂板姞杞芥寚鏍囧垪琛�
+ if (currentProductId.value) {
+ getList();
+ }
+}
+
// 鎻愪氦浜у搧琛ㄥ崟
const submitForm = () => {
proxy.$refs.formRef.validate(valid => {
if (valid) {
form.value.inspectType = 1
+ // 灏� processId 杞崲涓� process 鍚嶇О锛堝鏋滃悗绔渶瑕� process 瀛楁锛�
+ const processName = form.value.processId ? processOptions.value.find(p => p.value === form.value.processId)?.label : '';
if (operationType.value === "add") {
tableData.value.forEach((item) => {
delete item.id
})
}
- const data = {...form.value, qualityInspectParams: tableData.value}
+ const data = {
+ ...form.value,
+ process: processName, // 淇濈暀 process 瀛楁浠ュ吋瀹瑰悗绔�
+ qualityInspectParams: tableData.value
+ }
if (operationType.value === "add") {
qualityInspectAdd(data).then(res => {
proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
@@ -260,8 +379,42 @@
})
}
const getList = () => {
- qualityInspectDetailByProductId(currentProductId.value).then(res => {
- tableData.value = res.data;
+ if (!currentProductId.value) {
+ testStandardOptions.value = [];
+ tableData.value = [];
+ return;
+ }
+ // 鑾峰彇宸ュ簭鍚嶇О
+ const processName = form.value.processId ? processOptions.value.find(p => p.value === form.value.processId)?.label : '';
+ let params = {
+ productId: currentProductId.value,
+ inspectType: 1,
+ process: processName
+ }
+ qualityInspectDetailByProductId(params).then(res => {
+ // 淇濆瓨涓嬫媺妗嗛�夐」鏁版嵁
+ testStandardOptions.value = res.data || [];
+ // 娓呯┖琛ㄦ牸鏁版嵁锛岀瓑寰呯敤鎴烽�夋嫨鎸囨爣
+ tableData.value = [];
+ // 娓呯┖鎸囨爣閫夋嫨
+ form.value.testStandardId = '';
+ })
+}
+
+// 鎸囨爣閫夋嫨鍙樺寲澶勭悊
+const handleTestStandardChange = (testStandardId) => {
+ if (!testStandardId) {
+ tableData.value = [];
+ return;
+ }
+ tableLoading.value = true;
+ getQualityTestStandardParamByTestStandardId(testStandardId).then(res => {
+ tableData.value = res.data || [];
+ }).catch(error => {
+ console.error('鑾峰彇鏍囧噯鍙傛暟澶辫触:', error);
+ tableData.value = [];
+ }).finally(() => {
+ tableLoading.value = false;
})
}
const getQualityInspectParamList = (id) => {
@@ -272,6 +425,9 @@
// 鍏抽棴寮规
const closeDia = () => {
proxy.resetForm("formRef");
+ tableData.value = [];
+ testStandardOptions.value = [];
+ form.value.testStandardId = '';
dialogFormVisible.value = false;
emit('close')
};
diff --git a/src/views/qualityManagement/rawMaterialInspection/components/formDia.vue b/src/views/qualityManagement/rawMaterialInspection/components/formDia.vue
index 5ea1e47..5cafd2c 100644
--- a/src/views/qualityManagement/rawMaterialInspection/components/formDia.vue
+++ b/src/views/qualityManagement/rawMaterialInspection/components/formDia.vue
@@ -45,6 +45,24 @@
<el-input v-model="form.model" placeholder="璇疯緭鍏�" clearable/>
</el-form-item>
</el-col>
+ <el-col :span="12">
+ <el-form-item label="鎸囨爣閫夋嫨锛�" prop="testStandardId">
+ <el-select
+ v-model="form.testStandardId"
+ placeholder="璇烽�夋嫨鎸囨爣"
+ clearable
+ @change="handleTestStandardChange"
+ style="width: 100%"
+ >
+ <el-option
+ v-for="item in testStandardOptions"
+ :key="item.id"
+ :label="item.standardName || item.standardNo"
+ :value="item.id"
+ />
+ </el-select>
+ </el-form-item>
+ </el-col>
</el-row>
<el-row :gutter="30">
<el-col :span="12">
@@ -121,13 +139,13 @@
</template>
<script setup>
-import {ref} from "vue";
+import {ref, reactive, toRefs, getCurrentInstance, nextTick} from "vue";
import {getOptions} from "@/api/procurementManagement/procurementLedger.js";
import {productTreeList} from "@/api/basicData/product.js";
import {qualityInspectAdd, qualityInspectUpdate} from "@/api/qualityManagement/rawMaterialInspection.js";
import {ElMessageBox} from "element-plus";
import {qualityInspectParamDel, qualityInspectParamInfo} from "@/api/qualityManagement/qualityInspectParam.js";
-import {qualityInspectDetailByProductId} from "@/api/qualityManagement/metricMaintenance.js";
+import {qualityInspectDetailByProductId, getQualityTestStandardParamByTestStandardId} from "@/api/qualityManagement/metricMaintenance.js";
const {proxy} = getCurrentInstance()
const emit = defineEmits(['close'])
@@ -142,6 +160,7 @@
productName: "",
productId: "",
model: "",
+ testStandardId: "",
unit: "",
quantity: "",
checkCompany: "",
@@ -153,6 +172,7 @@
checkName: [{required: false, message: "璇疯緭鍏�", trigger: "blur"}],
productId: [{required: true, message: "璇疯緭鍏�", trigger: "blur"}],
model: [{required: false, message: "璇疯緭鍏�", trigger: "blur"}],
+ testStandardId: [{required: true, message: "璇烽�夋嫨鎸囨爣", trigger: "change"}],
unit: [{required: false, message: "璇疯緭鍏�", trigger: "blur"}],
quantity: [{required: true, message: "璇疯緭鍏�", trigger: "blur"}],
checkCompany: [{required: false, message: "璇疯緭鍏�", trigger: "blur"}],
@@ -190,6 +210,7 @@
const supplierList = ref([]);
const productOptions = ref([]);
const currentProductId = ref(0);
+const testStandardOptions = ref([]); // 鎸囨爣閫夋嫨涓嬫媺妗嗘暟鎹�
// 鎵撳紑寮规
const openDialog = (type, row) => {
@@ -199,11 +220,52 @@
supplierList.value = res.data;
});
form.value = {}
+ testStandardOptions.value = [];
+ tableData.value = [];
getProductOptions();
if (operationType.value === 'edit') {
+ // 鍏堜繚瀛� testStandardId锛岄伩鍏嶈娓呯┖
+ const savedTestStandardId = row.testStandardId;
form.value = {...row}
currentProductId.value = row.productId || 0
- getQualityInspectParamList(row.id)
+ // 缂栬緫妯″紡涓嬶紝鍏堝姞杞芥寚鏍囬�夐」锛岀劧鍚庡姞杞藉弬鏁板垪琛�
+ if (currentProductId.value) {
+ // 鍏堝姞杞芥寚鏍囬�夐」
+ let params = {
+ productId: currentProductId.value,
+ inspectType: 0
+ }
+ 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;
+ handleTestStandardChange(matchedOption.id);
+ } else {
+ // 濡傛灉鎵句笉鍒板尮閰嶉」锛屽皾璇曠洿鎺ヤ娇鐢ㄥ師鍊�
+ console.warn('鏈壘鍒板尮閰嶇殑鎸囨爣閫夐」锛宼estStandardId:', savedTestStandardId, '鍙敤閫夐」:', testStandardOptions.value);
+ form.value.testStandardId = savedTestStandardId;
+ handleTestStandardChange(savedTestStandardId);
+ }
+ } else {
+ // 鍚﹀垯浣跨敤鏃х殑閫昏緫
+ getQualityInspectParamList(row.id);
+ }
+ }, 100);
+ });
+ });
+ } else {
+ getQualityInspectParamList(row.id);
+ }
}
}
const getProductOptions = () => {
@@ -214,7 +276,7 @@
const getModels = (value) => {
currentProductId.value = value
form.value.productName = findNodeById(productOptions.value, value);
- if (currentProductId) {
+ if (currentProductId.value) {
getList();
}
};
@@ -275,8 +337,39 @@
}
const getList = () => {
- qualityInspectDetailByProductId(currentProductId.value).then(res => {
- tableData.value = res.data;
+ if (!currentProductId.value) {
+ testStandardOptions.value = [];
+ tableData.value = [];
+ return;
+ }
+ let params = {
+ productId: currentProductId.value,
+ inspectType: 0
+ }
+ qualityInspectDetailByProductId(params).then(res => {
+ // 淇濆瓨涓嬫媺妗嗛�夐」鏁版嵁
+ testStandardOptions.value = res.data || [];
+ // 娓呯┖琛ㄦ牸鏁版嵁锛岀瓑寰呯敤鎴烽�夋嫨鎸囨爣
+ tableData.value = [];
+ // 娓呯┖鎸囨爣閫夋嫨
+ form.value.testStandardId = '';
+ })
+}
+
+// 鎸囨爣閫夋嫨鍙樺寲澶勭悊
+const handleTestStandardChange = (testStandardId) => {
+ if (!testStandardId) {
+ tableData.value = [];
+ return;
+ }
+ tableLoading.value = true;
+ getQualityTestStandardParamByTestStandardId(testStandardId).then(res => {
+ tableData.value = res.data || [];
+ }).catch(error => {
+ console.error('鑾峰彇鏍囧噯鍙傛暟澶辫触:', error);
+ tableData.value = [];
+ }).finally(() => {
+ tableLoading.value = false;
})
}
@@ -288,7 +381,9 @@
// 鍏抽棴寮规
const closeDia = () => {
proxy.resetForm("formRef");
- tableData.value = []
+ tableData.value = [];
+ testStandardOptions.value = [];
+ form.value.testStandardId = '';
dialogFormVisible.value = false;
emit('close')
};
diff --git a/src/views/reportAnalysis/dataDashboard/index.vue b/src/views/reportAnalysis/dataDashboard/index.vue
index 574c3f2..566d7ea 100644
--- a/src/views/reportAnalysis/dataDashboard/index.vue
+++ b/src/views/reportAnalysis/dataDashboard/index.vue
@@ -22,34 +22,44 @@
<div class="left-panel">
<!-- 瀹㈡埛淇℃伅缁熻鍒嗘瀽 -->
<div class="panel-header">
- <span class="panel-title">瀹㈡埛淇℃伅缁熻鍒嗘瀽</span>
+ <span class="panel-title">鍦ㄥ埗鍝佺粺璁″垎鏋�</span>
</div>
<div class="panel-item-customers">
- <div class="panel-title-second">
- <div class="panel-title-icon"></div>
- <div class="total-customers">
- <span class="label">鎬诲悎鍚岄噾棰�(鍏�)</span>
- <span class="value">{{sum}}</span>
+ <div class="quality-cards">
+ <div class="quality-cardSec">
+ <div class="quality-card one"></div>
+ <div class="quality-cardTitle">
+ <div>鎬诲湪鍒舵暟閲�</div>
+ <div>{{workInProcessStatistics.totalQuantity}}浠�</div>
+ </div>
</div>
-<!-- <div class="jiantou"></div>-->
+ <div class="quality-cardSec">
+ <div class="quality-card two"></div>
+ <div class="quality-cardTitle">
+ <div>骞冲潎鍛ㄨ浆澶╂暟</div>
+ <div>{{workInProcessStatistics.avgTurnoverDays}}澶�</div>
+ </div>
+ </div>
+ <div class="quality-cardSec">
+ <div class="quality-card three"></div>
+ <div class="quality-cardTitle">
+ <div>鍛ㄨ浆鏁堢巼</div>
+ <div>{{workInProcessStatistics.turnoverEfficiency}}%</div>
+ </div>
+ </div>
</div>
- <!-- 楗煎浘鍖哄煙 -->
- <div style="display: flex;align-items: center;gap: 20px;justify-content: space-evenly;height: 82%;margin-top: 20px">
- <div style="width: 240px; height: 240px; background-image: url('/src/assets/BI/zonghetongbingtubiankuang@2x.png'); background-size: contain; background-position: center; background-repeat: no-repeat; display: flex; align-items: center; justify-content: center;">
- <Echarts ref="chart" :legend="pieLegend" :chartStyle="chartStylePie"
- :series="materialPieSeries"
- :tooltip="pieTooltip"
- :options="{backgroundColor: 'transparent'}"
- style="margin-left: 5px;"></Echarts>
- </div>
- <ul class="contract-list" style="margin: 0; padding: 0; display: flex; flex-direction: column;justify-content: space-around; height: 100%; overflow-y: auto; scroll-behavior: smooth;" ref="refContractList">
- <li v-for="item in materialPieSeries[0].data" :key="item.name" style="list-style: none; margin-bottom: 12px;">
- <div style="display: flex;align-items: center;justify-content: space-between;width: 100%">
- <div class="line" :style="{color: item.itemStyle.color}">鈻� {{item.name}}</div>
- <div style="font-weight: 700;font-size: 16px;color: #85B1E4;">锟{item.value}}</div>
- </div>
- </li>
- </ul>
+ <!-- 宸ュ簭鍦ㄥ埗鍝佹暟閲忔煴鐘跺浘 -->
+ <div style="height: 82%;margin-top: 20px">
+ <Echarts ref="chart"
+ :chartStyle="chartStyle"
+ :grid="grid"
+ :legend="workInProcessBarLegend"
+ :series="workInProcessBarSeries"
+ :tooltip="tooltip"
+ :xAxis="workInProcessXAxis"
+ :yAxis="workInProcessYAxis"
+ :options="{backgroundColor: 'transparent', textStyle: {color: '#B8C8E0'}}"
+ style="height: 100%"></Echarts>
</div>
</div>
@@ -63,21 +73,21 @@
<div class="quality-cardSec">
<div class="quality-card one"></div>
<div class="quality-cardTitle">
- <div>鍘熸潗鏂欏凡妫�娴嬫暟</div>
+ <div>鍘熸潗鏂欐鏁�</div>
<div>{{qualityStatisticsObject.supplierNum}}浠�</div>
</div>
</div>
<div class="quality-cardSec">
<div class="quality-card two"></div>
<div class="quality-cardTitle">
- <div>杩囩▼妫�楠屾暟閲�</div>
+ <div>杩囩▼妫�鏁�</div>
<div>{{qualityStatisticsObject.processNum}}浠�</div>
</div>
</div>
<div class="quality-cardSec">
<div class="quality-card three"></div>
<div class="quality-cardTitle">
- <div>鍑哄巶宸叉鏁伴噺</div>
+ <div>鍑哄巶妫�鏁�</div>
<div>{{qualityStatisticsObject.factoryNum}}浠�</div>
</div>
</div>
@@ -179,20 +189,72 @@
</div>
<div class="main-panel">
<div class="panel-item-customers">
- <div class="event-header">
- <img src="@/assets/BI/shijianmingxiicon@2x.png" alt="鍥炬爣" class="event-icon" />
- <span class="event-title">缁忚惀鍒嗘瀽</span>
+ <div class="order-statistics-cards" style="margin-bottom: 0px;">
+ <div class="quality-cardSec">
+ <div class="quality-card four"></div>
+ <div class="quality-cardTitle">
+ <div>鎬昏鍗曟暟</div>
+ <div>{{orderStatisticsObject.totalOrderCount}}浠�</div>
+ </div>
+ </div>
+ <div class="quality-cardSec">
+ <div class="quality-card five"></div>
+ <div class="quality-cardTitle">
+ <div>鏈畬鎴愯鍗曟暟</div>
+ <div>{{orderStatisticsObject.uncompletedOrderCount}}浠�</div>
+ </div>
+ </div>
+ <div class="quality-cardSec">
+ <div class="quality-card six"></div>
+ <div class="quality-cardTitle">
+ <div>閮ㄥ垎瀹屾垚璁㈠崟鏁�</div>
+ <div>{{orderStatisticsObject.partialCompletedOrderCount}}浠�</div>
+ </div>
+ </div>
+ <div class="quality-cardSec">
+ <div class="quality-card seven"></div>
+ <div class="quality-cardTitle">
+ <div>宸插畬鎴愯鍗曟暟</div>
+ <div>{{orderStatisticsObject.completedOrderCount}}浠�</div>
+ </div>
+ </div>
</div>
- <Echarts ref="chart"
- :chartStyle="chartStyle"
- :grid="grid"
- :legend="barLegend1"
- :series="barSeries11"
- :tooltip="tooltip"
- :xAxis="xAxis3"
- :yAxis="yAxis3"
- :options="{backgroundColor: 'transparent', textStyle: {color: '#B8C8E0'}}"
- style="height: 170px"></Echarts>
+ <div class="progress-table-container" ref="progressTableRef" style="margin-top: 0px;" @scroll="handleTableScroll">
+ <table class="progress-table">
+ <thead>
+ <tr>
+ <th>鐢熶骇璁㈠崟鍙�</th>
+ <th>浜у搧鍚嶇О</th>
+ <th>瑙勬牸</th>
+ <th>闇�姹傛暟閲�</th>
+ <th>瀹屾垚鏁伴噺</th>
+ <th>瀹屾垚杩涘害</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr
+ v-for="(item, index) in progressTableData"
+ :key="index"
+ :ref="el => setRowRef(el, index)"
+ :class="{ 'row-under-header': isRowUnderHeader(index) }"
+ >
+ <td>{{ item.npsNo || '-' }}</td>
+ <td>{{ item.productCategory || '-' }}</td>
+ <td>{{ item.specificationModel || '-' }}</td>
+ <td>{{ item.quantity || 0 }}</td>
+ <td>{{ item.completeQuantity || 0 }}</td>
+ <td>
+ <el-progress
+ :percentage="calculateProgress(item)"
+ :color="progressColor(calculateProgress(item))"
+ :status="calculateProgress(item) >= 100 ? 'success' : ''"
+ :stroke-width="8"
+ />
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
</div>
</div>
</div>
@@ -253,7 +315,7 @@
getProgressStatistics,
getWorkInProcessTurnover
} from "@/api/viewIndex.js";
-import {staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js";
+import {staffOnJobListPage} from "@/api/personnelManagement/employeeRecord.js";
import {listCustomer} from "@/api/basicData/customerFile.js";
import {listSupplier} from "@/api/basicData/supplierManageFile.js";
import {getLedgerPage} from "@/api/equipmentManagement/ledger.js";
@@ -261,6 +323,7 @@
import {getUpkeepPage} from "@/api/equipmentManagement/upkeep.js";
import {measuringInstrumentListPage} from "@/api/equipmentManagement/measurementEquipment.js";
import {listPageAnalysis} from "@/api/financialManagement/expenseManagement.js";
+import {productOrderListPage} from "@/api/productionManagement/productionOrder.js";
// 鍏ㄥ睆鐩稿叧鐘舵��
const isFullscreen = ref(false);
@@ -288,11 +351,17 @@
const realtimeLineChartRef = ref(null)
const refContractList = ref(null)
const refTodoList = ref(null)
+const progressTableRef = ref(null)
const timerScroll = ref(null)
+const progressTableScrollTimer = ref(null)
+const isTableScrolling = ref(false)
+const tableScrollTimeout = ref(null)
+const tableRowRefs = ref([])
+const rowsUnderHeader = ref(new Set())
const chartStylePie = {
- width: '140%',
- height: '140%' // 璁剧疆鍥捐〃瀹瑰櫒鐨勯珮搴�
+ width: '100%',
+ height: '100%' // 璁剧疆鍥捐〃瀹瑰櫒鐨勯珮搴�
}
const materialPieSeries = ref([
{
@@ -336,6 +405,21 @@
supplierNum: 0,
processNum: 0,
factoryNum: 0,
+})
+
+// 璁㈠崟缁熻瀵硅薄
+const orderStatisticsObject = ref({
+ totalOrderCount: 0,
+ uncompletedOrderCount: 0,
+ partialCompletedOrderCount: 0,
+ completedOrderCount: 0,
+})
+
+// 鍦ㄥ埗鍝佸懆杞粺璁″璞�
+const workInProcessStatistics = ref({
+ totalQuantity: 0,
+ avgTurnoverDays: 0,
+ turnoverEfficiency: 0,
})
const chartStyle = {
width: '100%',
@@ -579,8 +663,83 @@
axisLabel: { color: '#B8C8E0' }
}]
+// 鍦ㄥ埗鍝佸伐搴忔煴鐘跺浘閰嶇疆
+const workInProcessXAxis = ref([{
+ type: 'category',
+ axisTick: { show: false },
+ axisLabel: { color: '#B8C8E0' },
+ data: []
+}])
+const workInProcessYAxis = [{
+ type: 'value',
+ axisLabel: { color: '#B8C8E0' },
+ name: ''
+}]
+const workInProcessBarLegend = {
+ show: false,
+ textStyle: { color: '#B8C8E0' },
+ data: []
+}
+const workInProcessBarSeries = ref([
+ {
+ name: '鍦ㄥ埗鍝佹暟閲�',
+ type: 'bar',
+ barWidth: 25, // 鍥哄畾鏌辩姸鍥惧搴︿负40px
+ barGap: 0,
+ emphasis: {
+ focus: 'series'
+ },
+ itemStyle: {
+ color: {
+ type: 'linear',
+ x: 0,
+ y: 0,
+ x2: 0,
+ y2: 1,
+ colorStops: [
+ { offset: 0, color: '#4EE4FF' },
+ { offset: 1, color: '#00A4ED' }
+ ]
+ }
+ },
+ label: {
+ show: true,
+ position: 'top',
+ color: '#B8C8E0'
+ },
+ data: []
+ }
+])
+
// 寰呭姙浜嬮」
const todoList = ref([])
+
+// 鐢熶骇璁㈠崟瀹屾垚杩涘害琛ㄦ牸鏁版嵁
+const progressTableData = ref([])
+
+// 璁$畻瀹屾垚杩涘害鐧惧垎姣�
+const calculateProgress = (item) => {
+ if (!item) return 0
+ // 浼樺厛浣跨敤completionStatus瀛楁
+ if (item.completionStatus !== undefined && item.completionStatus !== null) {
+ const percentage = Number(item.completionStatus)
+ if (isNaN(percentage)) return 0
+ return Math.min(Math.max(Math.round(percentage), 0), 100)
+ }
+ // 濡傛灉娌℃湁completionStatus锛屽垯鏍规嵁瀹屾垚鏁伴噺鍜岄渶姹傛暟閲忚绠�
+ if (!item.quantity || item.quantity === 0) return 0
+ const percentage = (item.completeQuantity || 0) / item.quantity * 100
+ return Math.min(Math.max(Math.round(percentage), 0), 100)
+}
+
+// 鏍规嵁杩涘害鐧惧垎姣旇繑鍥為鑹�
+const progressColor = (percentage) => {
+ const p = percentage || 0
+ if (p < 30) return "#f56c6c"
+ if (p < 50) return "#e6a23c"
+ if (p < 80) return "#409eff"
+ return "#67c23a"
+}
// 璁$畻缂╂斁姣斾緥
const calculateScale = () => {
@@ -635,6 +794,43 @@
}))
})
}
+// 鍦ㄥ埗鍝佸懆杞粺璁�
+const workInProcessTurnoverInfo = () => {
+ getWorkInProcessTurnover().then((res) => {
+ console.log("鍦ㄥ埗鍝佸懆杞粺璁℃暟鎹�:", res)
+
+ if (!res || !res.data) {
+ console.warn('鍦ㄥ埗鍝佸懆杞粺璁℃暟鎹负绌�')
+ return
+ }
+
+ // 浠庢帴鍙h幏鍙栫粺璁℃暟鎹�
+ workInProcessStatistics.value = {
+ totalQuantity: res.data.totalOrderCount || 0,
+ avgTurnoverDays: res.data.averageTurnoverDays || 0,
+ turnoverEfficiency: res.data.turnoverEfficiency || 0,
+ }
+
+ // 璁剧疆宸ュ簭鏌辩姸鍥炬暟鎹�
+ // X杞达細processDetails (宸ュ簭璇︽儏鏁扮粍)
+ // Y杞达細processQuantityDetails (宸ュ簭鏁伴噺璇︽儏鏁扮粍)
+ if (res.data.processDetails && Array.isArray(res.data.processDetails)) {
+ // 璁剧疆X杞存暟鎹紙宸ュ簭鍚嶇О锛�
+ workInProcessXAxis.value[0].data = res.data.processDetails
+ } else {
+ workInProcessXAxis.value[0].data = []
+ }
+
+ if (res.data.processQuantityDetails && Array.isArray(res.data.processQuantityDetails)) {
+ // 璁剧疆Y杞存暟鎹紙鍦ㄥ埗鍝佹暟閲忥級
+ workInProcessBarSeries.value[0].data = res.data.processQuantityDetails
+ } else {
+ workInProcessBarSeries.value[0].data = []
+ }
+ }).catch((error) => {
+ console.error('鑾峰彇鍦ㄥ埗鍝佸懆杞粺璁″け璐�:', error)
+ })
+}
// 璐ㄦ缁熻
const qualityStatisticsInfo = () => {
qualityStatistics().then((res) => {
@@ -651,6 +847,7 @@
}
// 鍚勭敓浜ц鍗曠殑瀹屾垚杩涘害缁熻
const progressStatisticsInfo = () => {
+ // 浠庣粺璁℃帴鍙h幏鍙栫粺璁℃暟鎹�
getProgressStatistics().then((res) => {
console.log("鐢熶骇璁㈠崟瀹屾垚杩涘害缁熻鏁版嵁:", res)
@@ -659,24 +856,22 @@
return
}
- // 璁剧疆X杞存暟鎹� - 浣跨敤鍒嗙被鍚嶇О
- xAxis3.value[0].data = ['宸插畬鎴愯繘搴︽暟', '鎬昏鍗曟暟', '鏈畬鎴愯鍗曟暟', '宸插畬鎴愯鍗曟暟']
-
- // 璁剧疆鍗曚釜绯诲垪鐨勬暟鎹� - 姣忎釜X杞村垎绫诲搴斾竴涓��
- if (barSeries11.value && barSeries11.value.length > 0) {
- barSeries11.value[0].data = [
- res.data.completedProgressCount || 0,
- res.data.totalOrderCount || 0,
- res.data.uncompletedOrderCount || 0,
- res.data.completedOrderCount || 0
- ]
+ // 浠庢帴鍙h幏鍙栫粺璁℃暟鎹�
+ orderStatisticsObject.value = {
+ totalOrderCount: res.data.totalOrderCount || 0,
+ uncompletedOrderCount: res.data.uncompletedOrderCount || 0,
+ partialCompletedOrderCount: res.data.partialCompletedOrderCount || 0,
+ completedOrderCount: res.data.completedOrderCount || 0
}
+ progressTableData.value = res.data.completedOrderDetails || []
+ // 閲嶇疆琛屽紩鐢�
+ tableRowRefs.value = []
+ rowsUnderHeader.value.clear()
- console.log('鍥捐〃鏁版嵁璁剧疆瀹屾垚:', {
- xAxis: xAxis3.value[0].data,
- series: barSeries11.value[0]?.data
+ // 鍦ㄨ幏鍙栧埌鏁版嵁鍚庯紝鍒濆鍖栨粴鍔ㄥ姛鑳�
+ nextTick(() => {
+ initProgressTableScroll()
})
-
}).catch((error) => {
console.error('鑾峰彇鐢熶骇璁㈠崟瀹屾垚杩涘害缁熻澶辫触:', error)
})
@@ -822,6 +1017,163 @@
// 鑷姩杞崲鍛ㄣ�佹湀銆佸搴︾殑瀹氭椂鍣�
const autoSwitchTimer = ref(null)
+
+// 璁剧疆琛屽紩鐢�
+const setRowRef = (el, index) => {
+ if (el) {
+ tableRowRefs.value[index] = el
+ }
+}
+
+// 鍒ゆ柇琛屾槸鍚﹀湪琛ㄥご涓嬫柟
+const isRowUnderHeader = (index) => {
+ return rowsUnderHeader.value.has(index)
+}
+
+// 澶勭悊琛ㄦ牸婊氬姩浜嬩欢
+const handleTableScroll = () => {
+ const tableContainer = progressTableRef.value
+ if (!tableContainer) return
+
+ const thead = tableContainer.querySelector('thead')
+ if (!thead) return
+
+ const theadHeight = thead.offsetHeight
+ const containerRect = tableContainer.getBoundingClientRect()
+ const containerTop = containerRect.top
+ const theadBottom = containerTop + theadHeight
+
+ // 娓呯┖涔嬪墠鐨勮褰�
+ rowsUnderHeader.value.clear()
+
+ // 妫�鏌ユ瘡涓�琛屾槸鍚﹀湪琛ㄥご涓嬫柟锛堣琛ㄥご閬尅锛�
+ tableRowRefs.value.forEach((row, index) => {
+ if (row) {
+ const rowRect = row.getBoundingClientRect()
+ const rowTop = rowRect.top
+ const rowBottom = rowRect.bottom
+
+ // 濡傛灉琛屼笌琛ㄥご鏈夐噸鍙狅紙琛屽湪琛ㄥご涓嬫柟琚伄鎸★級
+ // 琛岀殑椤堕儴鍦ㄨ〃澶村簳閮ㄤ笅鏂癸紝浣嗚鐨勫簳閮ㄥ湪琛ㄥご搴曢儴涓婃柟锛岃鏄庤閬尅
+ if (rowTop < theadBottom && rowBottom > containerTop) {
+ rowsUnderHeader.value.add(index)
+ }
+ }
+ })
+
+ // 娓呴櫎涔嬪墠鐨勫畾鏃跺櫒
+ if (tableScrollTimeout.value) {
+ clearTimeout(tableScrollTimeout.value)
+ }
+
+ // 婊氬姩鍋滄鍚庢竻绌烘贰鍖栨爣璁�
+ tableScrollTimeout.value = setTimeout(() => {
+ rowsUnderHeader.value.clear()
+ }, 150)
+}
+
+// 鍒濆鍖栫敓浜ц鍗曡繘搴﹁〃鏍兼粴鍔ㄥ姛鑳�
+const initProgressTableScroll = () => {
+ const tableContainer = progressTableRef.value
+ if (!tableContainer) return
+
+ // 娓呯悊涔嬪墠鐨勬粴鍔ㄥ姩鐢诲拰瀹氭椂鍣�
+ if (progressTableScrollTimer.value) {
+ cancelAnimationFrame(progressTableScrollTimer.value)
+ progressTableScrollTimer.value = null
+ }
+ if (tableContainer._pauseTimer) {
+ clearInterval(tableContainer._pauseTimer)
+ tableContainer._pauseTimer = null
+ }
+
+ const tbody = tableContainer.querySelector('tbody')
+ if (!tbody) return
+
+ // 娓呯悊涔嬪墠鍙兘瀛樺湪鐨勫厠闅嗚锛堜繚鐣欏師濮嬫暟鎹锛�
+ // 鍘熷鏁版嵁琛岀殑鏁伴噺搴旇绛変簬 progressTableData.value.length
+ const originalCount = progressTableData.value.length
+ const allRows = Array.from(tbody.querySelectorAll('tr'))
+ if (allRows.length > originalCount) {
+ // 绉婚櫎鎵�鏈夎秴杩囧師濮嬫暟閲忕殑琛岋紙杩欎簺鏄厠闅嗙殑琛岋級
+ for (let i = originalCount; i < allRows.length; i++) {
+ allRows[i].remove()
+ }
+ }
+
+ const scrollItems = Array.from(tbody.querySelectorAll('tr'))
+ if (scrollItems.length === 0) return
+
+ // 鑾峰彇鍘熷鏁版嵁椤规暟閲�
+ const originalItemCount = scrollItems.length
+
+ // 璁$畻瀹瑰櫒楂樺害鍜岃〃澶撮珮搴�
+ const thead = tableContainer.querySelector('thead')
+ const theadHeight = thead ? thead.offsetHeight : 40
+ const containerHeight = tableContainer.clientHeight
+ const visibleHeight = containerHeight - theadHeight
+
+ // 璁$畻鍘熷鏁版嵁鐨勬�婚珮搴�
+ const itemHeight = scrollItems[0]?.offsetHeight || 40
+ const totalContentHeight = itemHeight * originalItemCount
+
+ // 濡傛灉鏁版嵁閲忎笉澶燂紝瀹瑰櫒鍙互瀹屽叏鏄剧ず鎵�鏈夋暟鎹紝灏变笉闇�瑕佹粴鍔ㄥ拰鍏嬮殕
+ if (totalContentHeight <= visibleHeight) {
+ // 鏁版嵁閲忓皯锛屼笉闇�瑕佹粴鍔紝鐩存帴杩斿洖
+ return
+ }
+
+ // 鏁版嵁閲忚冻澶燂紝闇�瑕佹粴鍔紝杩涜鍏嬮殕浠ュ疄鐜版棤缂濇粴鍔�
+ const cloneCount = Math.ceil(visibleHeight / itemHeight) + 2
+
+ // 鍏嬮殕鍓嶅嚑涓」鐩苟娣诲姞鍒板垪琛ㄦ湯灏撅紝瀹炵幇鏃犵紳婊氬姩
+ for (let i = 0; i < cloneCount; i++) {
+ const clone = scrollItems[i % originalItemCount].cloneNode(true)
+ tbody.appendChild(clone)
+ }
+
+ let scrollPosition = 0
+ const scrollSpeed = 1.5
+ const pauseTime = 3000
+ let isPaused = false
+ let lastTimestamp = 0
+
+ // 杩炵画婊氬姩鍔ㄧ敾鍑芥暟
+ function scrollAnimation(timestamp) {
+ if (!lastTimestamp) lastTimestamp = timestamp
+ const deltaTime = timestamp - lastTimestamp
+ lastTimestamp = timestamp
+
+ if (!isPaused) {
+ scrollPosition += scrollSpeed * (deltaTime / 16)
+
+ // 璁$畻鏈�澶ф粴鍔ㄤ綅缃紙鍘熷鍐呭鐨勯珮搴︼級
+ const maxScroll = itemHeight * originalItemCount
+
+ // 褰撴粴鍔ㄨ秴杩囧師濮嬪唴瀹归暱搴︽椂锛岄噸缃綅缃疄鐜版棤缂濇粴鍔�
+ if (scrollPosition >= maxScroll) {
+ scrollPosition = 0
+ tableContainer.scrollTop = 0
+ } else {
+ tableContainer.scrollTop = scrollPosition
+ }
+ }
+
+ progressTableScrollTimer.value = requestAnimationFrame(scrollAnimation)
+ }
+
+ // 鍚姩婊氬姩鍔ㄧ敾
+ progressTableScrollTimer.value = requestAnimationFrame(scrollAnimation)
+
+ // 璁剧疆婊氬姩-鏆傚仠-婊氬姩鐨勫惊鐜晥鏋�
+ const pauseTimer = setInterval(() => {
+ isPaused = !isPaused
+ }, pauseTime)
+
+ // 娓呯悊瀹氭椂鍣�
+ tableContainer._pauseTimer = pauseTimer
+}
+
// 鍒濆鍖栧緟鍔炰簨椤瑰垪琛ㄦ粴鍔ㄥ姛鑳�
const initTodoListScroll = () => {
const todoList = refTodoList.value
@@ -1031,6 +1383,7 @@
window.addEventListener('webkitfullscreenchange', handleFullscreenChange)
window.addEventListener('MSFullscreenChange', handleFullscreenChange)
analysisCustomer()
+ workInProcessTurnoverInfo()
qualityStatisticsInfo()
// accountStatisticsInfo()
progressStatisticsInfo()
@@ -1072,6 +1425,25 @@
clearInterval(todoList._pauseTimer)
todoList._pauseTimer = null
}
+ }
+
+ // 娓呯悊鐢熶骇璁㈠崟杩涘害琛ㄦ牸鐨勫姩鐢诲拰瀹氭椂鍣�
+ const progressTable = progressTableRef.value
+ if (progressTable) {
+ if (progressTableScrollTimer.value) {
+ cancelAnimationFrame(progressTableScrollTimer.value)
+ progressTableScrollTimer.value = null
+ }
+ if (progressTable._pauseTimer) {
+ clearInterval(progressTable._pauseTimer)
+ progressTable._pauseTimer = null
+ }
+ }
+
+ // 娓呯悊琛ㄦ牸婊氬姩瀹氭椂鍣�
+ if (tableScrollTimeout.value) {
+ clearTimeout(tableScrollTimeout.value)
+ tableScrollTimeout.value = null
}
// 娓呯悊鑷姩杞崲鍛ㄣ�佹湀銆佸搴︾殑瀹氭椂鍣�
@@ -1272,7 +1644,33 @@
}
.quality-card.three {
background-image: url("@/assets/BI/chuchangyijianicon@2x.png");
-
+}
+
+/* 璁㈠崟缁熻鍗$墖鏍峰紡 */
+.order-statistics-cards {
+ display: flex;
+ gap: 12px;
+ width: 100%;
+ height: 94px;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 20px;
+}
+
+.quality-card.four {
+ background-image: url("@/assets/BI/yuancailiaoyijianicon@2x.png");
+}
+
+.quality-card.five {
+ background-image: url("@/assets/BI/guochengyijianicon@2x.png");
+}
+
+.quality-card.six {
+ background-image: url("@/assets/BI/chuchangyijianicon@2x.png");
+}
+
+.quality-card.seven {
+ background-image: url("@/assets/BI/yuancailiaoyijianicon@2x.png");
}
.panel-title-icon {
width: 60px;
@@ -1555,4 +1953,84 @@
border-color: rgba(255, 255, 255, 0.5);
box-shadow: -1px 0 0 0 rgba(255, 255, 255, 0.5);
}
+
+/* 鐢熶骇璁㈠崟杩涘害琛ㄦ牸鏍峰紡 */
+.progress-table-container {
+ height: 250px;
+ overflow-y: auto;
+ overflow-x: hidden;
+ margin-top: 10px;
+ scrollbar-width: none; /* Firefox */
+ -ms-overflow-style: none; /* IE鍜孍dge */
+}
+
+.progress-table-container::-webkit-scrollbar {
+ display: none; /* Chrome銆丼afari鍜孫pera */
+}
+
+.progress-table {
+ width: 100%;
+ border-collapse: collapse;
+ color: #B8C8E0;
+ font-size: 12px;
+ table-layout: fixed;
+}
+
+.progress-table thead {
+ position: sticky;
+ top: 0;
+ background-color: rgba(26, 88, 176, 0.9);
+ z-index: 10;
+}
+
+.progress-table th {
+ padding: 8px 6px;
+ text-align: left;
+ font-weight: 500;
+ border-bottom: 1px solid rgba(184, 200, 224, 0.3);
+ color: #B8C8E0;
+ font-size: 12px;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.progress-table th:nth-child(1) { width: 15%; } /* 鐢熶骇璁㈠崟鍙� */
+.progress-table th:nth-child(2) { width: 15%; } /* 浜у搧鍚嶇О */
+.progress-table th:nth-child(3) { width: 15%; } /* 瑙勬牸 */
+.progress-table th:nth-child(4) { width: 12%; } /* 闇�姹傛暟閲� */
+.progress-table th:nth-child(5) { width: 12%; } /* 瀹屾垚鏁伴噺 */
+.progress-table th:nth-child(6) { width: 31%; } /* 瀹屾垚杩涘害 */
+
+.progress-table td {
+ padding: 8px 6px;
+ border-bottom: 1px solid rgba(184, 200, 224, 0.1);
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ font-size: 12px;
+ transition: opacity 0.3s ease;
+}
+
+.progress-table tbody tr:hover {
+ background-color: rgba(184, 200, 224, 0.1);
+}
+
+.progress-table tbody tr.row-under-header {
+ opacity: 0.5;
+}
+
+/* el-progress 缁勪欢鏍峰紡璋冩暣 */
+.progress-table :deep(.el-progress) {
+ width: 100%;
+}
+
+.progress-table :deep(.el-progress-bar__outer) {
+ background-color: rgba(184, 200, 224, 0.2);
+}
+
+.progress-table :deep(.el-progress__text) {
+ color: #B8C8E0;
+ font-size: 11px;
+}
</style>
\ No newline at end of file
diff --git a/src/views/reportAnalysis/reportManagement/index.vue b/src/views/reportAnalysis/reportManagement/index.vue
index 2adfb54..4c73f7f 100644
--- a/src/views/reportAnalysis/reportManagement/index.vue
+++ b/src/views/reportAnalysis/reportManagement/index.vue
@@ -1,715 +1,1402 @@
<template>
- <div class="report-management">
- <!-- 绛涢�夋潯浠� -->
- <el-card class="filter-card" shadow="never">
- <el-form :model="filterForm" inline>
- <el-form-item label="鏃堕棿鑼冨洿">
- <el-date-picker
- style="width: 300px"
- v-model="filterForm.dateRange"
- type="daterange"
- range-separator="鑷�"
- start-placeholder="寮�濮嬫棩鏈�"
- end-placeholder="缁撴潫鏃ユ湡"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- @change="handleFilterChange"
- />
- </el-form-item>
- <el-form-item label="鎶ヨ〃绫诲瀷">
- <el-select v-model="filterForm.reportType" placeholder="璇烽�夋嫨鎶ヨ〃绫诲瀷" @change="handleFilterChange" style="width: 300px">
- <el-option label="鏍峰搧杩涘害鎶ヨ〃" value="sample" />
- <el-option label="璁惧浣跨敤鎶ヨ〃" value="equipment" />
- <el-option label="妫�娴嬮」鐩姤琛�" value="inspection" />
- <el-option label="棰嗙敤璁板綍鎶ヨ〃" value="usage" />
- </el-select>
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="handleFilterChange">鏌ヨ</el-button>
- <el-button @click="resetFilter">閲嶇疆</el-button>
- <el-button type="success" @click="exportReport">瀵煎嚭鎶ヨ〃</el-button>
- </el-form-item>
- </el-form>
- </el-card>
-
- <!-- 缁熻鍗$墖 -->
- <div class="statistics-cards">
- <el-row :gutter="20">
- <el-col :span="6">
- <el-card class="stat-card" shadow="hover">
- <div class="stat-content">
- <div class="stat-icon">
- <el-icon><Box /></el-icon>
- </div>
- <div class="stat-info">
- <div class="stat-number">{{ statistics.totalSamples }}</div>
- <div class="stat-label">鎬绘牱鍝佹暟</div>
- </div>
- </div>
- </el-card>
- </el-col>
- <el-col :span="6">
- <el-card class="stat-card" shadow="hover">
- <div class="stat-content">
- <div class="stat-icon">
- <el-icon><Tools /></el-icon>
- </div>
- <div class="stat-info">
- <div class="stat-number">{{ statistics.activeEquipment }}</div>
- <div class="stat-label">鍦ㄧ敤璁惧</div>
- </div>
- </div>
- </el-card>
- </el-col>
- <el-col :span="6">
- <el-card class="stat-card" shadow="hover">
- <div class="stat-content">
- <div class="stat-icon">
- <el-icon><Document /></el-icon>
- </div>
- <div class="stat-info">
- <div class="stat-number">{{ statistics.completedInspections }}</div>
- <div class="stat-label">宸插畬鎴愭娴�</div>
- </div>
- </div>
- </el-card>
- </el-col>
- <el-col :span="6">
- <el-card class="stat-card" shadow="hover">
- <div class="stat-content">
- <div class="stat-icon">
- <el-icon><ShoppingCart /></el-icon>
- </div>
- <div class="stat-info">
- <div class="stat-number">{{ statistics.totalUsage }}</div>
- <div class="stat-label">鎬婚鐢ㄦ鏁�</div>
- </div>
- </div>
- </el-card>
- </el-col>
- </el-row>
- </div>
-
- <!-- 鍥捐〃鍖哄煙 -->
- <div class="charts-container">
- <el-row :gutter="20">
- <!-- 鏍峰搧杩涘害鍥捐〃 -->
- <el-col :span="12">
- <el-card class="chart-card" shadow="hover">
- <template #header>
- <div class="card-header">
- <span>鏍峰搧杩涘害缁熻</span>
- <el-button link @click="refreshSampleChart">鍒锋柊</el-button>
- </div>
- </template>
- <div ref="sampleChartRef" class="chart-container"></div>
- </el-card>
- </el-col>
-
- <!-- 璁惧浣跨敤鍥捐〃 -->
- <el-col :span="12">
- <el-card class="chart-card" shadow="hover">
- <template #header>
- <div class="card-header">
- <span>璁惧浣跨敤鐜囩粺璁�</span>
- <el-button link @click="refreshEquipmentChart">鍒锋柊</el-button>
- </div>
- </template>
- <div ref="equipmentChartRef" class="chart-container"></div>
- </el-card>
- </el-col>
- </el-row>
-
- <el-row :gutter="20" style="margin-top: 20px;">
- <!-- 妫�娴嬮」鐩粺璁� -->
- <el-col :span="12">
- <el-card class="chart-card" shadow="hover">
- <template #header>
- <div class="card-header">
- <span>妫�娴嬮」鐩垎甯�</span>
- <el-button link @click="refreshInspectionChart">鍒锋柊</el-button>
- </div>
- </template>
- <div ref="inspectionChartRef" class="chart-container"></div>
- </el-card>
- </el-col>
-
- <!-- 棰嗙敤璁板綍瓒嬪娍 -->
- <el-col :span="12">
- <el-card class="chart-card" shadow="hover">
- <template #header>
- <div class="card-header">
- <span>棰嗙敤璁板綍瓒嬪娍</span>
- <el-button link @click="refreshUsageChart">鍒锋柊</el-button>
- </div>
- </template>
- <div ref="usageChartRef" class="chart-container"></div>
- </el-card>
- </el-col>
- </el-row>
- </div>
-
- <!-- 璇︾粏鏁版嵁琛ㄦ牸 -->
- <el-card class="table-card" shadow="hover">
- <template #header>
- <div class="card-header">
- <span>璇︾粏鏁版嵁</span>
- <div>
- <el-button type="primary" size="small" @click="refreshTable">鍒锋柊</el-button>
- <el-button type="success" size="small" @click="exportTable">瀵煎嚭</el-button>
- </div>
- </div>
- </template>
-
- <el-table
- :data="tableData"
- style="width: 100%"
- v-loading="tableLoading"
- stripe
- border
- >
- <el-table-column prop="id" label="缂栧彿" width="80" />
- <el-table-column prop="name" label="鍚嶇О" />
- <el-table-column prop="status" label="鐘舵��">
- <template #default="scope">
- <el-tag :type="getStatusType(scope.row.status)">
- {{ scope.row.status }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column prop="progress" label="杩涘害">
- <template #default="scope">
- <el-progress :percentage="scope.row.progress" :status="getProgressStatus(scope.row.progress)" />
- </template>
- </el-table-column>
- <el-table-column prop="createTime" label="鍒涘缓鏃堕棿" width="180" />
- <el-table-column prop="updateTime" label="鏇存柊鏃堕棿" width="180" />
- <el-table-column label="鎿嶄綔" width="150" fixed="right">
- <template #default="scope">
- <el-button link size="small" @click="viewDetail(scope.row)">鏌ョ湅</el-button>
- <el-button link size="small" @click="editItem(scope.row)">缂栬緫</el-button>
- </template>
- </el-table-column>
- </el-table>
-
- <div class="pagination-container">
- <el-pagination
- v-model:current-page="pagination.currentPage"
- v-model:page-size="pagination.pageSize"
- :page-sizes="[10, 20, 50, 100]"
- :total="pagination.total"
- layout="total, sizes, prev, pager, next, jumper"
- @size-change="handleSizeChange"
- @current-change="handleCurrentChange"
- />
- </div>
- </el-card>
- </div>
+ <div class="report-management">
+ <!-- 鍥捐〃鍖哄煙 -->
+ <div class="charts-container">
+ <el-row :gutter="20">
+ <!-- 鍚勭被鍨嬪畬鎴愭暟閲� -->
+ <el-col :span="9">
+ <el-card class="chart-card"
+ shadow="hover">
+ <template #header>
+ <div class="card-header">
+ <div class="chart-title-line"></div>
+ <span>鍚勭被鍨嬪畬鎴愭暟閲�</span>
+ </div>
+ </template>
+ <div class="top-container">
+ <div class="typeNum">
+ <div class="typeNum-left">
+ <img src="~@/assets/images/chartCard.svg"
+ alt="鍥捐〃"
+ style="width: 40px; height: 40px; object-fit: contain;">
+ <div class="typeNum-left-text">鍘熸潗鏂�</div>
+ </div>
+ <div class="typeNum-center">
+ <div class="typeNum-leftLine">-</div>
+ <div class="typeNum-rightLine"></div>
+ </div>
+ <div class="typeNum-right">
+ <div class="typeNum-right-top">
+ <div class="typeNum-right-top-name">鎬绘暟閲�</div>
+ <div class="typeNum-right-top-text">2099 <span class="unit">涓�</span></div>
+ </div>
+ <div class="typeNum-right-bottom">
+ <div class="typeNum-right-top-name">宸插畬鎴愭暟</div>
+ <div class="typeNum-right-top-text">2099 <span class="unit">涓�</span></div>
+ </div>
+ </div>
+ </div>
+ <div class="typeNum">
+ <div class="typeNum-left">
+ <img src="~@/assets/images/chartCard2.svg"
+ alt="鍥捐〃"
+ style="width: 40px; height: 40px; object-fit: contain;">
+ <div class="typeNum-left-text"
+ style="color: #5EB334;">鍗婃垚鍝�</div>
+ </div>
+ <div class="typeNum-center">
+ <div class="typeNum-leftLine2">-</div>
+ <div class="typeNum-rightLine2"></div>
+ </div>
+ <div class="typeNum-right">
+ <div class="typeNum-right-top">
+ <div class="typeNum-right-top-name">鎬绘暟閲�</div>
+ <div class="typeNum-right-top-text">2099 <span class="unit">涓�</span></div>
+ </div>
+ <div class="typeNum-right-bottom">
+ <div class="typeNum-right-top-name">宸插畬鎴愭暟</div>
+ <div class="typeNum-right-top-text">2099 <span class="unit">涓�</span></div>
+ </div>
+ </div>
+ </div>
+ <div class="typeNum">
+ <div class="typeNum-left">
+ <img src="~@/assets/images/chartCard3.svg"
+ alt="鍥捐〃"
+ style="width: 40px; height: 40px; object-fit: contain;">
+ <div class="typeNum-left-text"
+ style="color: #8000FF;">鎴愬搧</div>
+ </div>
+ <div class="typeNum-center">
+ <div class="typeNum-leftLine3">-</div>
+ <div class="typeNum-rightLine3"></div>
+ </div>
+ <div class="typeNum-right">
+ <div class="typeNum-right-top">
+ <div class="typeNum-right-top-name">鎬绘暟閲�</div>
+ <div class="typeNum-right-top-text">2099 <span class="unit">涓�</span></div>
+ </div>
+ <div class="typeNum-right-bottom">
+ <div class="typeNum-right-top-name">宸插畬鎴愭暟</div>
+ <div class="typeNum-right-top-text">2099 <span class="unit">涓�</span></div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </el-card>
+ </el-col>
+ <!-- 璐ㄦ鍚堟牸鐜� -->
+ <el-col :span="15">
+ <el-card class="chart-card"
+ shadow="hover">
+ <template #header>
+ <div class="card-header">
+ <div class="chart-title-line"></div>
+ <span>璐ㄦ鍚堟牸鐜�</span>
+ </div>
+ </template>
+ <div class="top-container flex-center">
+ <div class="quality-card blue-card">
+ <div class="quality-card-title">
+ <img src="~@/assets/images/chartCard.svg"
+ alt="鍘熸潗鏂�"
+ style="width: 24px; height: 24px; margin-right: 8px;">
+ 鍘熸潗鏂欏悎鏍肩巼
+ </div>
+ <div class="quality-card-content">
+ <div class="quality-item">
+ <div>
+ <div class="quality-item-label blue-label">瀹屾垚鐜�</div>
+ <div class="quality-item-tip">鍗犳瘮</div>
+ <div class="quality-item-value">80%</div>
+ </div>
+ <div class="quality-item-chart"
+ ref="materialCompletionChart"></div>
+ </div>
+ <div class="quality-item">
+ <div>
+ <div class="quality-item-label green-label">鍚堟牸鐜�</div>
+ <div class="quality-item-tip">鍗犳瘮</div>
+ <div class="quality-item-value">80%</div>
+ </div>
+ <div class="quality-item-chart"
+ ref="materialQualityChart"></div>
+ </div>
+ </div>
+ </div>
+ <div class="quality-card green-card">
+ <div class="quality-card-title">
+ <img src="~@/assets/images/chartCard2.svg"
+ alt="鍗婃垚鍝�"
+ style="width: 24px; height: 24px; margin-right: 8px;">
+ 鍗婃垚鍝佸悎鏍肩巼
+ </div>
+ <div class="quality-card-content">
+ <div class="quality-item">
+ <div>
+ <div class="quality-item-label blue-label">瀹屾垚鐜�</div>
+ <div class="quality-item-tip">鍗犳瘮</div>
+ <div class="quality-item-value">80%</div>
+ </div>
+ <div class="quality-item-chart"
+ ref="semiCompletionChart"></div>
+ </div>
+ <div class="quality-item">
+ <div>
+ <div class="quality-item-label green-label">鍚堟牸鐜�</div>
+ <div class="quality-item-tip">鍗犳瘮</div>
+ <div class="quality-item-value">80%</div>
+ </div>
+ <div class="quality-item-chart"
+ ref="semiQualityChart"></div>
+ </div>
+ </div>
+ </div>
+ <div class="quality-card purple-card">
+ <div class="quality-card-title">
+ <img src="~@/assets/images/chartCard3.svg"
+ alt="鎴愬搧"
+ style="width: 24px; height: 24px; margin-right: 8px;">
+ 鎴愬搧鍚堟牸鐜�
+ </div>
+ <div class="quality-card-content">
+ <div class="quality-item">
+ <div>
+ <div class="quality-item-label blue-label">瀹屾垚鐜�</div>
+ <div class="quality-item-tip">鍗犳瘮</div>
+ <div class="quality-item-value">80%</div>
+ </div>
+ <div class="quality-item-chart"
+ ref="finalCompletionChart"></div>
+ </div>
+ <div class="quality-item">
+ <div>
+ <div class="quality-item-label green-label">鍚堟牸鐜�</div>
+ <div class="quality-item-tip">鍗犳瘮</div>
+ <div class="quality-item-value">80%</div>
+ </div>
+ <div class="quality-item-chart"
+ ref="finalQualityChart"></div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </el-card>
+ </el-col>
+ </el-row>
+ </div>
+ <div class="charts-container">
+ <el-row :gutter="20">
+ <!-- 璐ㄦ鍚堟牸鐜� -->
+ <el-col :span="24">
+ <el-card class="chart-card"
+ shadow="hover">
+ <template #header>
+ <div class="card-header">
+ <div class="chart-title-line"></div>
+ <span>璐ㄦ鍚堟牸鐜�</span>
+ </div>
+ </template>
+ <div class="chart-container-line">
+ <div class="container-line-left">
+ <div style="height: 100%; width: 100%;"
+ ref="usageChartRef">
+ </div>
+ </div>
+ <div class="container-line-right">
+ <div style="height: 80%; width: 100%;"
+ ref="inspectionChartRef">
+ </div>
+ <div class="container-line-right-bottom">
+ <div class="inspection-chart-box">
+ <div class="chart-box-title">鍘熸潗鏂欐娊妫�鏁�</div>
+ <div class="chart-box-num">600</div>
+ </div>
+ <div class="inspection-chart-box">
+ <div class="chart-box-title">鍗婃垚鍝佹娊妫�鏁�</div>
+ <div class="chart-box-num">200</div>
+ </div>
+ <div class="inspection-chart-box">
+ <div class="chart-box-title">鎴愬搧鎶芥鏁�</div>
+ <div class="chart-box-num">200</div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <!-- </div> -->
+ <!-- <div ref="sampleChartRef"
+ class="chart-container"></div> -->
+ <div class="yearchange">
+ <div style="margin-right: 8px;font-size: 14px;">骞翠唤:</div>
+ <el-date-picker v-model="value3"
+ size="mini"
+ :clearable="false"
+ style="width: 60px;"
+ type="year"
+ :disabled-date="disabledDate"
+ placeholder="">
+ </el-date-picker>
+ </div>
+ </el-card>
+ </el-col>
+ </el-row>
+ </div>
+ <div class="charts-container">
+ <el-row :gutter="20">
+ <!-- 鏍峰搧杩涘害鍥捐〃 -->
+ <el-col :span="12">
+ <el-card class="chart-card"
+ shadow="hover">
+ <template #header>
+ <div class="card-header">
+ <div class="chart-title-line"></div>
+ <span>璐ㄩ噺瀹屾垚鏄庣粏</span>
+ </div>
+ </template>
+ <div ref="equipmentChartRef"
+ class="chart-container"></div>
+ </el-card>
+ </el-col>
+ <!-- 璁惧浣跨敤鍥捐〃 -->
+ <el-col :span="12">
+ <el-card class="chart-card"
+ shadow="hover">
+ <template #header>
+ <div class="card-header">
+ <div class="chart-title-line"></div>
+ <span>妫�娴嬮」鐩垎绫�</span>
+ </div>
+ </template>
+ <div class="chart-container-line">
+ <div class="container-line2-left">
+ <div class="info-box">
+ <div class="info-box-header">椤圭洰鍒嗗竷</div>
+ <div class="info-line">
+ <div class="info-icon"
+ style="background-color: #165DFF"></div>
+ <div class="info-line-title">鐗╃悊鎬ц兘</div>
+ <div class="info-line-value1">30%</div>
+ <div class="info-line-value2">300</div>
+ </div>
+ <div class="info-line">
+ <div class="info-icon"
+ style="background-color: #14C9C9;"></div>
+ <div class="info-line-title">鐗╃悊鎬ц兘</div>
+ <div class="info-line-value1">30%</div>
+ <div class="info-line-value2">300</div>
+ </div>
+ <div class="info-line">
+ <div class="info-icon"
+ style="background-color: #F7BA1E;"></div>
+ <div class="info-line-title">鐗╃悊鎬ц兘</div>
+ <div class="info-line-value1">30%</div>
+ <div class="info-line-value2">300</div>
+ </div>
+ <div class="info-line">
+ <div class="info-icon"
+ style="background-color: #722ED1;"></div>
+ <div class="info-line-title">鐗╃悊鎬ц兘</div>
+ <div class="info-line-value1">30%</div>
+ <div class="info-line-value2">300</div>
+ </div>
+ <div class="info-line">
+ <div class="info-icon"
+ style="background-color: #3491FA;"></div>
+ <div class="info-line-title">鐗╃悊鎬ц兘</div>
+ <div class="info-line-value1">30%</div>
+ <div class="info-line-value2">300</div>
+ </div>
+ </div>
+ </div>
+ <div ref="sampleChartRef"
+ style="height: 100%; width: 50%;"
+ class="chart-container"></div>
+ </div>
+ <!-- Tab 閫夋嫨鍣� -->
+ <div class="tab-selector">
+ <div class="tab-item"
+ :class="{ active: activeTab === 'raw' }"
+ @click="activeTab = 'raw'">鍘熸潗鏂�</div>
+ <div class="tab-item"
+ :class="{ active: activeTab === 'semi' }"
+ @click="activeTab = 'semi'">鍗婃垚鍝�</div>
+ <div class="tab-item"
+ :class="{ active: activeTab === 'final' }"
+ @click="activeTab = 'final'">鎴愬搧</div>
+ </div>
+ </el-card>
+ </el-col>
+ </el-row>
+ </div>
+ </div>
</template>
<script setup>
-import { ref, reactive, onMounted, nextTick } from 'vue'
-import { ElMessage, ElMessageBox } from 'element-plus'
-import * as echarts from 'echarts'
-import { Box, Tools, Document, ShoppingCart } from '@element-plus/icons-vue'
+ import { ref, reactive, onMounted, nextTick } from "vue";
+ import { ElMessage, ElMessageBox } from "element-plus";
+ import * as echarts from "echarts";
+ import { Box, Tools, Document, ShoppingCart } from "@element-plus/icons-vue";
-// 鍝嶅簲寮忔暟鎹�
-const filterForm = reactive({
- dateRange: [],
- reportType: 'sample'
-})
+ // 鍝嶅簲寮忔暟鎹�
+ const filterForm = reactive({
+ dateRange: [],
+ reportType: "sample",
+ });
-const statistics = reactive({
- totalSamples: 1250,
- activeEquipment: 45,
- completedInspections: 890,
- totalUsage: 2340
-})
+ const statistics = reactive({
+ totalSamples: 1250,
+ activeEquipment: 45,
+ completedInspections: 890,
+ totalUsage: 2340,
+ });
-const tableData = ref([])
-const tableLoading = ref(false)
-const pagination = reactive({
- currentPage: 1,
- pageSize: 20,
- total: 0
-})
+ const tableData = ref([]);
+ const tableLoading = ref(false);
+ const pagination = reactive({
+ currentPage: 1,
+ pageSize: 20,
+ total: 0,
+ });
-// 鍥捐〃寮曠敤
-const sampleChartRef = ref(null)
-const equipmentChartRef = ref(null)
-const inspectionChartRef = ref(null)
-const usageChartRef = ref(null)
+ // 鍒濆鍖栧勾浠戒负褰撳墠骞翠唤锛堜娇鐢―ate瀵硅薄锛�
+ const currentYear = new Date().getFullYear();
+ const value3 = ref(new Date(currentYear, 0, 1));
-// 鍥捐〃瀹炰緥
-let sampleChart = null
-let equipmentChart = null
-let inspectionChart = null
-let usageChart = null
+ // 闄愬埗鏃ユ湡閫夋嫨锛屼笉鍏佽閫夋嫨浠婂勾涔嬪悗鐨勫勾浠�
+ const disabledDate = time => {
+ const currentYear = new Date().getFullYear();
+ return time.getFullYear() > currentYear;
+ };
-// 鍒濆鍖栨暟鎹�
-const initData = () => {
- // 妯℃嫙琛ㄦ牸鏁版嵁
- tableData.value = [
- {
- id: 'SP001',
- name: '鏍峰搧A-001',
- type: '閲戝睘鏉愭枡',
- status: '妫�娴嬩腑',
- progress: 75,
- createTime: '2025-01-15 09:30:00',
- updateTime: '2025-01-20 14:20:00'
- },
- {
- id: 'SP002',
- name: '鏍峰搧B-002',
- type: '濉戞枡鍒跺搧',
- status: '宸插畬鎴�',
- progress: 100,
- createTime: '2025-01-10 10:15:00',
- updateTime: '2025-01-18 16:45:00'
- },
- {
- id: 'SP003',
- name: '鏍峰搧C-003',
- type: '鐢靛瓙鍏冧欢',
- status: '寰呮娴�',
- progress: 0,
- createTime: '2025-01-22 08:45:00',
- updateTime: '2025-01-22 08:45:00'
- },
- {
- id: 'EQ001',
- name: '妫�娴嬭澶嘇',
- type: '鍏夎氨浠�',
- status: '浣跨敤涓�',
- progress: 60,
- createTime: '2025-01-05 14:20:00',
- updateTime: '2025-01-20 11:30:00'
- },
- {
- id: 'EQ002',
- name: '妫�娴嬭澶嘊',
- type: '鏄惧井闀�',
- status: '绌洪棽',
- progress: 0,
- createTime: '2025-01-08 16:10:00',
- updateTime: '2025-01-19 09:15:00'
- }
- ]
-
- pagination.total = tableData.value.length
-}
+ // Tab 閫夋嫨鍣ㄥ綋鍓嶆縺娲婚」
+ const activeTab = ref("raw");
-// 鍒濆鍖栨牱鍝佽繘搴﹀浘琛�
-const initSampleChart = () => {
- if (sampleChartRef.value) {
- sampleChart = echarts.init(sampleChartRef.value)
- const option = {
- title: {
- show: false
- },
- tooltip: {
- trigger: 'item',
- formatter: '{a} <br/>{b}: {c} ({d}%)'
- },
- legend: {
- orient: 'vertical',
- left: 'left'
- },
- series: [
- {
- name: '鏍峰搧鐘舵��',
- type: 'pie',
- radius: ['40%', '70%'],
- avoidLabelOverlap: false,
- label: {
- show: false,
- position: 'center'
- },
- emphasis: {
- label: {
- show: true,
- fontSize: '18',
- fontWeight: 'bold'
- }
- },
- labelLine: {
- show: false
- },
- data: [
- { value: 450, name: '宸插畬鎴�' },
- { value: 320, name: '妫�娴嬩腑' },
- { value: 280, name: '寰呮娴�' },
- { value: 200, name: '宸叉殏鍋�' }
- ]
- }
- ]
- }
- sampleChart.setOption(option)
- }
-}
+ // 鍥捐〃寮曠敤
+ const sampleChartRef = ref(null);
+ const equipmentChartRef = ref(null);
+ const inspectionChartRef = ref(null);
+ const usageChartRef = ref(null);
-// 鍒濆鍖栬澶囦娇鐢ㄥ浘琛�
-const initEquipmentChart = () => {
- if (equipmentChartRef.value) {
- equipmentChart = echarts.init(equipmentChartRef.value)
- const option = {
- title: {
- show: false
- },
- tooltip: {
- trigger: 'axis',
- axisPointer: {
- type: 'shadow'
- }
- },
- xAxis: {
- type: 'category',
- data: ['鍏夎氨浠�', '鏄惧井闀�', '纭害璁�', '鎷夊姏鏈�', '鍐插嚮鏈�', '閲戠浉浠�']
- },
- yAxis: {
- type: 'value',
- name: '浣跨敤鐜�(%)'
- },
- series: [
- {
- name: '浣跨敤鐜�',
- type: 'bar',
- data: [85, 60, 75, 90, 45, 70],
- itemStyle: {
- color: function(params) {
- const colors = ['#409EFF', '#67C23A', '#E6A23C', '#F56C6C', '#909399', '#9C27B0']
- return colors[params.dataIndex]
- }
- }
- }
- ]
- }
- equipmentChart.setOption(option)
- }
-}
+ // 璐ㄦ鍚堟牸鐜囧浘琛ㄥ紩鐢�
+ const materialCompletionChart = ref(null);
+ const materialQualityChart = ref(null);
+ const semiCompletionChart = ref(null);
+ const semiQualityChart = ref(null);
+ const finalCompletionChart = ref(null);
+ const finalQualityChart = ref(null);
-// 鍒濆鍖栨娴嬮」鐩浘琛�
-const initInspectionChart = () => {
- if (inspectionChartRef.value) {
- inspectionChart = echarts.init(inspectionChartRef.value)
- const option = {
- title: {
- show: false
- },
- tooltip: {
- trigger: 'item'
- },
- legend: {
- orient: 'vertical',
- left: 'left'
- },
- series: [
- {
- name: '妫�娴嬮」鐩�',
- type: 'pie',
- radius: '50%',
- data: [
- { value: 335, name: '鐗╃悊鎬ц兘' },
- { value: 310, name: '鍖栧鍒嗘瀽' },
- { value: 234, name: '灏哄娴嬮噺' },
- { value: 135, name: '澶栬妫�鏌�' },
- { value: 148, name: '鍏朵粬妫�娴�' }
- ],
- emphasis: {
- itemStyle: {
- shadowBlur: 10,
- shadowOffsetX: 0,
- shadowColor: 'rgba(0, 0, 0, 0.5)'
- }
- }
- }
- ]
- }
- inspectionChart.setOption(option)
- }
-}
+ // 鍥捐〃瀹炰緥
+ let sampleChart = null;
+ let equipmentChart = null;
+ let inspectionChart = null;
+ let usageChart = null;
-// 鍒濆鍖栭鐢ㄨ褰曞浘琛�
-const initUsageChart = () => {
- if (usageChartRef.value) {
- usageChart = echarts.init(usageChartRef.value)
- const option = {
- title: {
- show: false
- },
- tooltip: {
- trigger: 'axis'
- },
- legend: {
- data: ['棰嗙敤娆℃暟', '褰掕繕娆℃暟']
- },
- xAxis: {
- type: 'category',
- boundaryGap: false,
- data: ['1鏈�', '2鏈�', '3鏈�', '4鏈�', '5鏈�', '6鏈�', '7鏈�', '8鏈�', '9鏈�', '10鏈�', '11鏈�', '12鏈�']
- },
- yAxis: {
- type: 'value'
- },
- series: [
- {
- name: '棰嗙敤娆℃暟',
- type: 'line',
- stack: 'Total',
- data: [120, 132, 101, 134, 90, 230, 210, 182, 191, 234, 290, 330]
- },
- {
- name: '褰掕繕娆℃暟',
- type: 'line',
- stack: 'Total',
- data: [110, 125, 95, 128, 85, 220, 200, 175, 185, 225, 280, 320]
- }
- ]
- }
- usageChart.setOption(option)
- }
-}
+ // 璐ㄦ鍚堟牸鐜囧浘琛ㄥ疄渚�
+ let materialCompletionChartInstance = null;
+ let materialQualityChartInstance = null;
+ let semiCompletionChartInstance = null;
+ let semiQualityChartInstance = null;
+ let finalCompletionChartInstance = null;
+ let finalQualityChartInstance = null;
-// 浜嬩欢澶勭悊鍑芥暟
-const handleFilterChange = () => {
- ElMessage.success('绛涢�夋潯浠跺凡鏇存柊')
- // 杩欓噷鍙互鏍规嵁绛涢�夋潯浠堕噸鏂板姞杞芥暟鎹�
-}
+ // 鍒濆鍖栨暟鎹�
+ const initData = () => {
+ // 妯℃嫙琛ㄦ牸鏁版嵁
+ tableData.value = [
+ {
+ id: "SP001",
+ name: "鏍峰搧A-001",
+ type: "閲戝睘鏉愭枡",
+ status: "妫�娴嬩腑",
+ progress: 75,
+ createTime: "2025-01-15 09:30:00",
+ updateTime: "2025-01-20 14:20:00",
+ },
+ {
+ id: "SP002",
+ name: "鏍峰搧B-002",
+ type: "濉戞枡鍒跺搧",
+ status: "宸插畬鎴�",
+ progress: 100,
+ createTime: "2025-01-10 10:15:00",
+ updateTime: "2025-01-18 16:45:00",
+ },
+ {
+ id: "SP003",
+ name: "鏍峰搧C-003",
+ type: "鐢靛瓙鍏冧欢",
+ status: "寰呮娴�",
+ progress: 0,
+ createTime: "2025-01-22 08:45:00",
+ updateTime: "2025-01-22 08:45:00",
+ },
+ {
+ id: "EQ001",
+ name: "妫�娴嬭澶嘇",
+ type: "鍘熸潗鏂�",
+ status: "浣跨敤涓�",
+ progress: 60,
+ createTime: "2025-01-05 14:20:00",
+ updateTime: "2025-01-20 11:30:00",
+ },
+ {
+ id: "EQ002",
+ name: "妫�娴嬭澶嘊",
+ type: "鍗婃垚鍝�",
+ status: "绌洪棽",
+ progress: 0,
+ createTime: "2025-01-08 16:10:00",
+ updateTime: "2025-01-19 09:15:00",
+ },
+ ];
-const resetFilter = () => {
- filterForm.dateRange = []
- filterForm.reportType = 'sample'
- ElMessage.info('绛涢�夋潯浠跺凡閲嶇疆')
-}
+ pagination.total = tableData.value.length;
+ };
-const exportReport = () => {
- ElMessage.success('鎶ヨ〃瀵煎嚭鍔熻兘寮�鍙戜腑...')
-}
+ // 鍒濆鍖栨牱鍝佽繘搴﹀浘琛�
+ const initSampleChart = () => {
+ if (sampleChartRef.value) {
+ sampleChart = echarts.init(sampleChartRef.value);
+ const option = {
+ title: {
+ show: false,
+ },
+ tooltip: {
+ trigger: "item",
+ formatter: "{a} <br/>{b}: {c} ({d}%)",
+ },
+ // legend: {
+ // orient: "vertical",
+ // left: "left",
+ // },
+ series: [
+ {
+ name: "鏍峰搧鐘舵��",
+ type: "pie",
+ radius: ["40%", "80%"],
+ avoidLabelOverlap: false,
+ label: {
+ show: false,
+ position: "center",
+ },
+ emphasis: {
+ label: {
+ show: true,
+ fontSize: "18",
+ fontWeight: "bold",
+ },
+ },
+ labelLine: {
+ show: false,
+ },
+ data: [
+ { value: 450, name: "宸插畬鎴�" },
+ { value: 320, name: "妫�娴嬩腑" },
+ { value: 280, name: "寰呮娴�" },
+ { value: 200, name: "宸叉殏鍋�" },
+ ],
+ },
+ ],
+ };
+ sampleChart.setOption(option);
+ }
+ };
-const refreshSampleChart = () => {
- initSampleChart()
- ElMessage.success('鏍峰搧杩涘害鍥捐〃宸插埛鏂�')
-}
+ // 鍒濆鍖栬澶囦娇鐢ㄥ浘琛�
+ const initEquipmentChart = () => {
+ if (equipmentChartRef.value) {
+ equipmentChart = echarts.init(equipmentChartRef.value);
+ const option = {
+ title: {
+ show: false,
+ },
+ tooltip: {
+ trigger: "axis",
+ axisPointer: {
+ type: "shadow",
+ },
+ },
+ grid: {
+ left: "1%",
+ right: "1%",
+ bottom: "1%",
+ containLabel: true,
+ },
+ legend: {
+ data: ["鍘熸潗鏂�", "鍗婃垚鍝�", "鎴愬搧"], // 鍥句緥鏁版嵁
+ icon: ["circle", "circle", "circle"],
+ itemWidth: 10, // 璁剧疆鍥炬爣瀹藉害
+ itemHeight: 10,
+ itemGap: 30,
+ right: 10,
+ },
+ xAxis: {
+ type: "category",
+ data: [
+ value3.value.getFullYear() + "-1",
+ value3.value.getFullYear() + "-2",
+ value3.value.getFullYear() + "-3",
+ value3.value.getFullYear() + "-4",
+ value3.value.getFullYear() + "-5",
+ value3.value.getFullYear() + "-6",
+ value3.value.getFullYear() + "-7",
+ value3.value.getFullYear() + "-8",
+ value3.value.getFullYear() + "-9",
+ value3.value.getFullYear() + "-10",
+ value3.value.getFullYear() + "-11",
+ value3.value.getFullYear() + "-12",
+ ], // 鏀逛负鍗佷簩涓湀
+ },
+ yAxis: {
+ type: "value",
+ name: "鏁�(涓�)",
+ },
+ series: [
+ {
+ name: "鍘熸潗鏂�",
+ type: "bar",
+ barWidth: "15%",
+ data: [85, 75, 80, 85, 90, 88, 92, 87, 89, 91, 93, 95],
+ itemStyle: {
+ color: "#409EFF",
+ },
+ },
+ {
+ name: "鍗婃垚鍝�",
+ type: "bar",
+ barWidth: "15%",
-const refreshEquipmentChart = () => {
- initEquipmentChart()
- ElMessage.success('璁惧浣跨敤鍥捐〃宸插埛鏂�')
-}
+ data: [60, 65, 70, 68, 72, 75, 78, 80, 79, 82, 84, 85],
+ itemStyle: {
+ color: "#67C23A",
+ },
+ },
+ {
+ name: "鎴愬搧",
+ type: "bar",
+ barWidth: "15%",
-const refreshInspectionChart = () => {
- initInspectionChart()
- ElMessage.success('妫�娴嬮」鐩浘琛ㄥ凡鍒锋柊')
-}
+ data: [75, 78, 80, 82, 85, 83, 86, 88, 87, 89, 90, 92],
+ itemStyle: {
+ color: "#E6A23C",
+ },
+ },
+ ],
+ };
+ equipmentChart.setOption(option);
+ }
+ };
-const refreshUsageChart = () => {
- initUsageChart()
- ElMessage.success('棰嗙敤璁板綍鍥捐〃宸插埛鏂�')
-}
+ // 鍒濆鍖栨娴嬮」鐩浘琛�
+ const initInspectionChart = () => {
+ if (inspectionChartRef.value) {
+ inspectionChart = echarts.init(inspectionChartRef.value);
+ const option = {
+ title: {
+ show: false,
+ },
+ tooltip: {
+ trigger: "item",
+ },
+ series: [
+ {
+ type: "pie",
+ radius: "80%",
+ data: [
+ { value: 335, name: "鍘熸潗鏂�", itemStyle: { color: "#1890FF" } },
+ { value: 310, name: "鍗婃垚鍝�", itemStyle: { color: "#F7BA1E" } },
+ { value: 234, name: "鎴愬搧", itemStyle: { color: "#14C9C9" } },
+ ],
+ emphasis: {
+ itemStyle: {
+ shadowBlur: 10,
+ shadowOffsetX: 0,
+ shadowColor: "rgba(0, 0, 0, 0.5)",
+ },
+ },
+ },
+ ],
+ };
+ inspectionChart.setOption(option);
+ }
+ };
-const refreshTable = () => {
- tableLoading.value = true
- setTimeout(() => {
- tableLoading.value = false
- ElMessage.success('琛ㄦ牸鏁版嵁宸插埛鏂�')
- }, 1000)
-}
+ // 鍒濆鍖栭鐢ㄨ褰曞浘琛�
+ const initUsageChart = () => {
+ // 妫�鏌ュ浘琛ㄥ鍣ㄦ槸鍚﹀瓨鍦�
+ if (usageChartRef.value) {
+ // 鍒濆鍖� ECharts 瀹炰緥
+ usageChart = echarts.init(usageChartRef.value);
+ // 閰嶇疆鍥捐〃閫夐」
+ const option = {
+ // 鏍囬閰嶇疆锛堥殣钘忥級
+ title: {
+ show: false,
+ },
-const exportTable = () => {
- ElMessage.success('琛ㄦ牸瀵煎嚭鍔熻兘寮�鍙戜腑...')
-}
+ // 缃戞牸閰嶇疆锛堣皟鏁磋竟璺濓級
+ grid: {
+ left: "1%",
+ right: "4%",
+ bottom: "3%",
+ top: "14%",
+ containLabel: true,
+ },
+ // 鎻愮ず妗嗛厤缃�
+ tooltip: {
+ trigger: "axis", // 瑙﹀彂绫诲瀷涓哄潗鏍囪酱瑙﹀彂
+ },
+ // 鍥句緥閰嶇疆
+ legend: {
+ data: ["鍘熸潗鏂�", "鍗婃垚鍝�", "鎴愬搧"], // 鍥句緥鏁版嵁
+ icon: ["circle", "circle", "circle"],
+ itemWidth: 10, // 璁剧疆鍥炬爣瀹藉害
+ itemHeight: 10,
+ itemGap: 30,
+ },
+ // X杞撮厤缃�
+ xAxis: {
+ type: "category", // 绫诲埆杞�
+ boundaryGap: false, // 鍧愭爣杞翠袱杈圭暀鐧界瓥鐣�
+ data: [
+ value3.value.getFullYear() + "-1",
+ value3.value.getFullYear() + "-2",
+ value3.value.getFullYear() + "-3",
+ value3.value.getFullYear() + "-4",
+ value3.value.getFullYear() + "-5",
+ value3.value.getFullYear() + "-6",
+ value3.value.getFullYear() + "-7",
+ value3.value.getFullYear() + "-8",
+ value3.value.getFullYear() + "-9",
+ value3.value.getFullYear() + "-10",
+ value3.value.getFullYear() + "-11",
+ value3.value.getFullYear() + "-12",
+ ], // X杞存暟鎹�
+ },
+ // Y杞撮厤缃�
+ yAxis: {
+ type: "value", // 鏁板�艰酱
+ name: "鍗曚綅锛�%",
+ },
+ // 绯诲垪鏁版嵁
+ series: [
+ {
+ name: "鍘熸潗鏂�", // 绯诲垪鍚嶇О
+ type: "line", // 鍥捐〃绫诲瀷涓烘姌绾垮浘
+ stack: "Total", // 鍫嗗彔鍚嶇О
+ symbol: "none",
+ itemStyle: {
+ color: "#1890FF", // 璁剧疆杩欐潯绾跨殑棰滆壊
+ },
+ data: [120, 132, 101, 134, 90, 230, 210, 182, 191, 234, 290, 330], // 棰嗙敤娆℃暟鏁版嵁
+ },
+ {
+ name: "鍗婃垚鍝�", // 绯诲垪鍚嶇О
+ type: "line", // 鍥捐〃绫诲瀷涓烘姌绾垮浘
+ stack: "Total", // 鍫嗗彔鍚嶇О
+ symbol: "none",
+ itemStyle: {
+ color: "#F7BA1E", // 璁剧疆杩欐潯绾跨殑棰滆壊
+ },
+ data: [110, 125, 95, 128, 85, 220, 200, 175, 185, 225, 280, 320], // 褰掕繕娆℃暟鏁版嵁
+ },
+ {
+ name: "鎴愬搧", // 绯诲垪鍚嶇О
+ type: "line", // 鍥捐〃绫诲瀷涓烘姌绾垮浘
+ stack: "Total", // 鍫嗗彔鍚嶇О
+ symbol: "none",
+ itemStyle: {
+ color: "#14C9C9", // 璁剧疆杩欐潯绾跨殑棰滆壊
+ },
+ data: [110, 125, 95, 128, 85, 220, 200, 175, 185, 225, 280, 320], // 褰掕繕娆℃暟鏁版嵁
+ },
+ ],
+ };
+ // 灏嗛厤缃簲鐢ㄥ埌鍥捐〃
+ usageChart.setOption(option);
+ }
+ };
-const handleSizeChange = (val) => {
- pagination.pageSize = val
- // 閲嶆柊鍔犺浇鏁版嵁
-}
+ // 鍒濆鍖栬川妫�鍚堟牸鐜囧浘琛�
+ const initQualityChart = (chartRef, color) => {
+ if (chartRef.value) {
+ const chart = echarts.init(chartRef.value);
+ const option = {
+ series: [
+ {
+ type: "pie",
+ radius: ["45%", "90%"],
+ itemStyle: {
+ borderColor: "#f5f5f5",
+ // borderWidth: 2,
+ },
+ labelLine: {
+ show: false,
+ },
+ data: [
+ { value: 0.8, itemStyle: { color: color } },
+ { value: 0.2, itemStyle: { color: "#f5f5f5" } },
+ ],
+ },
+ ],
+ };
+ chart.setOption(option);
+ return chart;
+ }
+ return null;
+ };
-const handleCurrentChange = (val) => {
- pagination.currentPage = val
- // 閲嶆柊鍔犺浇鏁版嵁
-}
+ // 鍒濆鍖栨墍鏈夎川妫�鍚堟牸鐜囧浘琛�
+ const initAllQualityCharts = () => {
+ materialCompletionChartInstance = initQualityChart(
+ materialCompletionChart,
+ "#1890ff"
+ );
+ materialQualityChartInstance = initQualityChart(
+ materialQualityChart,
+ "#52c41a"
+ );
+ semiCompletionChartInstance = initQualityChart(
+ semiCompletionChart,
+ "#1890ff"
+ );
+ semiQualityChartInstance = initQualityChart(semiQualityChart, "#52c41a");
+ finalCompletionChartInstance = initQualityChart(
+ finalCompletionChart,
+ "#1890ff"
+ );
+ finalQualityChartInstance = initQualityChart(finalQualityChart, "#722ed1");
+ };
-const getStatusType = (status) => {
- const statusMap = {
- '宸插畬鎴�': 'success',
- '妫�娴嬩腑': 'warning',
- '寰呮娴�': 'info',
- '宸叉殏鍋�': 'danger',
- '浣跨敤涓�': 'primary',
- '绌洪棽': 'info'
- }
- return statusMap[status] || 'info'
-}
+ // 浜嬩欢澶勭悊鍑芥暟
+ const handleFilterChange = () => {
+ ElMessage.success("绛涢�夋潯浠跺凡鏇存柊");
+ // 杩欓噷鍙互鏍规嵁绛涢�夋潯浠堕噸鏂板姞杞芥暟鎹�
+ };
-const getProgressStatus = (progress) => {
- if (progress === 100) return 'success'
- if (progress >= 80) return 'warning'
- if (progress >= 50) return ''
- return 'exception'
-}
+ const resetFilter = () => {
+ filterForm.dateRange = [];
+ filterForm.reportType = "sample";
+ ElMessage.info("绛涢�夋潯浠跺凡閲嶇疆");
+ };
-const viewDetail = (row) => {
- ElMessage.info(`鏌ョ湅璇︽儏: ${row.name}`)
-}
+ const exportReport = () => {
+ ElMessage.success("鎶ヨ〃瀵煎嚭鍔熻兘寮�鍙戜腑...");
+ };
-const editItem = (row) => {
- ElMessage.info(`缂栬緫椤圭洰: ${row.name}`)
-}
+ const refreshSampleChart = () => {
+ initSampleChart();
+ ElMessage.success("鏍峰搧杩涘害鍥捐〃宸插埛鏂�");
+ };
-// 鐢熷懡鍛ㄦ湡
-onMounted(() => {
- initData()
- nextTick(() => {
- initSampleChart()
- initEquipmentChart()
- initInspectionChart()
- initUsageChart()
- })
-
- // 鐩戝惉绐楀彛澶у皬鍙樺寲锛岄噸鏂拌皟鏁村浘琛ㄥぇ灏�
- window.addEventListener('resize', () => {
- sampleChart?.resize()
- equipmentChart?.resize()
- inspectionChart?.resize()
- usageChart?.resize()
- })
-})
+ const refreshEquipmentChart = () => {
+ initEquipmentChart();
+ ElMessage.success("璁惧浣跨敤鍥捐〃宸插埛鏂�");
+ };
+
+ const refreshInspectionChart = () => {
+ initInspectionChart();
+ ElMessage.success("妫�娴嬮」鐩浘琛ㄥ凡鍒锋柊");
+ };
+
+ const refreshUsageChart = () => {
+ initUsageChart();
+ ElMessage.success("棰嗙敤璁板綍鍥捐〃宸插埛鏂�");
+ };
+
+ const refreshTable = () => {
+ tableLoading.value = true;
+ setTimeout(() => {
+ tableLoading.value = false;
+ ElMessage.success("琛ㄦ牸鏁版嵁宸插埛鏂�");
+ }, 1000);
+ };
+
+ const exportTable = () => {
+ ElMessage.success("琛ㄦ牸瀵煎嚭鍔熻兘寮�鍙戜腑...");
+ };
+
+ const handleSizeChange = val => {
+ pagination.pageSize = val;
+ // 閲嶆柊鍔犺浇鏁版嵁
+ };
+
+ const handleCurrentChange = val => {
+ pagination.currentPage = val;
+ // 閲嶆柊鍔犺浇鏁版嵁
+ };
+
+ const getStatusType = status => {
+ const statusMap = {
+ 宸插畬鎴�: "success",
+ 妫�娴嬩腑: "warning",
+ 寰呮娴�: "info",
+ 宸叉殏鍋�: "danger",
+ 浣跨敤涓�: "primary",
+ 绌洪棽: "info",
+ };
+ return statusMap[status] || "info";
+ };
+
+ const getProgressStatus = progress => {
+ if (progress === 100) return "success";
+ if (progress >= 80) return "warning";
+ if (progress >= 50) return "";
+ return "exception";
+ };
+
+ const viewDetail = row => {
+ ElMessage.info(`鏌ョ湅璇︽儏: ${row.name}`);
+ };
+
+ const editItem = row => {
+ ElMessage.info(`缂栬緫椤圭洰: ${row.name}`);
+ };
+
+ // 鐢熷懡鍛ㄦ湡
+ onMounted(() => {
+ initData();
+ nextTick(() => {
+ initSampleChart();
+ initEquipmentChart();
+ initInspectionChart();
+ initUsageChart();
+ initAllQualityCharts();
+ });
+ // 鐩戝惉绐楀彛澶у皬鍙樺寲锛岄噸鏂拌皟鏁村浘琛ㄥぇ灏�
+ window.addEventListener("resize", () => {
+ sampleChart?.resize();
+ equipmentChart?.resize();
+ inspectionChart?.resize();
+ usageChart?.resize();
+
+ // 璋冩暣璐ㄦ鍚堟牸鐜囧浘琛ㄥぇ灏�
+ materialCompletionChartInstance?.resize();
+ materialQualityChartInstance?.resize();
+ semiCompletionChartInstance?.resize();
+ semiQualityChartInstance?.resize();
+ finalCompletionChartInstance?.resize();
+ finalQualityChartInstance?.resize();
+ });
+ });
</script>
<style scoped>
-.report-management {
- padding: 20px;
- background-color: #f5f5f5;
- min-height: 100vh;
-}
+ .report-management {
+ padding: 20px;
+ background-color: #f5f5f5;
+ min-height: 100vh;
+ /* height: 87vh;
+ overflow: hidden; */
+ }
-.page-header {
- margin-bottom: 20px;
- text-align: center;
-}
+ .page-header {
+ margin-bottom: 20px;
+ text-align: center;
+ }
-.page-header h2 {
- color: #303133;
- margin-bottom: 8px;
- font-size: 24px;
- font-weight: 600;
-}
+ .page-header h2 {
+ color: #303133;
+ margin-bottom: 8px;
+ font-size: 24px;
+ font-weight: 600;
+ }
-.page-header p {
- color: #909399;
- font-size: 14px;
- margin: 0;
-}
+ .page-header p {
+ color: #909399;
+ font-size: 14px;
+ margin: 0;
+ }
-.filter-card {
- margin-bottom: 20px;
-}
+ .filter-card {
+ margin-bottom: 20px;
+ }
-.statistics-cards {
- margin-bottom: 20px;
-}
+ .statistics-cards {
+ margin-bottom: 20px;
+ }
-.stat-card {
- height: 120px;
-}
+ .stat-card {
+ height: 120px;
+ }
-.stat-content {
- display: flex;
- align-items: center;
- height: 100%;
-}
+ .stat-content {
+ display: flex;
+ align-items: center;
+ height: 100%;
+ }
-.stat-icon {
- width: 60px;
- height: 60px;
- border-radius: 50%;
- display: flex;
- align-items: center;
- justify-content: center;
- margin-right: 20px;
- font-size: 24px;
- color: white;
-}
+ .stat-icon {
+ width: 60px;
+ height: 60px;
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ margin-right: 20px;
+ font-size: 24px;
+ color: white;
+ }
-.stat-card:nth-child(1) .stat-icon {
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
-}
+ .stat-card:nth-child(1) .stat-icon {
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+ }
-.stat-card:nth-child(2) .stat-icon {
- background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
-}
+ .stat-card:nth-child(2) .stat-icon {
+ background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
+ }
-.stat-card:nth-child(3) .stat-icon {
- background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
-}
+ .stat-card:nth-child(3) .stat-icon {
+ background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
+ }
-.stat-card:nth-child(4) .stat-icon {
- background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);
-}
+ .stat-card:nth-child(4) .stat-icon {
+ background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);
+ }
-.stat-info {
- flex: 1;
-}
+ .stat-info {
+ flex: 1;
+ }
-.stat-number {
- font-size: 28px;
- font-weight: bold;
- color: #303133;
- margin-bottom: 8px;
-}
+ .stat-number {
+ font-size: 28px;
+ font-weight: bold;
+ color: #303133;
+ margin-bottom: 8px;
+ }
-.stat-label {
- font-size: 14px;
- color: #909399;
-}
+ .stat-label {
+ font-size: 14px;
+ color: #909399;
+ }
-.charts-container {
- margin-bottom: 20px;
-}
+ .charts-container {
+ /* margin-bottom: 20px; */
+ position: relative;
+ }
-.chart-card {
- margin-bottom: 20px;
-}
+ .chart-card {
+ margin-bottom: 20px;
+ }
+ .container-line-right-bottom {
+ height: 20%;
+ width: 100%;
+ display: flex;
+ justify-content: space-evenly;
+ align-items: center;
+ /* background-color: #5b3f3f; */
+ }
+ .card-header {
+ display: flex;
+ justify-content: flex-start;
+ align-items: center;
+ font-family: Source Han Sans, Source Han Sans;
+ font-weight: 700;
+ font-size: 18px;
+ color: #000000;
+ /* line-height: 27px; */
+ text-align: left;
+ font-style: normal;
+ text-transform: none;
+ }
+ .chart-title-line {
+ width: 6px;
+ height: 22px;
+ background-color: #161a9a;
+ margin-right: 16px;
+ border-radius: 3px;
+ }
-.card-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
-}
+ .chart-container {
+ height: 250px;
+ width: 100%;
+ }
+ .chart-container-line {
+ height: 250px;
+ width: 100%;
+ display: flex;
+ position: relative;
+ }
-.chart-container {
- height: 300px;
- width: 100%;
-}
+ /* Tab 閫夋嫨鍣ㄦ牱寮� */
+ .tab-selector {
+ position: absolute;
+ top: 20px;
+ right: 40px;
+ display: flex;
+ border: 1px solid #dcdfe6;
+ border-radius: 4px;
+ overflow: hidden;
+ }
-.table-card {
- margin-bottom: 20px;
-}
+ .tab-item {
+ padding: 4px 12px;
+ cursor: pointer;
+ font-size: 14px;
+ color: #606266;
+ background-color: #fff;
+ border-right: 1px solid #dcdfe6;
+ transition: all 0.3s;
+ }
-.pagination-container {
- margin-top: 20px;
- text-align: right;
-}
+ .tab-item:last-child {
+ border-right: none;
+ }
-:deep(.el-card__header) {
- padding: 15px 20px;
- border-bottom: 1px solid #ebeef5;
- background-color: #fafafa;
-}
+ .tab-item:hover {
+ color: #409eff;
+ }
-:deep(.el-card__body) {
- padding: 20px;
-}
+ .tab-item.active {
+ color: #fff;
+ background-color: #409eff;
+ }
+ .container-line-left {
+ height: 100%;
+ width: 66%;
+ }
+ .container-line-right {
+ height: 100%;
+ width: 34%;
+ }
+ .container-line2-left {
+ height: 100%;
+ width: 50%;
+ }
+ .info-box {
+ width: 92%;
+ margin-left: 4%;
+ height: 100%;
+ background-color: #f7f8fa;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: space-around;
+ }
+ .info-box-header {
+ width: 100%;
+ margin-left: 20px;
+ color: #1d2129;
+ font-size: 16px;
+ font-weight: 500;
+ }
-:deep(.el-table) {
- margin-bottom: 20px;
-}
+ .info-line {
+ width: 100%;
+ display: flex;
+ padding-left: 20px;
+ align-items: center;
+ }
+ .info-icon {
+ width: 7px;
+ height: 7px;
+ border-radius: 50%;
+ margin-right: 8px;
+ }
+ .info-line-title {
+ font-size: 12px;
+ color: #4e5969;
+ flex: 1;
+ }
+ .info-line-value1 {
+ font-size: 12px;
+ color: #3d3d3d;
+ color: #1d2129;
+ font-weight: 500;
+ margin-right: 15%;
+ }
+ .info-line-value2 {
+ font-size: 12px;
+ color: #3d3d3d;
+ color: #1d2129;
+ font-weight: 500;
+ margin-right: 10%;
+ }
+ .top-container {
+ height: 130px;
+ width: 100%;
+ display: flex;
+ }
+ .typeNum {
+ height: 100%;
+ width: 33.33%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
+ .typeNum-left {
+ font-size: 12px;
+ color: #909399;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ }
+ .typeNum-left-text {
+ font-size: 12px;
+ color: #3491fa;
+ font-weight: 500;
+ margin-top: 5px;
+ }
+ .table-card {
+ margin-bottom: 20px;
+ }
+ .typeNum-center {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ margin-left: 10px;
+ }
+ .typeNum-leftLine {
+ color: #3491fa;
+ font-size: 12px;
+ }
+ .typeNum-rightLine {
+ border-top: 1px solid #3491fa;
+ border-left: 1px solid #3491fa;
+ border-bottom: 1px solid #3491fa;
+ height: 80px;
+ width: 8px;
+ }
+ .typeNum-leftLine2 {
+ color: #5eb334;
+ font-size: 12px;
+ }
+ .typeNum-rightLine2 {
+ border-top: 1px solid #3491fa;
+ border-left: 1px solid #5eb334;
+ border-bottom: 1px solid #5eb334;
+ height: 80px;
+ width: 8px;
+ }
+ .typeNum-leftLine3 {
+ color: #8000ff;
+ font-size: 12px;
+ }
+ .typeNum-rightLine3 {
+ border-top: 1px solid #8000ff;
+ border-left: 1px solid #8000ff;
+ border-bottom: 1px solid #8000ff;
+ height: 80px;
+ width: 8px;
+ }
+ .typeNum-right {
+ margin-left: 10px;
+ display: flex;
+ flex-direction: column;
+ height: 90%;
+ justify-content: space-between;
+ }
+ .typeNum-right-top-name {
+ font-weight: 400;
+ font-size: 12px;
+ color: #3d3d3d;
+ }
+ .typeNum-right-top-text {
+ font-weight: 400;
+ font-size: 16px;
+ color: rgba(0, 0, 0, 0.85);
+ margin-top: 5px;
+ }
+ .unit {
+ font-size: 12px;
+ color: #3d3d3d;
+ }
+ .inspection-chart-box {
+ height: 50px;
+ width: 30%;
+ background-color: #f7f8fa;
+ border-radius: 8px;
+ padding-left: 15px;
+ }
+ .chart-box-title {
+ font-size: 12px;
+ color: #4e5969;
+ margin-top: 5px;
+ }
+ .unit {
+ font-size: 12px;
+ color: #3d3d3d;
+ }
+ .chart-box-num {
+ font-size: 18px;
+ color: #000;
+ margin-top: 5px;
+ font-weight: 500;
+ }
+ /* 璐ㄦ鍚堟牸鐜囧崱鐗囨牱寮� */
+ .top-container鍚堟牸鐜� {
+ height: 130px;
+ width: 100%;
+ display: flex;
+ gap: 15px;
+ align-items: center;
+ justify-content: space-between;
+ }
+ .flex-center {
+ justify-content: space-evenly;
+ }
+ .quality-card {
+ /* flex: 1; */
+ width: 32%;
+ /* height: 100px; */
+ border-radius: 8px;
+ padding: 12px;
+ display: flex;
+ flex-direction: column;
+ }
-:deep(.el-progress) {
- margin: 0;
-}
+ .blue-card {
+ background-color: #e6f7ff;
+ }
-:deep(.el-tag) {
- margin: 0;
-}
+ .green-card {
+ background-color: #f6ffed;
+ color: #000000;
+ }
+
+ .purple-card {
+ background-color: #f9f0ff;
+ }
+
+ .quality-card-title {
+ font-size: 14px;
+ font-weight: 500;
+ margin-bottom: 10px;
+ display: flex;
+ align-items: center;
+ }
+
+ .quality-item-tip {
+ font-size: 12px;
+ color: #666666;
+ margin-bottom: 3px;
+ }
+ .blue-label {
+ color: #1890ff;
+ }
+ .green-label {
+ color: #52c41a;
+ }
+
+ .quality-card-title {
+ color: #000;
+ font-weight: bold;
+ }
+
+ .quality-card-content {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ flex: 1;
+ }
+
+ .quality-item {
+ display: flex;
+ /* flex-direction: column; */
+ align-items: center;
+ justify-content: center;
+ margin-top: 5px;
+ flex: 1;
+ }
+
+ .quality-item-label {
+ font-size: 12px;
+ /* color: #666; */
+ margin-bottom: 4px;
+ }
+
+ .quality-item-value {
+ font-size: 20px;
+ font-weight: 500;
+ margin-bottom: 4px;
+ }
+
+ .quality-item-chart {
+ width: 60px;
+ height: 60px;
+ margin-left: 10px;
+ }
+ /* .flex-center {
+ justify-content: space-evenly;
+ } */
+
+ .blue-chart {
+ /* background-color: rgba(24, 144, 255, 0.1); */
+ }
+
+ .green-chart {
+ /* background-color: rgba(82, 196, 26, 0.1); */
+ }
+
+ .purple-chart {
+ /* background-color: rgba(114, 46, 209, 0.1); */
+ }
+
+ .chart-ring {
+ width: 60px;
+ height: 60px;
+ border-radius: 50%;
+ border: 15px solid transparent;
+ position: relative;
+ }
+
+ .blue-chart .chart-ring {
+ border-top-color: #1890ff;
+ border-right-color: #1890ff;
+ border-bottom-color: #1890ff;
+ transform: rotate(45deg);
+ }
+
+ .green-chart .chart-ring {
+ border-top-color: #52c41a;
+ border-right-color: #52c41a;
+ border-bottom-color: #52c41a;
+ transform: rotate(45deg);
+ }
+
+ .purple-chart .chart-ring {
+ border-top-color: #722ed1;
+ border-right-color: #722ed1;
+ border-bottom-color: #722ed1;
+ transform: rotate(45deg);
+ }
+
+ .pagination-container {
+ margin-top: 20px;
+ text-align: right;
+ }
+ .yearchange {
+ position: absolute;
+ right: 40px;
+ top: 20px;
+ display: flex;
+ align-items: center;
+ /* width: 60px; */
+ }
+
+ :deep(.el-card__header) {
+ padding: 15px 20px;
+ border-bottom: 1px solid #ffffff;
+ background-color: #ffffff;
+ }
+
+ :deep(.el-card__body) {
+ padding: 20px;
+ }
+
+ :deep(.el-table) {
+ margin-bottom: 20px;
+ }
+
+ :deep(.el-progress) {
+ margin: 0;
+ }
+
+ :deep(.el-tag) {
+ margin: 0;
+ }
+ :deep(.el-input__prefix) {
+ display: none !important;
+ }
</style>
diff --git a/src/views/salesManagement/salesLedger/fileList.vue b/src/views/salesManagement/salesLedger/fileList.vue
new file mode 100644
index 0000000..da37db2
--- /dev/null
+++ b/src/views/salesManagement/salesLedger/fileList.vue
@@ -0,0 +1,43 @@
+<template>
+ <el-dialog v-model="dialogVisible" title="闄勪欢" width="40%" :before-close="handleClose">
+ <el-table :data="tableData" border height="40vh">
+ <el-table-column label="闄勪欢鍚嶇О" prop="name" min-width="400" show-overflow-tooltip />
+ <el-table-column fixed="right" label="鎿嶄綔" width="100" align="center">
+ <template #default="scope">
+ <el-button link type="primary" size="small" @click="downLoadFile(scope.row)">涓嬭浇</el-button>
+ <el-button link type="primary" size="small" @click="lookFile(scope.row)">棰勮</el-button>
+ </template>
+ </el-table-column>
+ </el-table>
+ </el-dialog>
+ <filePreview ref="filePreviewRef" />
+</template>
+
+<script setup>
+import { ref } from 'vue'
+import filePreview from '@/components/filePreview/index.vue'
+
+const dialogVisible = ref(false)
+const tableData = ref([])
+const { proxy } = getCurrentInstance();
+const filePreviewRef = ref()
+const handleClose = () => {
+ dialogVisible.value = false
+}
+const open = (list) => {
+ dialogVisible.value = true
+ tableData.value = list
+}
+const downLoadFile = (row) => {
+ proxy.$download.name(row.url);
+
+}
+const lookFile = (row) => {
+ filePreviewRef.value.open(row.url)
+}
+defineExpose({
+ open
+})
+</script>
+
+<style></style>
\ No newline at end of file
diff --git a/src/views/salesManagement/salesLedger/index.vue b/src/views/salesManagement/salesLedger/index.vue
index 141595d..54114f1 100644
--- a/src/views/salesManagement/salesLedger/index.vue
+++ b/src/views/salesManagement/salesLedger/index.vue
@@ -6,8 +6,16 @@
<el-input v-model="searchForm.customerName" placeholder="璇疯緭鍏�" clearable prefix-icon="Search"
@change="handleQuery" />
</el-form-item>
+ <el-form-item label="瀹㈡埛鍚堝悓鍙凤細">
+ <el-input v-model="searchForm.customerContractNo" placeholder="璇疯緭鍏�" clearable prefix-icon="Search"
+ @change="handleQuery" />
+ </el-form-item>
<el-form-item label="閿�鍞悎鍚屽彿锛�">
<el-input v-model="searchForm.salesContractNo" placeholder="璇疯緭鍏�" clearable prefix-icon="Search"
+ @change="handleQuery" />
+ </el-form-item>
+ <el-form-item label="椤圭洰鍚嶇О锛�">
+ <el-input v-model="searchForm.projectName" placeholder="璇疯緭鍏�" clearable prefix-icon="Search"
@change="handleQuery" />
</el-form-item>
<el-form-item label="褰曞叆鏃ユ湡锛�">
@@ -26,7 +34,6 @@
<el-button type="primary" @click="openForm('add')">
鏂板鍙拌处
</el-button>
- <el-button @click="handleImport">瀵煎叆</el-button>
<el-button @click="handleOut">瀵煎嚭</el-button>
<el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
<el-button type="primary" plain @click="handlePrint">鎵撳嵃</el-button>
@@ -34,7 +41,7 @@
</div>
<el-table :data="tableData" border v-loading="tableLoading" @selection-change="handleSelectionChange"
:expand-row-keys="expandedRowKeys" :row-key="(row) => row.id" show-summary style="width: 100%"
- :summary-method="summarizeMainTable" @expand-change="expandChange" height="calc(100vh - 21em)">
+ :summary-method="summarizeMainTable" @expand-change="expandChange" height="calc(100vh - 18.5em)">
<el-table-column align="center" type="selection" width="55" />
<el-table-column type="expand">
<template #default="props">
@@ -43,67 +50,72 @@
<el-table-column label="浜у搧澶х被" prop="productCategory" />
<el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" />
<el-table-column label="鍗曚綅" prop="unit" />
+ <el-table-column label="浜у搧鐘舵��" width="100px" align="center">
+ <template #default="scope">
+ <el-tag v-if="scope.row.approveStatus === 0" type="info">鏈嚭搴�</el-tag>
+ <el-tag v-if="scope.row.approveStatus === 1" type="success">宸插嚭搴�</el-tag>
+ <el-tag v-if="scope.row.approveStatus === 2" type="warning">瀹℃牳涓�</el-tag>
+ <el-tag v-if="scope.row.approveStatus === 3" type="success">瀹℃牳鎴愬姛</el-tag>
+ <el-tag v-if="scope.row.approveStatus === 4" type="danger">瀹℃牳澶辫触</el-tag>
+ </template>
+ </el-table-column>
+ <el-table-column label="鍙戣揣杞︾墝" minWidth="100px" align="center">
+ <template #default="scope">
+ <div>
+ <el-tag type="success" v-if="scope.row.shippingCarNumber">{{ scope.row.shippingCarNumber }}</el-tag>
+ <el-tag v-else type="info">鏈彂璐�</el-tag>
+ </div>
+ </template>
+ </el-table-column>
+ <el-table-column label="鍙戣揣鏃ユ湡" minWidth="100px" align="center">
+ <template #default="scope">
+ <div>
+ <div v-if="scope.row.shippingDate">{{ scope.row.shippingDate }}</div>
+ <el-tag v-else type="info">鏈彂璐�</el-tag>
+ </div>
+ </template>
+ </el-table-column>
<el-table-column label="鏁伴噺" prop="quantity" />
<el-table-column label="绋庣巼(%)" prop="taxRate" />
<el-table-column label="鍚◣鍗曚环(鍏�)" prop="taxInclusiveUnitPrice" :formatter="formattedNumber" />
<el-table-column label="鍚◣鎬讳环(鍏�)" prop="taxInclusiveTotalPrice" :formatter="formattedNumber" />
<el-table-column label="涓嶅惈绋庢�讳环(鍏�)" prop="taxExclusiveTotalPrice" :formatter="formattedNumber" />
+ <!--鎿嶄綔-->
+ <el-table-column Width="60px" label="鎿嶄綔" align="center">
+ <template #default="scope">
+ <el-button :disabled="scope.row.approveStatus!==2 || scope.row.approveStatus!==5" link type="primary" size="small" @click="openDeliveryForm(scope.row)">鍙戣揣</el-button>
+ </template>
+ </el-table-column>
</el-table>
</template>
</el-table-column>
<el-table-column align="center" label="搴忓彿" type="index" width="60" />
<el-table-column label="閿�鍞悎鍚屽彿" prop="salesContractNo" width="180" show-overflow-tooltip />
+ <el-table-column label="瀹㈡埛鍚堝悓鍙�" prop="customerContractNo" width="180" show-overflow-tooltip />
<el-table-column label="瀹㈡埛鍚嶇О" prop="customerName" width="300" show-overflow-tooltip />
<el-table-column label="涓氬姟鍛�" prop="salesman" width="100" show-overflow-tooltip />
+ <el-table-column label="椤圭洰鍚嶇О" prop="projectName" width="180" show-overflow-tooltip />
+ <el-table-column label="浠樻鏂瑰紡" prop="paymentMethod" show-overflow-tooltip />
<el-table-column label="鍚堝悓閲戦(鍏�)" prop="contractAmount" width="220" show-overflow-tooltip
:formatter="formattedNumber" />
<el-table-column label="褰曞叆浜�" prop="entryPersonName" width="100" show-overflow-tooltip />
- <el-table-column label="鐢熶骇鐘舵��" prop="productionStatus" width="100" show-overflow-tooltip >
- <template #default="scope">
- <div>
- <el-tag v-if="scope.row.productionStatus === '宸插畬鎴�'" type="success">宸插畬鎴�</el-tag>
- <el-tag v-if="scope.row.productionStatus === '鐢熶骇涓�'" type="warning">鐢熶骇涓�</el-tag>
- <el-tag v-if="scope.row.productionStatus === '鏈紑濮�'" type="danger">鏈紑濮�</el-tag>
- </div>
- </template>
- </el-table-column>
- <el-table-column label="鍙戣揣杞︾墝" prop="shippingCarNumber" width="120" show-overflow-tooltip>
- <template #default="scope">
- <div>
- <div v-if="scope.row.shippingCarNumber">{{ scope.row.shippingCarNumber }}</div>
- <el-tag v-else type="warning">鏈彂璐�</el-tag>
- </div>
- </template>
- </el-table-column>
- <el-table-column label="鍙戣揣鏃ユ湡" prop="shippingDate" width="120" show-overflow-tooltip />
- <el-table-column label="绛捐鏃ユ湡" prop="executionDate" width="120" show-overflow-tooltip />
<el-table-column label="褰曞叆鏃ユ湡" prop="entryDate" width="120" show-overflow-tooltip />
- <el-table-column fixed="right" label="鎿嶄綔" min-width="200" align="center">
+ <el-table-column label="绛捐鏃ユ湡" prop="executionDate" width="120" show-overflow-tooltip />
+ <el-table-column fixed="right" label="鎿嶄綔" min-width="100" align="center">
<template #default="scope">
<el-button link type="primary" size="small" @click="openForm('edit', scope.row)">缂栬緫</el-button>
<!-- <el-button link type="primary" size="small" @click="openForm('view', scope.row)">璇︽儏</el-button>-->
<el-button link type="primary" size="small" @click="downLoadFile(scope.row)">闄勪欢</el-button>
- <el-button v-if="!scope.row.shippingCarNumber" link type="primary" size="small" @click="openDeliveryForm(scope.row)">鍙戣揣</el-button>
+<!-- <el-button link type="primary" size="small" @click="openDeliveryForm(scope.row)">鍙戣揣</el-button>-->
</template>
</el-table-column>
</el-table>
<pagination v-show="total > 0" :total="total" layout="total, sizes, prev, pager, next, jumper"
:page="page.current" :limit="page.size" @pagination="paginationChange" />
</div>
- <FormDialog
- v-model="dialogFormVisible"
- :title="operationType === 'add' ? '鏂板閿�鍞彴璐﹂〉闈�' : '缂栬緫閿�鍞彴璐﹂〉闈�'"
- :width="'70%'"
- :operation-type="operationType"
- @close="closeDia"
- @confirm="submitForm"
- @cancel="closeDia">
+ <el-dialog v-model="dialogFormVisible" :title="operationType === 'add' ? '鏂板閿�鍞彴璐﹂〉闈�' : '缂栬緫閿�鍞彴璐﹂〉闈�'" width="70%"
+ @close="closeDia">
<el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
- <el-row v-if="operationType !== 'view'">
- <el-col :span="24" style="display:flex; justify-content:flex-end; gap:10px; margin-bottom: 6px;">
- <el-button type="primary" plain @click="openQuotationDialog">浠庡鎵归�氳繃鐨勬姤浠峰崟瀵煎叆</el-button>
- </el-col>
- </el-row>
<el-row :gutter="30">
<el-col :span="12">
<el-form-item label="閿�鍞悎鍚屽彿锛�" prop="salesContractNo">
@@ -112,9 +124,7 @@
</el-col>
<el-col :span="12">
<el-form-item label="涓氬姟鍛橈細" prop="salesman">
- <el-select v-model="form.salesman"
- filterable
- :reserve-keyword="false" placeholder="璇烽�夋嫨" clearable :disabled="operationType === 'view'">
+ <el-select v-model="form.salesman" placeholder="璇烽�夋嫨" clearable :disabled="operationType === 'view'">
<el-option v-for="item in userList" :key="item.nickName" :label="item.nickName"
:value="item.nickName" />
</el-select>
@@ -123,14 +133,26 @@
</el-row>
<el-row :gutter="30">
<el-col :span="12">
+ <el-form-item label="瀹㈡埛鍚堝悓鍙凤細" prop="customerContractNo">
+ <el-input v-model="form.customerContractNo" placeholder="璇疯緭鍏�" clearable :disabled="operationType === 'view'"/>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
<el-form-item label="瀹㈡埛鍚嶇О锛�" prop="customerId">
- <el-select v-model="form.customerId" placeholder="璇烽�夋嫨" clearable :disabled="operationType === 'view'" filterable>
+ <el-select v-model="form.customerId" placeholder="璇烽�夋嫨" clearable :disabled="operationType === 'view'">
<el-option v-for="item in customerOption" :key="item.id" :label="item.customerName" :value="item.id">
{{
item.customerName + "鈥斺��" + item.taxpayerIdentificationNumber
}}
</el-option>
</el-select>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="30">
+ <el-col :span="12">
+ <el-form-item label="椤圭洰鍚嶇О锛�" prop="projectName">
+ <el-input v-model="form.projectName" placeholder="璇疯緭鍏�" clearable :disabled="operationType === 'view'" />
</el-form-item>
</el-col>
<el-col :span="12">
@@ -143,10 +165,7 @@
<el-row :gutter="30">
<el-col :span="12">
<el-form-item label="褰曞叆浜猴細" prop="entryPerson">
- <el-select v-model="form.entryPerson"
- filterable
- default-first-option
- :reserve-keyword="false" placeholder="璇烽�夋嫨" clearable @change="changs">
+ <el-select v-model="form.entryPerson" placeholder="璇烽�夋嫨" clearable @change="changs" disabled>
<el-option v-for="item in userList" :key="item.userId" :label="item.nickName" :value="item.userId" />
</el-select>
</el-form-item>
@@ -158,7 +177,13 @@
</el-form-item>
</el-col>
</el-row>
-
+ <el-row :gutter="30">
+ <el-col :span="12">
+ <el-form-item label="浠樻鏂瑰紡">
+ <el-input v-model="form.paymentMethod" placeholder="璇疯緭鍏�" clearable :disabled="operationType === 'view'" />
+ </el-form-item>
+ </el-col>
+ </el-row>
<el-row>
<el-form-item label="浜у搧淇℃伅锛�" prop="entryDate">
<el-button v-if="operationType !== 'view'" type="primary" @click="openProductForm('add')">娣诲姞</el-button>
@@ -208,71 +233,14 @@
</el-col>
</el-row>
</el-form>
- </FormDialog>
-
- <!-- 浠庢姤浠峰崟瀵煎叆锛堜粎瀹℃壒閫氳繃锛� -->
- <el-dialog
- v-model="quotationDialogVisible"
- title="閫夋嫨瀹℃壒閫氳繃鐨勯攢鍞姤浠峰崟"
- width="80%"
- :close-on-click-modal="false"
- >
- <div style="margin-bottom: 12px; display:flex; gap: 12px; align-items:center;">
- <el-input
- v-model="quotationSearchForm.quotationNo"
- placeholder="璇疯緭鍏ユ姤浠峰崟鍙�"
- clearable
- style="max-width: 260px;"
- @change="fetchQuotationList"
- />
- <el-input
- v-model="quotationSearchForm.customer"
- placeholder="璇疯緭鍏ュ鎴峰悕绉�"
- clearable
- style="max-width: 260px;"
- @change="fetchQuotationList"
- />
- <el-button type="primary" @click="fetchQuotationList">鎼滅储</el-button>
- <el-button @click="resetQuotationSearch">閲嶇疆</el-button>
- </div>
-
- <el-table
- :data="quotationList"
- border
- stripe
- v-loading="quotationLoading"
- height="420px"
- >
- <el-table-column align="center" label="搴忓彿" type="index" width="60" />
- <el-table-column prop="quotationNo" label="鎶ヤ环鍗曞彿" width="180" show-overflow-tooltip />
- <el-table-column prop="customer" label="瀹㈡埛鍚嶇О" min-width="220" show-overflow-tooltip />
- <el-table-column prop="salesperson" label="涓氬姟鍛�" width="120" show-overflow-tooltip />
- <el-table-column prop="quotationDate" label="鎶ヤ环鏃ユ湡" width="140" />
- <el-table-column prop="status" label="瀹℃壒鐘舵��" width="120" align="center" />
- <el-table-column prop="totalAmount" label="鎶ヤ环閲戦(鍏�)" width="160" align="right">
- <template #default="scope">
- {{ Number(scope.row.totalAmount ?? 0).toFixed(2) }}
- </template>
- </el-table-column>
- <el-table-column fixed="right" label="鎿嶄綔" width="120" align="center">
- <template #default="scope">
- <el-button type="primary" link @click="applyQuotation(scope.row)">閫夋嫨</el-button>
- </template>
- </el-table-column>
- </el-table>
-
<template #footer>
- <el-button @click="quotationDialogVisible = false">鍏抽棴</el-button>
+ <div class="dialog-footer">
+ <el-button type="primary" @click="submitForm">纭</el-button>
+ <el-button @click="closeDia">鍙栨秷</el-button>
+ </div>
</template>
</el-dialog>
- <FormDialog
- v-model="productFormVisible"
- :title="productOperationType === 'add' ? '鏂板浜у搧' : '缂栬緫浜у搧'"
- :width="'40%'"
- :operation-type="productOperationType"
- @close="closeProductDia"
- @confirm="submitProduct"
- @cancel="closeProductDia">
+ <el-dialog v-model="productFormVisible" :title="productOperationType === 'add' ? '鏂板浜у搧' : '缂栬緫浜у搧'" width="40%" @close="closeProductDia">
<el-form :model="productForm" label-width="140px" label-position="top" :rules="productRules" ref="productFormRef">
<el-row :gutter="30">
<el-col :span="24">
@@ -288,7 +256,7 @@
<el-row :gutter="30">
<el-col :span="24">
<el-form-item label="瑙勬牸鍨嬪彿锛�" prop="productModelId">
- <el-select v-model="productForm.productModelId" placeholder="璇烽�夋嫨" clearable @change="getProductModel" filterable>
+ <el-select v-model="productForm.productModelId" placeholder="璇烽�夋嫨" clearable @change="getProductModel">
<el-option v-for="item in modelOptions" :key="item.id" :label="item.model" :value="item.id" />
</el-select>
</el-form-item>
@@ -349,7 +317,13 @@
</el-col>
</el-row>
</el-form>
- </FormDialog>
+ <template #footer>
+ <div class="dialog-footer">
+ <el-button type="primary" @click="submitProduct">纭</el-button>
+ <el-button @click="closeProductDia">鍙栨秷</el-button>
+ </div>
+ </template>
+ </el-dialog>
<!-- 鎵撳嵃棰勮寮圭獥 -->
<el-dialog
v-model="printPreviewVisible"
@@ -384,15 +358,12 @@
<span class="value">{{ formatDate(item.createTime) }}</span>
</div>
<div>
- <span class="label">鍙戣揣杞︾墝鍙凤細</span>
- <span class="value">{{ item.shippingCarNumber }}</span>
- </div>
- </div>
- <div class="info-row">
- <div>
+
<span class="label">瀹㈡埛鍚嶇О锛�</span>
<span class="value">{{ item.customerName || '寮犵埍鏈�' }}</span>
</div>
+ </div>
+ <div class="info-row">
<span class="label">鍗曞彿锛�</span>
<span class="value">{{ item.salesContractNo }}</span>
</div>
@@ -501,6 +472,15 @@
</el-form-item>
</el-col>
</el-row>
+ <el-row :gutter="30">
+ <el-col :span="24">
+ <el-form-item label="瀹℃壒浜猴細" prop="approverId">
+ <el-select v-model="deliveryForm.approverId" placeholder="璇烽�夋嫨瀹℃壒浜�" clearable :disabled="operationType === 'view'">
+ <el-option v-for="item in userList" :key="item.userId" :label="item.nickName" :value="item.userId" />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ </el-row>
</el-form>
<template #footer>
<div class="dialog-footer">
@@ -559,24 +539,21 @@
import { UploadFilled } from "@element-plus/icons-vue";
import useUserStore from "@/store/modules/user";
import { userListNoPage } from "@/api/system/user.js";
-import FileListDialog from '@/components/Dialog/FileListDialog.vue';
-import FormDialog from '@/components/Dialog/FormDialog.vue';
-import { getQuotationList } from "@/api/salesManagement/salesQuotation.js";
+import FileList from "./fileList.vue";
import {
- ledgerListPage,
- productList,
- customerList,
- addOrUpdateSalesLedger,
- getSalesLedgerWithProducts,
- delLedger,
- addOrUpdateSalesLedgerProduct,
- delProduct,
- delLedgerFile, getProductInventory,
+ ledgerListPage,
+ productList,
+ customerList,
+ addOrUpdateSalesLedger,
+ getSalesLedgerWithProducts,
+ delLedger,
+ addOrUpdateSalesLedgerProduct,
+ delProduct,
+ delLedgerFile, getProductInventory,
} from "@/api/salesManagement/salesLedger.js";
import { modelList, productTreeList } from "@/api/basicData/product.js";
import useFormData from "@/hooks/useFormData.js";
import dayjs from "dayjs";
-import { getCurrentDate } from "@/utils/index.js";
const userStore = useUserStore();
const { proxy } = getCurrentInstance();
@@ -602,7 +579,9 @@
const data = reactive({
searchForm: {
customerName: "", // 瀹㈡埛鍚嶇О
+ customerContractNo: "", // 瀹㈡埛鍚堝悓缂栧彿
salesContractNo: "", // 閿�鍞悎鍚岀紪鍙�
+ projectName: "", // 椤圭洰鍚嶇О
entryDate: null, // 褰曞叆鏃ユ湡
entryDateStart: undefined,
entryDateEnd: undefined,
@@ -610,16 +589,23 @@
form: {
salesContractNo: "",
salesman: "",
+ customerContractNo: "",
customerId: "",
+ projectName: "",
entryPerson: "",
entryDate: "",
maintenanceTime: "",
productData: [],
executionDate: "",
+ paymentMethod: "",
},
rules: {
salesman: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+ customerContractNo: [
+ { required: true, message: "璇疯緭鍏�", trigger: "blur" },
+ ],
customerId: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+ projectName: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
entryPerson: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
entryDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
executionDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
@@ -677,16 +663,6 @@
const printPreviewVisible = ref(false);
const printData = ref([]);
-// 鎶ヤ环鍗曞鍏ョ浉鍏�
-const quotationDialogVisible = ref(false);
-const quotationLoading = ref(false);
-const quotationList = ref([]);
-const quotationSearchForm = reactive({
- quotationNo: "",
- customer: "",
-});
-const selectedQuotation = ref(null);
-
// 鍙戣揣鐩稿叧
const deliveryFormVisible = ref(false);
const currentDeliveryRow = ref(null);
@@ -702,6 +678,11 @@
shippingCarNumber: [
{ required: true, message: "璇疯緭鍏ュ彂璐ц溅鐗屽彿", trigger: "blur" }
],
+ approverId:[
+ {
+ required: true,message: "",
+ }
+ ]
},
});
const { deliveryForm, deliveryRules } = toRefs(deliveryFormData);
@@ -768,11 +749,7 @@
// 鏌ヨ鍒楄〃
/** 鎼滅储鎸夐挳鎿嶄綔 */
const handleQuery = () => {
- // 鍙湁鍦ㄧ偣鍑绘悳绱㈡寜閽椂鎵嶉噸缃〉鐮佸埌绗竴椤�
- // 閬垮厤琛ㄥ崟瀛楁change浜嬩欢骞叉壈鍒嗛〉
- if (arguments.length === 0) {
- page.current = 1;
- }
+ page.current = 1;
expandedRowKeys.value = [];
getList();
};
@@ -781,14 +758,12 @@
page.size = obj.limit;
getList();
};
-const getList = () => {
+const getList =async () => {
+ let userLists = await userListNoPage();
+ userList.value = userLists.data;
tableLoading.value = true;
const { entryDate, ...rest } = searchForm;
- // 灏嗚寖鍥存棩鏈熷瓧娈典紶閫掔粰鍚庣
- const params = { ...rest, ...page };
- // 绉婚櫎褰曞叆鏃ユ湡鐨勯粯璁ゅ�艰缃紝鍙繚鐣欒寖鍥存棩鏈熷瓧娈�
- delete params.entryDate;
- ledgerListPage(params)
+ ledgerListPage({ ...rest, ...page })
.then((res) => {
tableLoading.value = false;
tableData.value = res.records;
@@ -803,12 +778,8 @@
};
// 鑾峰彇浜у搧澶х被tree鏁版嵁
const getProductOptions = () => {
- // 杩斿洖 Promise锛屼究浜庡湪缂栬緫浜у搧鏃剁瓑寰呭姞杞藉畬鎴�
- return productTreeList().then((res) => {
- // 鍏煎鎺ュ彛杩斿洖 { data: [] } 鎴栫洿鎺ヨ繑鍥炴暟缁�
- const list = Array.isArray(res) ? res : (res?.data ?? []);
- productOptions.value = convertIdToValue(list);
- return productOptions.value;
+ productTreeList().then((res) => {
+ productOptions.value = convertIdToValue(res);
});
};
const formattedNumber = (row, column, cellValue) => {
@@ -860,19 +831,6 @@
return newItem;
});
}
-// 鏍规嵁鍚嶇О鍙嶆煡浜у搧澶х被 id锛屼究浜庝粎瀛樺悕绉版椂鐨勫弽鏄�
-function findNodeIdByLabel(nodes, label) {
- if (!label) return null;
- for (let i = 0; i < nodes.length; i++) {
- const node = nodes[i];
- if (node.label === label) return node.value;
- if (node.children && node.children.length > 0) {
- const found = findNodeIdByLabel(node.children, label);
- if (found !== null && found !== undefined) return found;
- }
- }
- return null;
-}
// 琛ㄦ牸閫夋嫨鏁版嵁
const handleSelectionChange = (selection) => {
// 杩囨护鎺夊瓙鏁版嵁
@@ -883,23 +841,31 @@
productSelectedRows.value = selectedRows;
};
const expandedRowKeys = ref([]);
-// 灞曞紑琛�
-const expandChange = (row, expandedRows) => {
- if (expandedRows.length > 0) {
+// 灞曞紑琛岋紙濮嬬粓鍙睍寮�涓�琛岋級
+const expandChange = (row) => {
+ const rowKey = row.id;
+ const isExpanded = expandedRowKeys.value.includes(rowKey);
+
+ if (isExpanded) {
+ // 褰撳墠琛屽凡灞曞紑 -> 鏀惰捣
expandedRowKeys.value = [];
- try {
- productList({ salesLedgerId: row.id, type: 1 }).then((res) => {
- const index = tableData.value.findIndex((item) => item.id === row.id);
- if (index > -1) {
- tableData.value[index].children = res.data;
- }
- expandedRowKeys.value.push(row.id);
- });
- } catch (error) {
- console.log(error);
- }
- } else {
- expandedRowKeys.value = [];
+ return;
+ }
+
+ // 灞曞紑褰撳墠琛屽墠锛屽厛鏀惰捣鍏跺畠琛�
+ expandedRowKeys.value = [];
+
+ try {
+ productList({ salesLedgerId: row.id, type: 1 }).then((res) => {
+ const index = tableData.value.findIndex((item) => item.id === row.id);
+ if (index > -1) {
+ tableData.value[index].children = res.data;
+ }
+ // 鍙繚鐣欏綋鍓嶈繖涓�琛屽浜庡睍寮�鐘舵��
+ expandedRowKeys.value = [rowKey];
+ });
+ } catch (error) {
+ console.log(error);
}
};
// 涓昏〃鍚堣鏂规硶
@@ -923,19 +889,11 @@
operationType.value = type;
form.value = {};
productData.value = [];
- selectedQuotation.value = null;
- let userLists = await userListNoPage();
- userList.value = userLists.data;
customerList().then((res) => {
customerOption.value = res;
});
form.value.entryPerson = userStore.id;
- if (type === "add") {
- // 鏂板鏃惰缃綍鍏ユ棩鏈熶负褰撳ぉ
- form.value.entryDate = getCurrentDate();
- // 绛捐鏃ユ湡榛樿涓哄綋澶�
- form.value.executionDate = getCurrentDate();
- } else {
+ if (type !== "add") {
currentId.value = row.id;
getSalesLedgerWithProducts({ id: row.id, type: 1 }).then((res) => {
form.value = { ...res };
@@ -952,87 +910,6 @@
// });
form.value.entryDate = getCurrentDate(); // 璁剧疆榛樿褰曞叆鏃ユ湡涓哄綋鍓嶆棩鏈�
dialogFormVisible.value = true;
-};
-
-// 鎵撳紑鎶ヤ环鍗曢�夋嫨寮圭獥锛堜粎瀹℃壒閫氳繃锛�
-const openQuotationDialog = async () => {
- if (operationType.value === "view") return;
- quotationDialogVisible.value = true;
- // 鍏堢‘淇濆鎴峰垪琛ㄥ凡鍔犺浇锛屼究浜庡悗缁洖濉� customerId
- if (!customerOption.value || customerOption.value.length === 0) {
- try {
- const res = await customerList();
- customerOption.value = res;
- } catch (e) {
- // ignore锛屽厑璁哥敤鎴峰悗缁墜鍔ㄩ�夋嫨瀹㈡埛
- }
- }
- await fetchQuotationList();
-};
-
-const fetchQuotationList = async () => {
- quotationLoading.value = true;
- try {
- const params = {
- // 鍏煎鍚庣鍒嗛〉瀛楁锛氳繖閲屾部鐢ㄦ姤浠烽〉闈㈠凡鏈夊彲鐢ㄧ殑瀛楁鍛藉悕
- currentPage: 1,
- pageSize: 100,
- ...quotationSearchForm,
- status: "閫氳繃",
- };
- const res = await getQuotationList(params);
- quotationList.value = res?.data?.records || [];
- } finally {
- quotationLoading.value = false;
- }
-};
-
-const resetQuotationSearch = async () => {
- quotationSearchForm.quotationNo = "";
- quotationSearchForm.customer = "";
- await fetchQuotationList();
-};
-
-// 閫変腑鎶ヤ环鍗曞悗鍥炲~鍒板彴璐﹁〃鍗�
-const applyQuotation = (row) => {
- if (!row) return;
- selectedQuotation.value = row;
-
- // 涓氬姟鍛�
- form.value.salesman = row.salesperson || "";
-
- // 瀹㈡埛鍚嶇О -> customerId
- const customer = (customerOption.value || []).find((c) => c.customerName === row.customer);
- if (customer?.id) {
- form.value.customerId = customer.id;
- } else {
- // 濡傛灉鎵句笉鍒帮紝淇濈暀鍘熷�硷紙鍏佽鐢ㄦ埛鎵嬪姩閫夋嫨/涓嶆墦鏂凡鏈夎緭鍏ワ級
- form.value.customerId = form.value.customerId || "";
- }
-
- // 浜у搧淇℃伅鏄犲皠锛氭姤浠� products -> 鍙拌处 productData
- const products = Array.isArray(row.products) ? row.products : [];
- productData.value = products.map((p) => {
- const quantity = Number(p.quantity ?? 0) || 0;
- const unitPrice = Number(p.unitPrice ?? 0) || 0;
- const taxRate = "13"; // 榛樿 13%锛屼究浜庣洿鎺ユ彁浜わ紙濡傞渶鍙湪浜у搧涓嚜琛屼慨鏀癸級
- const taxInclusiveTotalPrice = (unitPrice * quantity).toFixed(2);
- const taxExclusiveTotalPrice = proxy.calculateTaxExclusiveTotalPrice(taxInclusiveTotalPrice, taxRate);
- return {
- // 鍙拌处瀛楁
- productCategory: p.product || p.productName || "",
- specificationModel: p.specification || "",
- unit: p.unit || "",
- quantity: quantity,
- taxRate: taxRate,
- taxInclusiveUnitPrice: unitPrice.toFixed(2),
- taxInclusiveTotalPrice: taxInclusiveTotalPrice,
- taxExclusiveTotalPrice: taxExclusiveTotalPrice,
- invoiceType: "澧炴櫘绁�",
- };
- });
-
- quotationDialogVisible.value = false;
};
function changs(val) {
console.log(val);
@@ -1106,7 +983,7 @@
const productIndex = ref(0);
// 鎵撳紑浜у搧寮规
-const openProductForm = async (type, row, index) => {
+const openProductForm =async (type, row,index) => {
productOperationType.value = type;
productForm.value = {};
proxy.resetForm("productFormRef");
@@ -1119,29 +996,9 @@
if (type === "edit") {
productForm.value = { ...row };
productIndex.value = index;
- // 缂栬緫鏃舵牴鎹骇鍝佸ぇ绫诲悕绉板弽鏌� tree 鑺傜偣 id锛屽苟鍔犺浇瑙勬牸鍨嬪彿鍒楄〃
- try {
- const options = productOptions.value && productOptions.value.length > 0
- ? productOptions.value
- : await getProductOptions();
- const categoryId = findNodeIdByLabel(options, productForm.value.productCategory);
- if (categoryId) {
- const models = await modelList({ id: categoryId });
- modelOptions.value = models || [];
- // 鏍规嵁褰撳墠瑙勬牸鍨嬪彿鍚嶇О鍙嶆煡骞惰缃� productModelId锛屼究浜庝笅鎷夋鏄剧ず宸查�夊��
- const currentModel = (modelOptions.value || []).find(
- (m) => m.model === productForm.value.specificationModel
- );
- if (currentModel) {
- productForm.value.productModelId = currentModel.id;
- }
- }
- } catch (e) {
- // 鍔犺浇澶辫触鏃朵繚鎸佸彲缂栬緫锛屼笉涓柇寮圭獥
- console.error("鍔犺浇浜у搧瑙勬牸鍨嬪彿澶辫触", e);
- }
}
productFormVisible.value = true;
+ getProductOptions();
};
// 鎻愪氦浜у搧琛ㄥ崟
const submitProduct = () => {
@@ -1597,6 +1454,15 @@
const seconds = String(date.getSeconds()).padStart(2, "0");
return `${year}/${month}/${day} ${hours}:${minutes}:${seconds}`;
};
+// 鑾峰彇褰撳墠鏃ユ湡骞舵牸寮忓寲涓� YYYY-MM-DD
+function getCurrentDate() {
+ const today = new Date();
+ const year = today.getFullYear();
+ const month = String(today.getMonth() + 1).padStart(2, "0"); // 鏈堜唤浠�0寮�濮�
+ const day = String(today.getDate()).padStart(2, "0");
+ return `${year}-${month}-${day}`;
+}
+
// 璁$畻浜у搧鎬绘暟閲�
const getTotalQuantity = (products) => {
if (!products || products.length === 0) return '0';
@@ -1809,28 +1675,20 @@
* @param row 涓嬭浇鏂囦欢鐨勭浉鍏充俊鎭璞�
*/
const fileListRef = ref(null)
-const fileListDialogVisible = ref(false)
const downLoadFile = (row) => {
getSalesLedgerWithProducts({ id: row.id, type: 1 }).then((res) => {
- if (fileListRef.value) {
- fileListRef.value.open(res.salesLedgerFiles)
- fileListDialogVisible.value = true
- }
+ fileListRef.value.open(res.salesLedgerFiles)
});
}
// 鎵撳紑鍙戣揣寮规
const openDeliveryForm = (row) => {
- getProductInventory({ salesLedgerId: row.id, type:1 }).then((res) => {
- currentDeliveryRow.value = row;
- deliveryForm.value = {
- shippingDate: getCurrentDate(),
- shippingCarNumber: "",
- };
- deliveryFormVisible.value = true;
- }).catch(err => {
- ElMessage.error(err.msg);
- });
+ currentDeliveryRow.value = row;
+ deliveryForm.value = {
+ shippingDate: "", // 绉婚櫎榛樿鍊艰缃�
+ shippingCarNumber: "",
+ };
+ deliveryFormVisible.value = true;
};
// 鎻愪氦鍙戣揣琛ㄥ崟
@@ -1838,7 +1696,9 @@
proxy.$refs["deliveryFormRef"].validate((valid) => {
if (valid) {
addShippingInfo({
- salesLedgerId: currentDeliveryRow.value.id,
+ approverId:deliveryForm.value.approverId,
+ salesLedgerId: currentDeliveryRow.value.salesLedgerId,
+ salesLedgerProductId: currentDeliveryRow.value.id,
shippingDate: deliveryForm.value.shippingDate,
shippingCarNumber: deliveryForm.value.shippingCarNumber,
})
@@ -1846,6 +1706,7 @@
proxy.$modal.msgSuccess("鍙戣揣鎴愬姛");
closeDeliveryDia();
getList();
+ expandedRowKeys.value = [];
})
.catch(() => {
proxy.$modal.msgError("鍙戣揣澶辫触锛岃閲嶈瘯");
--
Gitblit v1.9.3