From cde41517836da5403165b2f962ac842aa921fe95 Mon Sep 17 00:00:00 2001 From: shijing Date: Mon, 25 May 2026 15:33:19 +0800 Subject: [PATCH 01/50] =?UTF-8?q?feat:=E8=AE=BE=E5=A4=87=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E4=B8=80=E4=B8=AAcate=E7=9A=84=E7=AD=9B=E9=80=89=E6=9D=A1?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/em/equipment.vue | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/views/em/equipment.vue b/src/views/em/equipment.vue index c96e9958..05337b33 100644 --- a/src/views/em/equipment.vue +++ b/src/views/em/equipment.vue @@ -7,8 +7,11 @@
+ :show-all-levels="false" @change="handleQuery" style="width:180px"> + + +
@@ -38,7 +41,7 @@ - + @@ -195,6 +198,7 @@ export default { data() { return { runningStateEnum, + cateOptions:[], deptOptions: [], dialog: { save: false, @@ -247,9 +251,16 @@ export default { }; }, mounted() { - this.getDept() + this.getDept(); + this.getCateOptions(); }, methods: { + getCateOptions() { + let that = this; + that.$API.em.ecate.list.req({page:0,type:10}).then(res => { + that.cateOptions = res; + }) + }, //表格选择后回调事件 selectionChange(selection) { this.selectiones = selection; From e5670a267cc55a397187247af975a6a642ff473b Mon Sep 17 00:00:00 2001 From: shijing Date: Tue, 26 May 2026 09:23:34 +0800 Subject: [PATCH 02/50] =?UTF-8?q?fix:=E6=A0=B7=E5=BC=8F=E5=86=B2=E7=AA=81?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/wpm_bx/mlogb_form.vue | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/views/wpm_bx/mlogb_form.vue b/src/views/wpm_bx/mlogb_form.vue index 0f3be5d4..72c1f123 100644 --- a/src/views/wpm_bx/mlogb_form.vue +++ b/src/views/wpm_bx/mlogb_form.vue @@ -7,9 +7,8 @@ destroy-on-close @closed="$emit('closed')" > - - - + 提交 取消 - From c7d79b12df954a99183ba767512f3e7fefabcfef Mon Sep 17 00:00:00 2001 From: shijing Date: Tue, 26 May 2026 09:25:30 +0800 Subject: [PATCH 03/50] =?UTF-8?q?feat:wpr=E4=BF=9D=E5=AD=98=E5=B7=A5?= =?UTF-8?q?=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/wpm_bx/wprList.vue | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/views/wpm_bx/wprList.vue b/src/views/wpm_bx/wprList.vue index b22e1774..37baa74b 100644 --- a/src/views/wpm_bx/wprList.vue +++ b/src/views/wpm_bx/wprList.vue @@ -69,7 +69,7 @@ diff --git a/src/views/wpm_gx/mlog_form.vue b/src/views/wpm_gx/mlog_form.vue index ba0fede9..3cebe28e 100644 --- a/src/views/wpm_gx/mlog_form.vue +++ b/src/views/wpm_gx/mlog_form.vue @@ -6,265 +6,261 @@ style="width: 80%;" @closed="$emit('closed')" > - - - - - - + + + + + + + + + + + + - - - - - - - - - - [{{ item.routepack_name }}]{{ item.name }} - - - - - - - - - - - - - - - - - - - [{{ item.routepack_name }}]{{ item.name }} + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - {{item.name}} - {{item.number}} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 保存 - 取消 - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {{item.name}} + {{item.number}} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 保存 + 取消 + diff --git a/src/views/wpm_gx/mlogb_form.vue b/src/views/wpm_gx/mlogb_form.vue index d3bf8cba..8f98c24a 100644 --- a/src/views/wpm_gx/mlogb_form.vue +++ b/src/views/wpm_gx/mlogb_form.vue @@ -6,185 +6,181 @@ destroy-on-close @closed="$emit('closed')" > - - - - - - - - - [{{ item.routepack_name }}]{{ item.name }} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 保存 - 取消 - - + + + + + + + [{{ item.routepack_name }}]{{ item.name }} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 保存 + 取消 + From b66f71c2d53d8e5d65862c4677f24aa167451293 Mon Sep 17 00:00:00 2001 From: shijing Date: Wed, 17 Jun 2026 09:06:04 +0800 Subject: [PATCH 36/50] =?UTF-8?q?feat:=E5=B7=A5=E5=BA=8F=E4=BD=99=E6=96=99?= =?UTF-8?q?=E5=8F=AA=E6=98=BE=E7=A4=BAQS=E3=80=8132.2=E3=80=813D=E3=80=812?= =?UTF-8?q?.5D=E5=9B=9B=E7=A7=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/bigScreen/gxerp/index_com.vue | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/views/bigScreen/gxerp/index_com.vue b/src/views/bigScreen/gxerp/index_com.vue index 3938f194..c5f3346a 100644 --- a/src/views/bigScreen/gxerp/index_com.vue +++ b/src/views/bigScreen/gxerp/index_com.vue @@ -359,10 +359,12 @@ export default { let list = res.data2.ds0; if (list.length > 0) { list.forEach((item) => { - let arr = []; - arr[0] = item.物料名+'('+item.状态+')'; - arr[1] = item.数量; - that.configDataProcess.data.push(arr); + if(item.物料名.indexOf('QS')>-1||item.物料名.indexOf('32.2')>-1||item.物料名.indexOf('3D')>-1||item.物料名.indexOf('2.5D')>-1){ + let arr = []; + arr[0] = item.物料名+'('+item.状态+')'; + arr[1] = item.数量; + that.configDataProcess.data.push(arr); + } }) } }) @@ -471,7 +473,7 @@ export default { getMaterials(page) { let that = this; let query = '{ material_name, batch, count, count_working }'; - that.$API.wpm.wmaterial.list.req({ page: page, page_size: 500, mgroup: that.mgroupId, query: query }).then((res) => { + that.$API.wpm.wmaterial.list.req({ page: page, page_size: 100, mgroup: that.mgroupId, query: query }).then((res) => { if (res.results.length > 0) { res.results.forEach((item) => { let arr = []; @@ -481,6 +483,9 @@ export default { arr[3] = item.count_working; that.configDataInm.data.push(arr); }) + if(that.configDataInm.data.length Date: Wed, 17 Jun 2026 16:07:33 +0800 Subject: [PATCH 37/50] =?UTF-8?q?feat=EF=BC=9A=E5=85=89=E5=AD=90=E9=94=80?= =?UTF-8?q?=E5=94=AE=E5=8F=91=E8=B4=A7mioitems=E5=88=9B=E5=BB=BA=E6=97=B6?= =?UTF-8?q?=E5=8F=AF=E4=BB=A5=E6=89=B9=E6=AC=A1=E5=88=9B=E5=BB=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/inm/mioitem_form.vue | 44 +++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/src/views/inm/mioitem_form.vue b/src/views/inm/mioitem_form.vue index 7ee5c7b8..1f52f301 100644 --- a/src/views/inm/mioitem_form.vue +++ b/src/views/inm/mioitem_form.vue @@ -90,6 +90,7 @@ v-model="selectBatch" value-key="id" clearable + :multiple="project_code=='gz'&&form.type == 'sale_out'" filterable remote = "true" :style="divStyle" @@ -581,6 +582,13 @@ export default { that.form.count = Number(that.selectObj.count_canmio); that.mTracking = that.selectObj.material_.tracking; that.selectBatchChange(that.selectObj) + }else if(that.type == "sale_out"&&that.project_code=='gz'){ + that.form.material = that.selectObj.id; + that.form.unit = that.selectObj.unit; + that.form.unit_price = that.selectObj.unit_price; + that.mTracking = that.selectObj.tracking; + that.selectBatch = []; + that.getBatchOptions(); }else{ var type = this.form.type; that.form.material = that.selectObj.id; @@ -616,6 +624,26 @@ export default { let that = this; that.wprList = []; that.mioitems = []; + // gz 销售发货:多选批次 + if(that.form.type == 'sale_out' && that.project_code == 'gz' && Array.isArray(items)){ + if(items.length === 0){ + that.form.batch = ""; + that.form.mb = ""; + that.form.count = 0; + that.batchcount = 0; + that.form.warehouse = ""; + that.inputBatchDisable = false; + return; + } + let totalCount = items.reduce((sum, it) => sum + Number(it.count_canmio || 0), 0); + that.form.batch = items.map(it => it.batch).join(','); + that.form.mb = items.map(it => it.id).join(','); + that.form.count = totalCount; + that.batchcount = totalCount; + that.form.warehouse = items[0].warehouse; + that.inputBatchDisable = true; + return; + } if(items){ if(that.form.type == 'sale_out'&&that.project_code=='bxerp'){ let count = 0; @@ -876,7 +904,21 @@ export default { try { let res; if (that.mode == "add") { - res = await that.$API.inm.mioitem.create.req(that.form); + if(that.form.type == 'sale_out' && that.project_code == 'gz' && Array.isArray(that.selectBatch) && that.selectBatch.length > 0){ + let payload = that.selectBatch.map(b => ({ + mio: that.mioId, + material: that.form.material, + batch: b.batch, + mb: b.id, + count: Number(b.count_canmio), + warehouse: b.warehouse, + unit_price: that.form.unit_price, + note: that.form.note || '' + })); + res = await that.$API.inm.mioitem.create.req(payload); + } else { + res = await that.$API.inm.mioitem.create.req(that.form); + } } else if (that.mode == "edit") { res = await that.$API.inm.mioitem.update.req(that.form.id,that.form); } From 789d8552399422fcec19298b27e431491574f9c1 Mon Sep 17 00:00:00 2001 From: shijing Date: Thu, 18 Jun 2026 10:19:15 +0800 Subject: [PATCH 38/50] =?UTF-8?q?fix:=E5=85=89=E5=AD=90=E5=A4=A7=E5=B1=8F?= =?UTF-8?q?=E5=86=85=E5=AD=98=E6=B3=84=E9=9C=B2=E9=9A=90=E8=97=8F=E9=97=AE?= =?UTF-8?q?=E9=A2=98=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/bigScreen/index_photon.vue | 153 +++++++++++++++++++-------- 1 file changed, 106 insertions(+), 47 deletions(-) diff --git a/src/views/bigScreen/index_photon.vue b/src/views/bigScreen/index_photon.vue index 7eceb216..11aa755a 100644 --- a/src/views/bigScreen/index_photon.vue +++ b/src/views/bigScreen/index_photon.vue @@ -463,10 +463,21 @@ export default { percentage: 100, count_guan: 0, }, + isUnmounted: false, + pieChart: null, + line1Chart: null, + line2Chart: null, + line3Chart: null, + bar1Chart: null, + onResize: null, + onCanvasMouseMove: null, + onCanvasClick: null, + canvasEl: null, }; }, mounted() { loadBabylon().then(() => { + if (this.isUnmounted) return; this.initView(); }) }, @@ -536,27 +547,22 @@ export default { that.showTime(); }, 1000); that.notokTimer = setInterval(() => { + if (that.isUnmounted) return; let pieDom = document.getElementById("pie"); - if (pieDom) { - if (that.deptName == "10车间") { - that.deptName = "7车间"; - } else { - that.deptName = "10车间"; - } - let deptData = []; - if (that.deptName == "7车间") { - deptData = that.dept7Data; - } else { - deptData = that.dept10Data; - } - that.pieoption.series.data = deptData; - let pieoption = that.pieoption; - - let pieChart = echarts.init(pieDom); - pieChart.clear(); - pieChart.setOption(pieoption, true); + if (!pieDom) return; + if (that.deptName == "10车间") { + that.deptName = "7车间"; + } else { + that.deptName = "10车间"; } - }, 5000); + let deptData = + that.deptName == "7车间" ? that.dept7Data : that.dept10Data; + that.pieoption.series.data = deptData; + if (!that.pieChart || that.pieChart.isDisposed()) { + that.pieChart = echarts.init(pieDom); + } + that.pieChart.setOption(that.pieoption, true); + }, 60000); that.timerData = setInterval(() => { that.getDeptDetail(); }, 60000); @@ -592,8 +598,12 @@ export default { that.getCountDept7(); //左1---本周交付数 let chartDom = document.getElementById("line1"); + if (!chartDom) return; chartDom.style.height = this.blockHeight; - let myChart = echarts.init(chartDom); + if (!that.line1Chart || that.line1Chart.isDisposed()) { + that.line1Chart = echarts.init(chartDom); + } + let myChart = that.line1Chart; let option = { tooltip: { trigger: "axis", @@ -862,8 +872,12 @@ export default { } //柱状图折线 let line3Dom = document.getElementById("line3"); + if (!line3Dom) return; line3Dom.style.height = this.blockHeight; - let line3Chart = echarts.init(line3Dom); + if (!that.line3Chart || that.line3Chart.isDisposed()) { + that.line3Chart = echarts.init(line3Dom); + } + let line3Chart = that.line3Chart; let line3option = { tooltip: { trigger: "axis", @@ -1217,7 +1231,7 @@ export default { // 添加抓取事件 const hl1 = new BABYLON.HighlightLayer("hl1", scene); const hl1Click = new BABYLON.HighlightLayer("hl1Click", scene); - canvas.addEventListener("mousemove", (event) => { + that.onCanvasMouseMove = (event) => { // 使用 scene.pick 检测鼠标拾取 const pickResult = scene.pick( scene.pointerX, @@ -1292,8 +1306,9 @@ export default { } else { that.infoVisibel = false; } - }); - canvas.addEventListener("click", (event) => { + }; + canvas.addEventListener("mousemove", that.onCanvasMouseMove); + that.onCanvasClick = (event) => { // 使用 scene.pick 检测鼠标拾取 const pickResult = scene.pick( scene.pointerX, @@ -1364,7 +1379,8 @@ export default { } } } - }); + }; + canvas.addEventListener("click", that.onCanvasClick); return scene; }; const scene = createScene(); //Call the createScene function @@ -1374,9 +1390,9 @@ export default { }); this.engine = engine; this.scene = scene; - window.addEventListener("resize", function () { - engine.resize(); - }); + this.canvasEl = canvas; + this.onResize = () => engine.resize(); + window.addEventListener("resize", this.onResize); }, getDeptData(name) { this.infoVisibel = true; @@ -1505,8 +1521,12 @@ export default { let that = this; //左边2 let bar1 = document.getElementById("bar1"); + if (!bar1) return; bar1.style.height = this.blockHeight; - let bar1Chart = echarts.init(bar1); + if (!that.bar1Chart || that.bar1Chart.isDisposed()) { + that.bar1Chart = echarts.init(bar1); + } + let bar1Chart = that.bar1Chart; let bar1option = { tooltip: { trigger: "axis", @@ -1655,8 +1675,12 @@ export default { bar1Chart.setOption(bar1option); //左3 let line2Dom = document.getElementById("line2"); + if (!line2Dom) return; line2Dom.style.height = this.blockHeight; - let line2Chart = echarts.init(line2Dom); + if (!that.line2Chart || that.line2Chart.isDisposed()) { + that.line2Chart = echarts.init(line2Dom); + } + let line2Chart = that.line2Chart; let line2option = { tooltip: { trigger: "axis", @@ -1845,8 +1869,12 @@ export default { line2Chart.setOption(line2option); //饼状图 let pieDom = document.getElementById("pie"); + if (!pieDom) return; pieDom.style.height = this.blockHeight; - let pieChart = echarts.init(pieDom); + if (!that.pieChart || that.pieChart.isDisposed()) { + that.pieChart = echarts.init(pieDom); + } + let pieChart = that.pieChart; let pieoption = { color: [ "rgb(237,224,45)", @@ -1914,22 +1942,53 @@ export default { }, }, beforeUnmount() { - let that = this; - clearInterval(that.timerTime); - clearInterval(that.timerData); - clearInterval(that.notokTimer); - that.timerTime = null; - that.timerData = null; - that.notokTimer = null; - }, - beforeDestoryed() { - let that = this; - clearInterval(that.timerTime); - clearInterval(that.timerData); - clearInterval(that.notokTimer); - that.timerTime = null; - that.timerData = null; - that.notokTimer = null; + this.isUnmounted = true; + // 定时器 + clearInterval(this.timerTime); + clearInterval(this.timerData); + clearInterval(this.notokTimer); + clearInterval(this.heightTimer); + this.timerTime = null; + this.timerData = null; + this.notokTimer = null; + this.heightTimer = null; + // echarts 实例 + [ + this.pieChart, + this.line1Chart, + this.line2Chart, + this.line3Chart, + this.bar1Chart, + ].forEach((c) => { + if (c && !c.isDisposed()) c.dispose(); + }); + this.pieChart = this.line1Chart = this.line2Chart = this.line3Chart = this.bar1Chart = null; + // 事件监听器 + if (this.onResize) { + window.removeEventListener("resize", this.onResize); + this.onResize = null; + } + if (this.canvasEl) { + if (this.onCanvasMouseMove) { + this.canvasEl.removeEventListener("mousemove", this.onCanvasMouseMove); + } + if (this.onCanvasClick) { + this.canvasEl.removeEventListener("click", this.onCanvasClick); + } + this.canvasEl = null; + } + this.onCanvasMouseMove = null; + this.onCanvasClick = null; + // babylon 引擎 + if (this.scene) { + try { this.scene.dispose(); } catch (e) {} + this.scene = null; + } + if (this.engine) { + try { this.engine.stopRenderLoop(); } catch (e) {} + try { this.engine.dispose(); } catch (e) {} + this.engine = null; + } }, }; From a7254d578ae1ce49cde7a259003a827e2f594634 Mon Sep 17 00:00:00 2001 From: shijing Date: Thu, 18 Jun 2026 14:27:20 +0800 Subject: [PATCH 39/50] =?UTF-8?q?fix:=E5=85=89=E8=8A=AF=E5=B7=A5=E6=AE=B5?= =?UTF-8?q?=E7=9C=8B=E6=9D=BF=E5=B7=A5=E5=BA=8F=E4=BD=99=E6=96=99=E5=8F=AA?= =?UTF-8?q?=E5=B1=95=E7=A4=BA=E5=90=88=E6=A0=BC=E5=93=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/bigScreen/gxerp/index_com.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/bigScreen/gxerp/index_com.vue b/src/views/bigScreen/gxerp/index_com.vue index c5f3346a..816faae2 100644 --- a/src/views/bigScreen/gxerp/index_com.vue +++ b/src/views/bigScreen/gxerp/index_com.vue @@ -359,7 +359,7 @@ export default { let list = res.data2.ds0; if (list.length > 0) { list.forEach((item) => { - if(item.物料名.indexOf('QS')>-1||item.物料名.indexOf('32.2')>-1||item.物料名.indexOf('3D')>-1||item.物料名.indexOf('2.5D')>-1){ + if(item.状态=='合格'&&(item.物料名.indexOf('QS')>-1||item.物料名.indexOf('32.2')>-1||item.物料名.indexOf('3D')>-1||item.物料名.indexOf('2.5D')>-1)){ let arr = []; arr[0] = item.物料名+'('+item.状态+')'; arr[1] = item.数量; From 4cb34c00bd7a8128a52b7e8c83078ab4e50f4603 Mon Sep 17 00:00:00 2001 From: shijing Date: Mon, 22 Jun 2026 14:08:43 +0800 Subject: [PATCH 40/50] =?UTF-8?q?feat:=E7=A6=85=E9=81=93437=20=E5=88=86?= =?UTF-8?q?=E6=A3=80=E7=9A=84=E6=A3=80=E6=B5=8B=E8=A1=A8=E9=87=8C=E5=B1=95?= =?UTF-8?q?=E7=A4=BA=E5=96=B7=E7=A0=81=E5=B7=A5=E5=BA=8F=E7=9A=84=E5=B7=A5?= =?UTF-8?q?=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/statistics/bxerp/fenjian.vue | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/views/statistics/bxerp/fenjian.vue b/src/views/statistics/bxerp/fenjian.vue index 7978f2c8..92b64fbf 100644 --- a/src/views/statistics/bxerp/fenjian.vue +++ b/src/views/statistics/bxerp/fenjian.vue @@ -115,13 +115,18 @@ {{scope.row.data.分检_缺陷项_扭转角不合格?scope.row.data.分检_缺陷项_扭转角不合格:0}} - + + + + - + @@ -151,9 +156,21 @@ export default { apiObj: this.$API.wpm.wpr.query, options:[], tableData:[], + toolList:{}, }; }, + mounted() { + this.getToolings(); + }, methods: { + getToolings(){ + let that = this; + that.$API.em.equipment.list.req({ page: 0,type:10,cate__code:'7'}).then((res) => { + res.forEach((item) => { + that.toolList[item.id] = item.number; + }); + }); + }, handleQuery(){ let that = this; let querys = [[{field:"wm",value:false,compare:"isnull"},{field:"data__分检_日期",compare:"isnull",value:false},{field:"data__has_key",compare:"",value:"分检_批次号"}]]; From 6181b757956629177a7c2a4e08918634c72dfac8 Mon Sep 17 00:00:00 2001 From: shijing Date: Mon, 22 Jun 2026 14:38:32 +0800 Subject: [PATCH 41/50] =?UTF-8?q?feat:=E7=A6=85=E9=81=93438?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/wpm_bx/mlogbw_check_table.vue | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/views/wpm_bx/mlogbw_check_table.vue b/src/views/wpm_bx/mlogbw_check_table.vue index 8769d286..d63ff6f6 100644 --- a/src/views/wpm_bx/mlogbw_check_table.vue +++ b/src/views/wpm_bx/mlogbw_check_table.vue @@ -58,7 +58,10 @@ 扭转日期 工装 {{ item.testitem_name }} - {{ item.defect_name }} + + {{ item.defect_name }} + {{ getDefectCount(item.defect_name) }} + 备注 操作 @@ -1358,6 +1361,15 @@ that.$API.wpm.prints.req(printer_ip, obj).then((response) => { this.$message.error("导入失败,请重新尝试"); }); }, + getDefectCount(defectName){ + let count = 0; + this.mlogbwlist.forEach(row => { + if(row[defectName]){ + count++; + } + }); + return count; + }, hasNull(){ let that = this; let canSubmit = true; From ec6c3fc806e733548af507fce144af17234230a8 Mon Sep 17 00:00:00 2001 From: shijing Date: Tue, 23 Jun 2026 13:43:21 +0800 Subject: [PATCH 42/50] =?UTF-8?q?feat:=E5=A4=A7=E5=B1=8F=E5=B7=A5=E5=8E=82?= =?UTF-8?q?=E5=90=8D=E4=BF=AE=E6=AD=A3=E4=B8=8E=E6=97=A0=E6=84=9F=E5=88=B7?= =?UTF-8?q?=E6=96=B0=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - hfnf大屏工厂ABCD改为真实名称,顶部卡片去除点击跳转,浏览器后退跳数据模板页 - request.js修复无感刷新:刷新成功后正确重试(原代码未return导致重试被丢弃)、刷新失败复位isRefreshing、并发401用token比对防刷新风暴、token清空时静默拒绝避免误报无权限 - main.js修复ResizeObserver在元素卸载时getComputedStyle非Element报错(try/catch包到debounce内层) - systemRouter新增hfnf_mplogx/cement_data_template固定子路由 - hfnf接口改走factory_api反向代理,新增stats统计接口 - layout修复pmenu.children为空时的报错 Co-Authored-By: Claude --- .env.development | 7 ++- src/api/model/hfnf.js | 15 +++++- src/layout/index.vue | 4 +- src/main.js | 11 +++- src/router/systemRouter.js | 16 +++++- src/utils/request.js | 91 ++++++++++++++++++++++++-------- src/views/fac_cal/hfnf_index.vue | 54 +++++++++++-------- 7 files changed, 148 insertions(+), 50 deletions(-) diff --git a/.env.development b/.env.development index 88d1f4fa..bf2585f4 100644 --- a/.env.development +++ b/.env.development @@ -21,8 +21,11 @@ VUE_APP_PJ = 'gx' # VUE_APP_BASEURL = http://10.50.211.228:2250/ -VUE_APP_API_BASEURL = http://127.0.0.1:2226/api -VUE_APP_BASEURL = http://127.0.0.1:2226 +# VUE_APP_API_BASEURL = http://127.0.0.1:2226/api +# VUE_APP_BASEURL = http://127.0.0.1:2226 + +VUE_APP_API_BASEURL = http://10.0.11.51:2250/api +VUE_APP_BASEURL = http://10.0.11.51:2250 # 托克逊 # VUE_APP_API_BASEURL = http://10.50.211.228:2250/api diff --git a/src/api/model/hfnf.js b/src/api/model/hfnf.js index 1e12772b..2343af9e 100644 --- a/src/api/model/hfnf.js +++ b/src/api/model/hfnf.js @@ -6,11 +6,24 @@ export default { name: "列表", req: async function(data){ return await http.post( - `${config.HOST_URL}/hfnf_api/mplogx/`, + // 同源路径,由 nginx(/factory_api/) 反向代理到统计服务 10.0.11.52:5800 + `${config.HOST_URL}/factory_api/mplogx/`, // "http://10.0.11.52:5800/mplogx/", data ); } }, + }, + stats: { + list: { + name: "数据统计", + req: async function(params){ + return await http.get( + // 同源路径,由 nginx(/factory_api/) 反向代理到统计服务 10.0.11.52:5800 + `${config.HOST_URL}/factory_api/stats`, + params + ); + } + }, } } \ No newline at end of file diff --git a/src/layout/index.vue b/src/layout/index.vue index 298d3346..803f0db8 100644 --- a/src/layout/index.vue +++ b/src/layout/index.vue @@ -414,8 +414,8 @@ export default { } this.pmenu = this.$route.meta.breadcrumb ? this.$route.meta.breadcrumb[0] - : {}; - let lists = this.pmenu.children; + : { meta: {}, children: [] }; + let lists = this.pmenu.children || []; let perms = this.$TOOL.data.get("PERMISSIONS") || []; for (var i = 0; i < lists.length; i++) { if (lists[i].meta && lists[i].meta.perms) { diff --git a/src/main.js b/src/main.js index 01fb4084..0e07e532 100644 --- a/src/main.js +++ b/src/main.js @@ -55,7 +55,14 @@ const _ResizeObserver = window.ResizeObserver; window.ResizeObserver = class ResizeObserver extends _ResizeObserver { constructor(callback) { - callback = debounce(callback, 16); - super(callback); + // 先包 try/catch 再 debounce:debounce 用 setTimeout 延迟执行, + // 必须让真正执行回调时也在 try/catch 内,否则元素卸载瞬间 + // getComputedStyle 拿到非 Element 的错误会逃出 setTimeout 成为未捕获异常 + const safe = (entries, observer) => { + try { + callback(entries, observer); + } catch (e) {} + }; + super(debounce(safe, 16)); } }; diff --git a/src/router/systemRouter.js b/src/router/systemRouter.js index ae775add..847ff04e 100644 --- a/src/router/systemRouter.js +++ b/src/router/systemRouter.js @@ -7,7 +7,21 @@ const routes = [ path: "/", component: () => import(/* webpackChunkName: "layout" */ '@/layout'), redirect: config.DASHBOARD_URL || getBaseDashboard(), - children: [] + //固定页:通过按钮跳转、不依赖菜单(动态/静态)的页面 + children: [ + { + name: "hfnf_mplogx", + path: "/hfnf_mplogx", + meta: { title: "测点数据明细", hidden: true }, + component: () => import('@/views/fac_cal/hfnf_mplogx'), + }, + { + name: "cement_data_template", + path: "/cement_data_template", + meta: { title: "数据模板", hidden: true }, + component: () => import('@/views/fac_cal/cement_data_template'), + }, + ] }, { path: "/login", diff --git a/src/utils/request.js b/src/utils/request.js index 23ade776..fbedd976 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -18,6 +18,8 @@ axios.interceptors.request.use( let token = tool.data.get("TOKEN"); if(token){ config.headers[sysConfig.TOKEN_NAME] = sysConfig.TOKEN_PREFIX + token + // 记录本次请求实际使用的 token,用于 401 时判断是否已被并发刷新过 + config._tokenUsed = token; } if(!sysConfig.REQUEST_CACHE && config.method == 'get'){ config.params = config.params || {}; @@ -49,39 +51,86 @@ axios.interceptors.response.use( }); }else{ if (error.config.url.indexOf('auth/token/refresh/') != -1) { - isRefreshing = false; - requests=[]; + // 刷新接口自身 401:refresh token 已失效,清除登录态并跳登录 + isRefreshing = false; + requests = []; + tool.data.remove("TOKEN"); + tool.data.remove("TOKEN_REFRESH"); + console.warn('[auth] refresh token 失效,跳转登录页'); router.push('/login'); - return + return Promise.reject(error.response); + } + const currentToken = tool.data.get("TOKEN"); + // 已无 token(refresh 失败已清登录态并跳登录):并发请求直接拒绝, + // 不再重试/刷新,避免误报“无权限” + if (!currentToken) { + return Promise.reject(error.response); + } + // 本次请求用的 token 已和当前 localStorage 里的不一致, + // 说明期间已被并发刷新过,直接用最新 token 重试一次即可,不再触发刷新 + // (避免快速点击时多个晚到 401 引发刷新风暴) + if (error.config._tokenUsed && error.config._tokenUsed !== currentToken && !error.config._retriedAfterRefresh) { + error.config._tokenUsed = currentToken; + error.config._retriedAfterRefresh = true; + return axios(error.config); + } + // 已刷新过 token 仍然 401:说明不是 token 过期,而是无权限/持久 401。 + // 不再刷新、不跳登录,只提示无权限,避免刷新循环把会话耗到失效。 + if (error.config._retriedAfterRefresh) { + console.warn('[auth] 刷新后仍 401,判定为无权限,不跳登录', error.config.url); + ElNotification.warning({ + title: '无权限', + message: (error.response.data && error.response.data.err_msg) || '当前账号无权限访问该资源' + }); + return Promise.reject(error.response); } if (!isRefreshing) { isRefreshing = true; - axios({ - method: 'post', - url: sysConfig.API_URL+'/auth/token/refresh/', - headers: { - Authorization: `Bearer ${tool.data.get("TOKEN")}`, - }, - data:{refresh:tool.data.get("TOKEN_REFRESH")} - }).then(res=>{ - // 替换本地的token - tool.data.set("TOKEN", res.data.access); - tool.data.set("TOKEN_TIME", new Date().getTime()); - error.config.headers[sysConfig.TOKEN_NAME] = sysConfig.TOKEN_PREFIX + res.data.access; - isRefreshing = false; - requests.forEach(cb => cb()) - //发起后将requests置空 - requests=[]; - return axios(error.config) + // 必须 return 刷新 Promise,否则即便刷新成功,原始请求也会被 reject,重试结果被丢弃 + return new Promise((resolve, reject) => { + axios({ + method: 'post', + url: sysConfig.API_URL+'/auth/token/refresh/', + headers: { + Authorization: `Bearer ${tool.data.get("TOKEN")}`, + }, + data:{refresh:tool.data.get("TOKEN_REFRESH")} + }).then(res=>{ + // 替换本地的token + tool.data.set("TOKEN", res.data.access); + tool.data.set("TOKEN_TIME", new Date().getTime()); + // 若后端开启了 refresh token 轮换,需同步更新本地 refresh token, + // 否则旧的被拉黑后,下一次刷新就会 401 → 跳登录(admin 也会偶发被踢) + if (res.data && res.data.refresh) { + tool.data.set("TOKEN_REFRESH", res.data.refresh); + } + error.config.headers[sysConfig.TOKEN_NAME] = sysConfig.TOKEN_PREFIX + res.data.access; + error.config._retriedAfterRefresh = true; // 标记:重试后若仍 401 则视为无权限 + isRefreshing = false; + //发起后将requests置空 + const queue = requests; requests = []; + queue.forEach(cb => cb()) + resolve(axios(error.config)) + }).catch(err=>{ + // 刷新失败:复位状态,清登录态,跳登录 + isRefreshing = false; + requests = []; + tool.data.remove("TOKEN"); + tool.data.remove("TOKEN_REFRESH"); + console.warn('[auth] token 刷新失败,跳转登录页', err); + router.push('/login'); + reject(err); + }) }) }else{ //如果正在刷新token,将发起的请求暂存在requests中 return new Promise((resolve)=>{ requests.push(()=>{ + error.config._retriedAfterRefresh = true; resolve(axios(error.config)); }) }) - } + } } } else { diff --git a/src/views/fac_cal/hfnf_index.vue b/src/views/fac_cal/hfnf_index.vue index 7f08dc23..2e051bce 100644 --- a/src/views/fac_cal/hfnf_index.vue +++ b/src/views/fac_cal/hfnf_index.vue @@ -23,7 +23,7 @@ -
+
@@ -193,30 +193,32 @@ let pieChart = null const colors = ['#409eff', '#67c23a', '#e6a23c', '#f56c6c'] const bgColors = ['#ecf5ff', '#f0f9eb', '#fdf6ec', '#fef0f0'] -// 各工厂基础比例 -const baseFactories = [ - { name: '合肥南方', ratio: 0.4382 }, - { name: '中联万吨', ratio: 0.3081 }, - { name: '铜梁水泥', ratio: 0.1424 }, - { name: '槐坎南方水泥', ratio: 0.1113 }, +// 各工厂与数据表的映射关系 +const factoryDefs = [ + { name: '合肥南方', match: (t) => t === 'mplogx' }, // 合肥南方 + { name: '中联万吨', match: (t) => t === 'mplogx_xzzl' }, // 中联万吨 + { name: '铜梁水泥', match: (t) => t === 'mplogx_tlxn' }, // 铜梁水泥 + { name: '槐坎南方水泥', match: (t) => t.startsWith('mplogx_hknf') }, // 槁坎南方水泥 ] const totalCount = ref(0) +const tables = ref([]) const factories = computed(() => { const total = totalCount.value - // 前3个按比例取整,最后一个用总量减去前3个保证总和精确 - const counts = baseFactories.map(f => Math.round(total * f.ratio)) - const sumFirst3 = counts[0] + counts[1] + counts[2] - counts[3] = total - sumFirst3 - - return baseFactories.map((f, i) => ({ - name: f.name, - count: counts[i], - color: colors[i], - bgColor: bgColors[i], - percentage: total > 0 ? (counts[i] / total) * 100 : 0, - })) + return factoryDefs.map((f, i) => { + // 同一工厂可能对应多张数据表,按表名匹配后累加行数 + const count = tables.value + .filter((t) => f.match(t.table_name)) + .reduce((sum, t) => sum + (t.approximate_row_count || 0), 0) + return { + name: f.name, + count, + color: colors[i], + bgColor: bgColors[i], + percentage: total > 0 ? (count / total) * 100 : 0, + } + }) }) const maxFactory = computed(() => { @@ -336,19 +338,29 @@ const handleResize = () => { pieChart?.resize() } +// 拦截浏览器后退:在大屏页按“返回”时跳转到数据模板页 +const handlePopState = () => { + router.push('/cement_data_template') +} + onMounted(() => { - API.hfnf.mplogx.list.req({ page: 1, page_size: 1 }).then(res => { - totalCount.value = res.count + API.hfnf.stats.list.req().then(res => { + tables.value = res.tables || [] + totalCount.value = res.summary?.approximate_row_count_total || 0 nextTick(() => { initBarChart() initPieChart() }) }) window.addEventListener('resize', handleResize) + // 多压一条相同的历史记录,使浏览器后退可被 popstate 拦截 + history.pushState(null, '', location.href) + window.addEventListener('popstate', handlePopState) }) onBeforeUnmount(() => { window.removeEventListener('resize', handleResize) + window.removeEventListener('popstate', handlePopState) barChart?.dispose() pieChart?.dispose() }) From 4e8d8b15587e5fdadf469810a9e2313b5e5d5b5f Mon Sep 17 00:00:00 2001 From: shijing Date: Wed, 24 Jun 2026 16:58:20 +0800 Subject: [PATCH 43/50] =?UTF-8?q?feat:=E5=88=86=E6=A3=80=E6=9D=BF=E6=AE=B5?= =?UTF-8?q?=E7=BB=9F=E8=AE=A1=E6=B7=BB=E5=8A=A0=E5=BC=80=E5=8F=B0=E8=AE=BE?= =?UTF-8?q?=E5=A4=87=E5=88=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/statistics/bxerp/fenjian.vue | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/views/statistics/bxerp/fenjian.vue b/src/views/statistics/bxerp/fenjian.vue index 92b64fbf..c58051d0 100644 --- a/src/views/statistics/bxerp/fenjian.vue +++ b/src/views/statistics/bxerp/fenjian.vue @@ -126,7 +126,13 @@ {{scope.row.data.喷码_磨床开台_操作人}} - + + + + From 701b085cb503552cd83431fcacc73ebfaede2125 Mon Sep 17 00:00:00 2001 From: shijing Date: Wed, 1 Jul 2026 15:53:23 +0800 Subject: [PATCH 44/50] =?UTF-8?q?fix:=E8=BF=94=E5=B7=A5=E6=97=A5=E5=BF=97?= =?UTF-8?q?=E8=BE=93=E5=87=BA=E7=89=A9=E6=96=99=E5=88=97=E8=A1=A8=E4=B8=8D?= =?UTF-8?q?=E5=B1=95=E7=A4=BA=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/wpm_bx/mlog_detail.vue | 15 +++++++++++---- src/views/wpm_bx/mlogbw_check_table.vue | 2 ++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/views/wpm_bx/mlog_detail.vue b/src/views/wpm_bx/mlog_detail.vue index 94e296b9..3b64422b 100644 --- a/src/views/wpm_bx/mlog_detail.vue +++ b/src/views/wpm_bx/mlog_detail.vue @@ -677,11 +677,18 @@ export default { } that.materialIn = res.material_in!==null?res.material_in:res.mlogb_full[0]?res.mlogb_full[0].material_in:null; that.deptId = res.belong_dept; - that.checkTableShow = true; that.apiObjWm = that.$API.wpm.wmaterial.list; - that.$API.wpm.mlogb.list.req(that.paramsOut).then((res) => { - that.tableData2 = res; - }) + if(res.qct!==null){ + that.checkTableShow = true; + }else{ + that.$API.wpm.mlogb.list.req(that.paramsOut).then((res_out) => { + that.tableData2 = res_out; + if(res.is_fix&&res_out[0].qct!==null){ + that.mlogItem.qct = res_out[0].qct; + } + that.checkTableShow = true; + }) + } if(!res.is_fix){ that.getcutCount(res.material_in); that.$API.mtm.routepack.list.req({page:0,search:res.routepack_name}).then((res) => { diff --git a/src/views/wpm_bx/mlogbw_check_table.vue b/src/views/wpm_bx/mlogbw_check_table.vue index d63ff6f6..7a189570 100644 --- a/src/views/wpm_bx/mlogbw_check_table.vue +++ b/src/views/wpm_bx/mlogbw_check_table.vue @@ -536,6 +536,8 @@ export default { }).catch(()=>{ that.getList(); }) + }else{ + that.getList(); } } that.visible = true; From 8856308e8f6a372d6509122c305949c142c8e7ef Mon Sep 17 00:00:00 2001 From: shijing Date: Wed, 1 Jul 2026 15:55:22 +0800 Subject: [PATCH 45/50] =?UTF-8?q?fix:=E4=BA=A4=E6=8E=A5=E7=89=A9=E6=96=99?= =?UTF-8?q?=E6=97=B6=EF=BC=8C=E5=8F=AF=E4=BB=A5=E9=80=89=E6=8B=A9=E5=90=88?= =?UTF-8?q?=E6=A0=BC=E7=89=A9=E6=96=99=EF=BC=8C=E4=B9=9F=E5=8F=AF=E4=BB=A5?= =?UTF-8?q?=E9=80=89=E6=8B=A9=E8=BF=94=E4=BF=AE=E5=AE=8C=E6=88=90=E7=89=A9?= =?UTF-8?q?=E6=96=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/wpm_bx/handover_form.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/wpm_bx/handover_form.vue b/src/views/wpm_bx/handover_form.vue index 301f4aaa..7a06c1f2 100644 --- a/src/views/wpm_bx/handover_form.vue +++ b/src/views/wpm_bx/handover_form.vue @@ -540,7 +540,7 @@ export default { let that = this; var req = { page: 0, - state:10, + state__in:'10,34', tag:that.tag, mgroupx:that.mgroupId }; From 32c8494f5478a5c7eeeeee2dfe19ac7d2f474e12 Mon Sep 17 00:00:00 2001 From: shijing Date: Wed, 1 Jul 2026 16:00:01 +0800 Subject: [PATCH 46/50] =?UTF-8?q?fix:=E6=B7=BB=E5=8A=A0=E5=BF=BD=E7=95=A5?= =?UTF-8?q?=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.gitignore b/.gitignore index 47ac71d9..a8692201 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,8 @@ node_modules /public/glb/ /dist .VSCodeCounter/ +.claude/ +.codex/ # local env files .env.local @@ -14,6 +16,7 @@ node_modules .env.production .env.development + # Log files npm-debug.log* yarn-debug.log* @@ -28,5 +31,7 @@ pnpm-debug.log* *.njsproj *.sln *.sw? +*.bat /package-lock.json +/vue.config.js From 5f47ef62c6397023beb6703236e810053b0d6118 Mon Sep 17 00:00:00 2001 From: shijing Date: Fri, 3 Jul 2026 14:58:48 +0800 Subject: [PATCH 47/50] =?UTF-8?q?fix:20260702=E5=85=89=E5=AD=90=E7=A7=91?= =?UTF-8?q?=E6=8A=80=E5=BC=80=E5=8F=91=E6=B5=8B=E6=96=B0=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/bigScreen/index_photon.vue | 27 ++++++++++++++++--------- src/views/home/widgets/index_photon.vue | 4 ++-- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/views/bigScreen/index_photon.vue b/src/views/bigScreen/index_photon.vue index 11aa755a..28274167 100644 --- a/src/views/bigScreen/index_photon.vue +++ b/src/views/bigScreen/index_photon.vue @@ -132,7 +132,7 @@ id="dashbordProcess" > {{ dialogData.percentage }}%{{ dialogData.percentage }} 完成进度 @@ -216,7 +216,7 @@ id="dashbordProcess" > {{ currentData.percentage }}%{{ currentData.percentage }}

完成进度

@@ -444,23 +444,23 @@ export default { yesterday: "", dept6Obj: { deptName: "光学精密加工车间", - percentage: 100, + percentage: "100%", count_bang: 0, count_guan: 0, }, dept7Obj: { deptName: "光纤预制棒生产车间", - percentage: 100, + percentage: "100%", count_bang: 0, }, dept8Obj: { deptName: "玻璃配合料制备车间", - percentage: 100, + percentage: "100%", count: 0, }, dept10Obj: { deptName: "光纤预制管生产车间", - percentage: 100, + percentage: "100%", count_guan: 0, }, isUnmounted: false, @@ -994,12 +994,19 @@ export default { that.$API.bi.dataset.exec.req("materialCount", obj).then((res) => { let data = []; let list = res.data2.ds0; + let names = []; if (list.length > 0) { list.forEach((item) => { - let arr = []; - arr[0] = item.material_name ; - arr[1] = item.count; - data.push(arr); + let indexes = names.indexOf(item.material_name); + if(indexes === -1){ + names.push(item.material_name); + let arr = []; + arr[0] = item.material_name ; + arr[1] = item.count; + data.push(arr); + }else{ + data[indexes][1] = data[indexes][1] + item.count; + } }); } that.taskBoard.data = data; diff --git a/src/views/home/widgets/index_photon.vue b/src/views/home/widgets/index_photon.vue index e247081f..a4135c95 100644 --- a/src/views/home/widgets/index_photon.vue +++ b/src/views/home/widgets/index_photon.vue @@ -183,7 +183,7 @@ >
Date: Mon, 6 Jul 2026 14:45:57 +0800 Subject: [PATCH 48/50] =?UTF-8?q?feat:=E7=A6=85=E9=81=93443?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/statistics/bxerp/workHoursRY_MP.vue | 21 +++++++++++++++++++ src/views/statistics/bxerp/workHoursRY_NZ.vue | 20 +++++++++++++++++- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/views/statistics/bxerp/workHoursRY_MP.vue b/src/views/statistics/bxerp/workHoursRY_MP.vue index c5298c15..90b83068 100644 --- a/src/views/statistics/bxerp/workHoursRY_MP.vue +++ b/src/views/statistics/bxerp/workHoursRY_MP.vue @@ -63,6 +63,12 @@ placeholder="结束时间" style="margin-left: 2px; width: 150px" /> + {{ scope.row.data.装炉压板出炉_装炉_日期?scope.row.data.装炉压板出炉_装炉_日期:'' }} + + @@ -201,6 +209,8 @@ + +