diff --git a/src/views/bigScreen/bxerp/jiejingdept.vue b/src/views/bigScreen/bxerp/jiejingdept.vue index 4e6ceca1..a0aea3f0 100644 --- a/src/views/bigScreen/bxerp/jiejingdept.vue +++ b/src/views/bigScreen/bxerp/jiejingdept.vue @@ -5,80 +5,16 @@
{{ currentDay }} {{ currentTime }}
- - - -
本月产量
-
123
-
-
- - -
今日产量
-
123
-
-
- - -
今日工序报工量
-
123
-
-
- - -
在产产品数
-
123
-
-
- - -
本月完工工单
-
123
-
-
- - -
本月计划产量
-
123
-
-
- - -
本月产量
-
123
-
-
- - -
本月产量
-
123
-
-
-
- - - -
在制工序数
-
123
-
-
- - -
今日完成工序
-
123
-
-
-
-
+
车间各工段生产产品数
-
+
产品占比
@@ -87,6 +23,32 @@
+ + + +
今日工序报工量
+
123
+
+
+ + +
在产产品数
+
123
+
+
+ + +
本月完工工单
+
123
+
+
+ + +
本月计划产量
+
123
+
+
+
@@ -94,38 +56,80 @@
-
+
-
设备列表
- +
+
+
+ + + 拉丝设备集群 · 实时状态 +
+
在线 {{ onlineCount }}/{{ equipmentList.length }}
+
+
+
+
{{ item.name }}
+
+ + + {{ item.running_state_text }} + +
+
{{ item.isRunning ? item.number : '待机中' }}
+
+
+ +
- - - -
在制工单数
-
123
-
-
- - -
本月交付数
-
123
-
-
-
-
+
-
每个人日产量
- - +
+
+
+ + 👥 + 人员日产量 TOP5 +
+
单位: 件
+
+
+
+
{{ item.操作人 ? item.操作人.charAt(0) : '?' }}
+
{{ item.操作人 }}
+
+ {{ item.生产数 }} + +
+
+
+ +
-
+
车间整体产品统计
@@ -414,22 +418,12 @@ export default { header: ['任务编号', '产出产品', '任务量', '合格数'], data: [] }, - config_middle_bottom:{ - rowNum:10, - headerBGC: 'rgba(0,0,0,0)', - oddRowBGC: 'rgba(0,0,0,0)', - evenRowBGC: 'rgba(0,0,0,0)', - header: ['设备名称','设备位号','设备状态','运行状态','所在工段'], - data: [] - }, - config_right_top:{ - rowNum:10, - headerBGC: 'rgba(47,102,107,.34)', - oddRowBGC: 'rgba(0,0,0,0)', - evenRowBGC: 'rgba(0,0,0,0)', - header: ['工段','姓名','生产数','合格数','不合格数'], - data: [] - }, + equipmentList: [], + lastUpdateSeconds: 0, + lastUpdateInterval: null, + scrollTimer: null, + performanceList: [], + perfScrollTimer: null, currentTime: "", currentDay: "", today: "", @@ -439,6 +433,43 @@ export default { mgroups:['洗棒','捆棒','拉单丝','捆一次棒','一次复丝','捆二次棒','二次复丝'], }; }, + computed: { + onlineCount() { + return this.equipmentList.filter(e => e.isRunning).length; + }, + lastUpdateText() { + return this.lastUpdateSeconds > 0 ? `${this.lastUpdateSeconds}s前` : '刚刚'; + }, + // 渲染两份,用于无缝滚动 + scrollItems() { + if (this.equipmentList.length === 0) return []; + return [...this.equipmentList, ...this.equipmentList]; + }, + // 全员按生产数降序排列 + sortedPerfList() { + return [...this.performanceList] + .sort((a, b) => Number(b.生产数) - Number(a.生产数)); + }, + // 渲染两份,用于无缝滚动 + scrollPerfItems() { + if (!this.sortedPerfList.length) return []; + return [...this.sortedPerfList, ...this.sortedPerfList]; + }, + // 平均效率 = 合格数之和 / 生产数之和 + avgEfficiency() { + if (!this.performanceList.length) return 0; + const totalProd = this.performanceList.reduce((s, i) => s + Number(i.生产数 || 0), 0); + const totalOk = this.performanceList.reduce((s, i) => s + Number(i.合格数 || 0), 0); + if (!totalProd) return 0; + return Math.round(totalOk / totalProd * 100); + }, + // 标兵 = 生产数最多的人 + topPerson() { + if (!this.performanceList.length) return '-'; + return [...this.performanceList] + .sort((a, b) => Number(b.生产数) - Number(a.生产数))[0]?.操作人 || '-'; + }, + }, mounted() { let that = this; //洗棒、捆棒、拉丝 :洗棒、捆棒、拉单丝、捆一次棒、一次复丝、捆二次棒、二次复丝 @@ -447,6 +478,7 @@ export default { this.showTime(); }, 1000); that.mgroupsforEach(); + that.getEquipment(); that.getMgroups(); //每个人日生产量:个人绩效 that.getEveryoneCount(); @@ -505,7 +537,6 @@ export default { mgroupsforEach(){ let that = this; that.mgroups.forEach((item)=>{ - that.getEquipment(item); that.getMtask1(item); }) }, @@ -546,46 +577,78 @@ export default { //车间设备列表 getEquipment() { let that = this; - let params = {page: 0, belong_dept__name:'拉丝排板班组', - // query: " { id, name, number, model, state ,mgroup_name }" - }; - that.config_middle_bottom.data = []; + let params = { page: 0, belong_dept__name: '拉丝排板班组' }; + that.equipmentList = []; + clearInterval(that.lastUpdateInterval); + that.lastUpdateSeconds = 0; that.$API.em.equipment.list.req(params).then((res) => { - if(res.length>0){ + if (res.length > 0) { res.forEach((item) => { - let arr = []; - let state_ = that.state_[item.state]; - let running_state_ = runningStateEnum[item.running_state]?.text; - arr[0] = item.name; - arr[1] = item.number; - arr[2] = state_; - arr[3] = running_state_; - arr[4] = item.mgroup_name; - that.config_middle_bottom.data.push(arr); - }) + that.equipmentList.push({ + id: item.id, + name: item.name, + number: item.number, + running_state_text: runningStateEnum[item.running_state]?.text || '未知', + mgroup_name: item.mgroup_name, + isRunning: item.running_state == 10, + }); + }); } - }) + that.lastUpdateSeconds = 0; + that.lastUpdateInterval = setInterval(() => { + that.lastUpdateSeconds++; + }, 1000); + that.$nextTick(() => { that.startAutoScroll(); }); + }); + }, + startPerfScroll() { + const that = this; + clearInterval(this.perfScrollTimer); + this.$nextTick(() => { + const el = that.$refs.perfList; + if (!el) return; + const halfHeight = el.scrollHeight / 2; + if (halfHeight <= el.clientHeight + 1) return; + that.perfScrollTimer = setInterval(() => { + el.scrollTop += 1; + if (el.scrollTop >= halfHeight) { + el.scrollTop = 0; + } + }, 40); + }); + }, + startAutoScroll() { + const that = this; + clearInterval(this.scrollTimer); + this.$nextTick(() => { + const el = that.$refs.eqGrid; + if (!el) return; + // scrollItems 已是两倍,halfHeight 即一份的高度 + const halfHeight = el.scrollHeight / 2; + // 一份内容就能装下,无需滚动 + if (halfHeight <= el.clientHeight + 1) return; + that.scrollTimer = setInterval(() => { + el.scrollTop += 1; + // 滚完第一份时瞬间归零,视觉无缝 + if (el.scrollTop >= halfHeight) { + el.scrollTop = 0; + } + }, 40); + }); }, //每个人日产量 getEveryoneCount(){ let that = this; - that.config_right_top.data = []; + that.performanceList = []; let date = that.$TOOL.dateFormat(new Date(), "yyyy-MM-dd"); let params = { query: {start_date:date,end_date:date,dept_name:that.deptName}, }; this.$API.bi.dataset.exec.req("performance", params).then((res) => { - if(res.data2.ds0.length>0){ - res.data2.ds0.forEach((item)=>{ - let arr = []; - arr[0] = item.工段; - arr[1] = item.操作人; - arr[2] = item.生产数; - arr[3] = item.合格数; - arr[4] = item.不合格数; - that.config_right_top.data.push(arr); - }) + if(res.data2.ds0.length > 0){ + that.performanceList = res.data2.ds0; } + that.$nextTick(() => { that.startPerfScroll(); }); }); }, //车间整体产品统计 @@ -692,14 +755,14 @@ export default { } .leftChartBlock1{ width: 90%; - height: 28vh; + height: 43vh; z-index: 999; left: 5%; border-radius: 3vh; } .leftChartBlock2{ width:100%; - height: 28vh; + height: 35vh; } .middleTableBlock1{ width:94%; @@ -725,4 +788,264 @@ export default { font-weight: 600; border-bottom: 1px solid rgb(83 198 243); } + +/* ===== 设备卡片面板 ===== */ +.eq-panel { position: relative; } + +/* dv-border-box-1 内层弹性布局,严格撑满边框内部 */ +.eq-inner { + position: absolute; + inset: 2.5%; + display: flex; + flex-direction: column; + overflow: hidden; +} + +.eq-header { + flex-shrink: 0; + display: flex; + justify-content: space-between; + align-items: center; + padding: 0 1.2vh; + height: 4vh; + border-bottom: 1px solid rgba(83, 198, 243, 0.25); +} +.eq-title { + display: flex; + align-items: center; + gap: 0.4vh; + font-size: 1.5vh; + font-weight: 600; + color: #e0f4ff; +} +.eq-title-bar { + display: inline-block; + width: 3px; + height: 1.6vh; + background: #00b4ff; + border-radius: 2px; + margin-right: 2px; +} +.eq-title-icon { font-style: normal; color: #ff9d3e; font-size: 1.4vh; } +.eq-online-badge { font-size: 1.2vh; color: rgba(180, 230, 255, 0.7); } + +/* 卡片网格 — flex:1 填充剩余空间,overflow hidden 由 JS 控制滚动 */ +.eq-grid { + flex: 1; + display: grid; + grid-template-columns: repeat(3, 1fr); + align-content: start; + gap: 0.5vh; + padding: 0.5vh 0.8vh; + overflow: hidden; /* JS 滚动,隐藏滚动条 */ + overflow-y: hidden; +} + +.eq-card { + background: rgba(8, 25, 45, 0.85); + border-radius: 0.8vh; + border: 1px solid rgba(40, 80, 120, 0.5); + padding: 0.4vh 0.3vh; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 0.3vh; +} +.eq-card--run { + border-color: rgba(0, 200, 100, 0.35); + box-shadow: inset 0 0 8px rgba(0, 200, 100, 0.06); +} +.eq-card--stop { + border-color: rgba(80, 90, 110, 0.45); +} + +.eq-card-name { + font-size: 1.05vh; + color: rgba(180, 220, 255, 0.9); + background: rgba(0, 55, 100, 0.55); + padding: 0.1vh 0.6vh; + border-radius: 0.4vh; + border: 1px solid rgba(80, 160, 220, 0.3); + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + max-width: 95%; +} +.eq-card-center { + display: flex; + align-items: center; + gap: 0.5vh; +} +.eq-card-state { + font-size: 1.5vh; + font-weight: bold; +} +.state-run { color: #00e676; } +.state-stop { color: #ff5252; } + +.eq-card-sub { + font-size: 0.9vh; + color: rgba(140, 195, 225, 0.55); +} + +/* 指示点 */ +.eq-dot { + display: inline-block; + border-radius: 50%; + flex-shrink: 0; + width: 1.1vh; + height: 1.1vh; +} +.eq-dot--green { + background: #00e676; + box-shadow: 0 0 5px #00e676, 0 0 12px rgba(0, 230, 118, 0.5); + animation: pulse-green 2s ease-in-out infinite; +} +.eq-dot--red { + background: #ff5252; + box-shadow: 0 0 5px #ff5252, 0 0 10px rgba(255, 82, 82, 0.45); +} +.eq-dot--sm { width: 0.8vh; height: 0.8vh; } + +@keyframes pulse-green { + 0%, 100% { box-shadow: 0 0 4px #00e676, 0 0 10px rgba(0,230,118,0.4); } + 50% { box-shadow: 0 0 8px #00e676, 0 0 18px rgba(0,230,118,0.75); } +} + +/* 底栏 */ +.eq-footer { + flex-shrink: 0; + display: flex; + align-items: center; + padding: 0 1.2vh; + height: 3.5vh; + border-top: 1px solid rgba(83, 198, 243, 0.2); + gap: 2vh; +} +.eq-foot-item { + display: flex; + align-items: center; + gap: 0.5vh; + font-size: 1.1vh; + color: rgba(180, 220, 255, 0.8); +} +.eq-foot-update { + margin-left: auto; + font-size: 1.05vh; + color: rgba(120, 175, 215, 0.55); +} + +/* ===== 人员日产量 TOP5 ===== */ +.perf-panel { position: relative; } + +.perf-inner { + position: absolute; + inset: 2.5%; + display: flex; + flex-direction: column; + overflow: hidden; +} + +.perf-header { + flex-shrink: 0; + display: flex; + justify-content: space-between; + align-items: center; + height: 4vh; + padding: 0 1vh; + border-bottom: 1px solid rgba(83, 198, 243, 0.2); +} +.perf-title { + display: flex; + align-items: center; + gap: 0.5vh; + font-size: 1.5vh; + font-weight: 600; + color: #e0f4ff; +} +.perf-title-bar { + display: inline-block; + width: 3px; + height: 1.8vh; + background: #00b4ff; + border-radius: 2px; +} +.perf-title-icon { font-style: normal; font-size: 1.4vh; } +.perf-unit { font-size: 1.2vh; color: rgba(180, 220, 255, 0.55); } + +/* 列表区 */ +.perf-list { + flex: 1; + overflow: hidden; /* JS 控制滚动,隐藏滚动条 */ + padding: 0 1vh; +} +.perf-row { + display: flex; + align-items: center; + gap: 1.2vh; + height: 5.2vh; /* 固定行高,保证无缝滚动节奏一致 */ + border-bottom: 1px solid rgba(83, 198, 243, 0.12); + flex-shrink: 0; +} + +/* 头像圆圈 */ +.perf-avatar { + flex-shrink: 0; + width: 3.6vh; + height: 3.6vh; + border-radius: 50%; + background: linear-gradient(135deg, #1a6fa8 0%, #0d4a7a 100%); + border: 1.5px solid rgba(100, 180, 255, 0.5); + display: flex; + align-items: center; + justify-content: center; + font-size: 1.5vh; + font-weight: 600; + color: #b8e0ff; +} + +.perf-name { + flex: 1; + font-size: 1.6vh; + color: rgba(210, 235, 255, 0.9); +} + +.perf-count { + display: flex; + align-items: baseline; + gap: 0.3vh; +} +.perf-num { + font-size: 2.4vh; + font-weight: 700; + color: #c8ff50; + font-family: "myfont", "Microsoft Yahei"; + letter-spacing: 1px; +} +.perf-unit-sm { + font-size: 1.1vh; + color: rgba(180, 220, 160, 0.7); +} + +/* 底部标兵栏 */ +.perf-footer { + flex-shrink: 0; + height: 4vh; + display: flex; + align-items: center; + justify-content: center; + gap: 0.6vh; + background: rgba(15, 40, 65, 0.8); + border-radius: 2vh; + font-size: 1.35vh; + color: rgba(200, 230, 255, 0.85); + border: 1px solid rgba(60, 120, 180, 0.3); + margin-top: 0.5vh; +} +.perf-lightning { + font-style: normal; + color: #ff9d3e; + font-size: 1.4vh; +}