From bf64e8016283b18c04d5392dd9c002b921021af2 Mon Sep 17 00:00:00 2001
From: Junjie <fallin.jie@qq.com>
Date: 星期六, 07 三月 2026 09:47:04 +0800
Subject: [PATCH] #
---
src/main/webapp/components/WatchCrnCard.js | 419 ++++++++++++++++++++++++++++++-----------------------------
1 files changed, 213 insertions(+), 206 deletions(-)
diff --git a/src/main/webapp/components/WatchCrnCard.js b/src/main/webapp/components/WatchCrnCard.js
index 53c90a2..0d7e292 100644
--- a/src/main/webapp/components/WatchCrnCard.js
+++ b/src/main/webapp/components/WatchCrnCard.js
@@ -1,96 +1,86 @@
Vue.component("watch-crn-card", {
template: `
- <div>
- <div style="display: flex;margin-bottom: 10px;">
- <div style="width: 100%;">鍫嗗灈鏈虹洃鎺�</div>
- <div style="width: 100%;text-align: right;display: flex;"><el-input size="mini" v-model="searchCrnNo" placeholder="璇疯緭鍏ュ爢鍨涙満鍙�"></el-input><el-button @click="getCrnStateInfo" size="mini">鏌ヨ</el-button></div>
+ <div class="mc-root">
+ <div class="mc-toolbar">
+ <div class="mc-title">鍫嗗灈鏈虹洃鎺�</div>
+ <div class="mc-search">
+ <input class="mc-input" v-model="searchCrnNo" placeholder="璇疯緭鍏ュ爢鍨涙満鍙�" />
+ <button type="button" class="mc-btn mc-btn-ghost" @click="getCrnStateInfo">鏌ヨ</button>
</div>
- <div style="margin-bottom: 10px;" v-if="!readOnly">
- <div style="margin-bottom: 5px;">
- <el-button v-if="showControl" @click="openControl" size="mini">鍏抽棴鎺у埗涓績</el-button>
- <el-button v-else @click="openControl" size="mini">鎵撳紑鎺у埗涓績</el-button>
+ </div>
+
+ <div v-if="!readOnly" class="mc-control-toggle">
+ <button type="button" class="mc-btn mc-btn-ghost" @click="openControl">
+ {{ showControl ? '鏀惰捣鎺у埗涓績' : '鎵撳紑鎺у埗涓績' }}
+ </button>
+ </div>
+
+ <div v-if="showControl" class="mc-control">
+ <div class="mc-control-grid">
+ <label class="mc-field">
+ <span class="mc-field-label">鍫嗗灈鏈哄彿</span>
+ <input class="mc-input" v-model="controlParam.crnNo" placeholder="渚嬪 1" />
+ </label>
+ <label class="mc-field">
+ <span class="mc-field-label">婧愬簱浣�</span>
+ <input class="mc-input" v-model="controlParam.sourceLocNo" placeholder="杈撳叆婧愮偣" />
+ </label>
+ <label class="mc-field mc-span-2">
+ <span class="mc-field-label">鐩爣搴撲綅</span>
+ <input class="mc-input" v-model="controlParam.targetLocNo" placeholder="杈撳叆鐩爣鐐�" />
+ </label>
+ <div class="mc-action-row">
+ <button type="button" class="mc-btn" @click="controlCommandTransport">鍙栨斁璐�</button>
+ <button type="button" class="mc-btn mc-btn-ghost" @click="controlCommandMove">绉诲姩</button>
+ <button type="button" class="mc-btn mc-btn-soft" @click="controlCommandTaskComplete">浠诲姟瀹屾垚</button>
+ </div>
+ </div>
+ </div>
+
+ <div class="mc-collapse">
+ <div
+ v-for="item in displayCrnList"
+ :key="item.crnNo"
+ :class="['mc-item', { 'is-open': isActive(item.crnNo) }]"
+ >
+ <button type="button" class="mc-head" @click="toggleItem(item)">
+ <div class="mc-head-main">
+ <div class="mc-head-title">{{ item.crnNo }}鍙峰爢鍨涙満</div>
+ <div class="mc-head-subtitle">宸ヤ綔鍙� {{ orDash(item.workNo) }} | 鐩爣 {{ orDash(item.locNo) }}</div>
</div>
- <div v-if="showControl" style="display: flex;justify-content: space-between;flex-wrap: wrap;">
- <div style="margin-bottom: 10px;width: 33%;"><el-input size="mini" v-model="controlParam.crnNo" placeholder="鍫嗗灈鏈哄彿"></el-input></div>
- <div style="margin-bottom: 10px;width: 33%;"><el-input size="mini" v-model="controlParam.sourceLocNo" placeholder="婧愮偣"></el-input></div>
- <div style="margin-bottom: 10px;width: 33%;"><el-input size="mini" v-model="controlParam.targetLocNo" placeholder="鐩爣鐐�"></el-input></div>
- <div style="margin-bottom: 10px;"><el-button @click="controlCommandTransport()" size="mini">鍙栨斁璐�</el-button></div>
- <div style="margin-bottom: 10px;"><el-button @click="controlCommandMove()" size="mini">绉诲姩</el-button></div>
- <div style="margin-bottom: 10px;"><el-button @click="controlCommandTaskComplete()" size="mini">浠诲姟瀹屾垚</el-button></div>
+ <div class="mc-head-right">
+ <span :class="['mc-badge', 'is-' + getStatusTone(item)]">{{ getStatusLabel(item) }}</span>
+ <span class="mc-chevron">{{ isActive(item.crnNo) ? '鈻�' : '鈻�' }}</span>
</div>
+ </button>
+
+ <div v-if="isActive(item.crnNo)" class="mc-body">
+ <div class="mc-detail-grid">
+ <div v-for="entry in buildDetailEntries(item)" :key="entry.label" class="mc-detail-cell">
+ <div class="mc-detail-label">{{ entry.label }}</div>
+ <div class="mc-detail-value">{{ entry.value }}</div>
+ </div>
+ </div>
+ </div>
</div>
- <div style="max-height: 55vh; overflow:auto;">
- <el-collapse v-model="activeNames" accordion>
- <el-collapse-item v-for="(item) in displayCrnList" :name="item.crnNo">
- <template slot="title">
- <div style="width: 100%;display: flex;">
- <div style="width: 50%;">{{ item.crnNo }}鍙峰爢鍨涙満</div>
- <div style="width: 50%;text-align: right;">
- <el-tag v-if="item.deviceStatus == 'AUTO'" type="success" size="small">鑷姩</el-tag>
- <el-tag v-else-if="item.deviceStatus == 'WORKING'" size="small">浣滀笟涓�</el-tag>
- <el-tag v-else-if="item.deviceStatus == 'ERROR'" type="danger" size="small">鏁呴殰</el-tag>
- <el-tag v-else type="warning" size="small">绂荤嚎</el-tag>
- </div>
- </div>
- </template>
- <el-descriptions border direction="vertical">
- <el-descriptions-item label="缂栧彿">{{ item.crnNo }}</el-descriptions-item>
- <el-descriptions-item label="宸ヤ綔鍙�">{{ item.workNo }}</el-descriptions-item>
- <el-descriptions-item label="妯″紡">{{ item.mode }}</el-descriptions-item>
- <el-descriptions-item label="鐘舵��">{{ item.status }}</el-descriptions-item>
- <el-descriptions-item label="婧愬簱浣�">{{ item.sourceLocNo }}</el-descriptions-item>
- <el-descriptions-item label="鐩爣搴撲綅">{{ item.locNo }}</el-descriptions-item>
- <el-descriptions-item label="鏄惁鏈夌墿">{{ item.loading }}</el-descriptions-item>
- <el-descriptions-item label="浠诲姟鎺ユ敹">{{ item.taskReceive }}</el-descriptions-item>
- <el-descriptions-item label="鍒�">{{ item.bay }}</el-descriptions-item>
- <el-descriptions-item label="灞�">{{ item.lev }}</el-descriptions-item>
- <el-descriptions-item label="璐у弶瀹氫綅">{{ item.forkOffset }}</el-descriptions-item>
- <el-descriptions-item label="杞借揣鍙板畾浣�">{{ item.liftPos }}</el-descriptions-item>
- <el-descriptions-item label="璧拌鍦ㄥ畾浣�">{{ item.walkPos }}</el-descriptions-item>
- <el-descriptions-item label="璧拌閫熷害锛坢/min)">{{ item.xspeed }}</el-descriptions-item>
- <el-descriptions-item label="鍗囬檷閫熷害锛坢/min)">{{ item.yspeed }}</el-descriptions-item>
- <el-descriptions-item label="鍙夌墮閫熷害锛坢/min)">{{ item.zspeed }}</el-descriptions-item>
- <el-descriptions-item label="璧拌璺濈(Km)">{{ item.xdistance }}</el-descriptions-item>
- <el-descriptions-item label="鍗囬檷璺濈(Km)">{{ item.ydistance }}</el-descriptions-item>
- <el-descriptions-item label="璧拌鏃堕暱(H)">{{ item.xduration }}</el-descriptions-item>
- <el-descriptions-item label="鍗囬檷鏃堕暱(H)">{{ item.yduration }}</el-descriptions-item>
- <el-descriptions-item label="绉伴噸鏁版嵁">{{ item.weight }}</el-descriptions-item>
- <el-descriptions-item label="鏉$爜鏁版嵁">{{ item.barcode }}</el-descriptions-item>
- <el-descriptions-item label="鏁呴殰浠g爜">{{ item.warnCode }}</el-descriptions-item>
- <el-descriptions-item label="鏁呴殰鎻忚堪">{{ item.alarm }}</el-descriptions-item>
- <el-descriptions-item label="鎵╁睍鏁版嵁">{{ item.extend }}</el-descriptions-item>
- </el-descriptions>
- </el-collapse-item>
- </el-collapse>
- </div>
- <div style="display:flex; justify-content:flex-end; margin-top:8px;">
- <el-pagination
- @current-change="handlePageChange"
- @size-change="handleSizeChange"
- :current-page="currentPage"
- :page-size="pageSize"
- :page-sizes="[10,20,50,100]"
- layout="total, prev, pager, next"
- :total="crnList.length">
- </el-pagination>
- </div>
+
+ <div v-if="displayCrnList.length === 0" class="mc-empty">褰撳墠娌℃湁鍙睍绀虹殑鍫嗗灈鏈烘暟鎹�</div>
+ </div>
+
+ <div class="mc-footer">
+ <button type="button" class="mc-page-btn" :disabled="currentPage <= 1" @click="handlePageChange(currentPage - 1)">涓婁竴椤�</button>
+ <span>{{ currentPage }} / {{ totalPages }}</span>
+ <button type="button" class="mc-page-btn" :disabled="currentPage >= totalPages" @click="handlePageChange(currentPage + 1)">涓嬩竴椤�</button>
+ </div>
</div>
- `,
+ `,
props: {
- param: {
- type: Object,
- default: () => ({})
- },
- autoRefresh: {
- type: Boolean,
- default: true
- },
- readOnly: {
- type: Boolean,
- default: false
- }
+ param: { type: Object, default: function () { return {}; } },
+ items: { type: Array, default: null },
+ autoRefresh: { type: Boolean, default: true },
+ readOnly: { type: Boolean, default: false }
},
- data() {
+ data: function () {
return {
crnList: [],
activeNames: "",
@@ -99,159 +89,176 @@
controlParam: {
crnNo: "",
sourceLocNo: "",
- targetLocNo: "",
+ targetLocNo: ""
},
- pageSize: 25,
+ pageSize: 12,
currentPage: 1,
timer: null
};
},
- created() {
- if (this.autoRefresh) {
- this.timer = setInterval(() => {
- this.getCrnStateInfo();
- }, 1000);
- }
- },
- beforeDestroy() {
- if (this.timer) {
- clearInterval(this.timer);
- }
- },
computed: {
- displayCrnList() {
- const start = (this.currentPage - 1) * this.pageSize;
- const end = start + this.pageSize;
- return this.crnList.slice(start, end);
+ sourceList: function () {
+ return Array.isArray(this.items) ? this.items : this.crnList;
+ },
+ filteredCrnList: function () {
+ var keyword = String(this.searchCrnNo || "").trim();
+ if (!keyword) {
+ return this.sourceList;
+ }
+ return this.sourceList.filter(function (item) {
+ return String(item.crnNo) === keyword;
+ });
+ },
+ displayCrnList: function () {
+ var start = (this.currentPage - 1) * this.pageSize;
+ return this.filteredCrnList.slice(start, start + this.pageSize);
+ },
+ totalPages: function () {
+ return Math.max(1, Math.ceil(this.filteredCrnList.length / this.pageSize) || 1);
}
},
watch: {
- param: {
- handler(newVal, oldVal) {
- if (newVal && newVal.crnNo && newVal.crnNo != 0) {
- this.activeNames = newVal.crnNo;
- this.searchCrnNo = newVal.crnNo;
- const idx = this.crnList.findIndex(i => i.crnNo == newVal.crnNo);
- if (idx >= 0) { this.currentPage = Math.floor(idx / this.pageSize) + 1; }
- }
- },
- deep: true, // 娣卞害鐩戝惉宓屽灞炴��
- immediate: true, // 绔嬪嵆瑙﹀彂涓�娆★紙鍙�夛級
+ items: function () {
+ this.afterDataRefresh();
},
+ param: {
+ deep: true,
+ immediate: true,
+ handler: function (newVal) {
+ if (newVal && newVal.crnNo && newVal.crnNo !== 0) {
+ this.focusCrn(newVal.crnNo);
+ }
+ }
+ }
+ },
+ created: function () {
+ MonitorCardKit.ensureStyles();
+ if (this.autoRefresh) {
+ this.timer = setInterval(this.getCrnStateInfo, 1000);
+ }
+ },
+ beforeDestroy: function () {
+ if (this.timer) {
+ clearInterval(this.timer);
+ this.timer = null;
+ }
},
methods: {
- handlePageChange(page) {
+ orDash: function (value) {
+ return MonitorCardKit.orDash(value);
+ },
+ getStatusLabel: function (item) {
+ return MonitorCardKit.deviceStatusLabel(item && item.deviceStatus);
+ },
+ getStatusTone: function (item) {
+ return MonitorCardKit.statusTone(this.getStatusLabel(item));
+ },
+ isActive: function (crnNo) {
+ return String(this.activeNames) === String(crnNo);
+ },
+ toggleItem: function (item) {
+ var next = String(item.crnNo);
+ this.activeNames = this.activeNames === next ? "" : next;
+ },
+ focusCrn: function (crnNo) {
+ this.searchCrnNo = String(crnNo);
+ var index = this.filteredCrnList.findIndex(function (item) {
+ return String(item.crnNo) === String(crnNo);
+ });
+ if (index >= 0) {
+ this.currentPage = Math.floor(index / this.pageSize) + 1;
+ } else {
+ this.currentPage = 1;
+ }
+ this.activeNames = String(crnNo);
+ },
+ afterDataRefresh: function () {
+ if (this.currentPage > this.totalPages) {
+ this.currentPage = this.totalPages;
+ }
+ if (this.activeNames) {
+ var exists = this.filteredCrnList.some(function (item) {
+ return String(item.crnNo) === String(this.activeNames);
+ }, this);
+ if (!exists) {
+ this.activeNames = "";
+ }
+ }
+ },
+ handlePageChange: function (page) {
+ if (page < 1 || page > this.totalPages) {
+ return;
+ }
this.currentPage = page;
},
- handleSizeChange(size) {
- this.pageSize = size;
- this.currentPage = 1;
- },
- getCrnStateInfo() {
- if (this.$root.sendWs) {
+ getCrnStateInfo: function () {
+ if (this.$root && this.$root.sendWs) {
this.$root.sendWs(JSON.stringify({
- "url": "/crn/table/crn/state",
- "data": {}
+ url: "/crn/table/crn/state",
+ data: {}
}));
}
},
- setCrnList(res) {
- let that = this;
- if (res.code == 200) {
- let list = res.data;
-
- if (that.searchCrnNo == "") {
- that.crnList = list;
- } else {
- let tmp = [];
- list.forEach((item) => {
- if (item.crnNo == that.searchCrnNo) {
- tmp.push(item);
- }
- });
- that.crnList = tmp;
- that.currentPage = 1;
- }
+ setCrnList: function (res) {
+ if (res && res.code === 200) {
+ this.crnList = res.data || [];
+ this.afterDataRefresh();
}
},
- openControl() {
+ openControl: function () {
this.showControl = !this.showControl;
},
- controlCommandTransport() {
- let that = this;
- //鍙栨斁璐�
+ buildDetailEntries: function (item) {
+ return [
+ { label: "缂栧彿", value: this.orDash(item.crnNo) },
+ { label: "宸ヤ綔鍙�", value: this.orDash(item.workNo) },
+ { label: "妯″紡", value: this.orDash(item.mode) },
+ { label: "鐘舵��", value: this.orDash(item.status) },
+ { label: "婧愬簱浣�", value: this.orDash(item.sourceLocNo) },
+ { label: "鐩爣搴撲綅", value: this.orDash(item.locNo) },
+ { label: "鏄惁鏈夌墿", value: MonitorCardKit.yesNo(item.loading) },
+ { label: "浠诲姟鎺ユ敹", value: this.orDash(item.taskReceive) },
+ { label: "鍒�", value: this.orDash(item.bay) },
+ { label: "灞�", value: this.orDash(item.lev) },
+ { label: "璐у弶瀹氫綅", value: this.orDash(item.forkOffset) },
+ { label: "杞借揣鍙板畾浣�", value: this.orDash(item.liftPos) },
+ { label: "璧拌瀹氫綅", value: this.orDash(item.walkPos) },
+ { label: "璧拌閫熷害", value: this.orDash(item.xspeed) },
+ { label: "鍗囬檷閫熷害", value: this.orDash(item.yspeed) },
+ { label: "鍙夌墮閫熷害", value: this.orDash(item.zspeed) },
+ { label: "绉伴噸鏁版嵁", value: this.orDash(item.weight) },
+ { label: "鏉$爜鏁版嵁", value: this.orDash(item.barcode) },
+ { label: "鏁呴殰浠g爜", value: this.orDash(item.warnCode) },
+ { label: "鏁呴殰鎻忚堪", value: this.orDash(item.alarm) },
+ { label: "鎵╁睍鏁版嵁", value: this.orDash(item.extend) }
+ ];
+ },
+ postControl: function (url, payload) {
$.ajax({
- url: baseUrl + "/crn/command/take",
+ url: baseUrl + url,
headers: {
- token: localStorage.getItem("token"),
+ token: localStorage.getItem("token")
},
contentType: "application/json",
method: "post",
- data: JSON.stringify(that.controlParam),
- success: (res) => {
- if (res.code == 200) {
- that.$message({
- message: res.msg,
- type: "success",
- });
+ data: JSON.stringify(payload),
+ success: function (res) {
+ if (res && res.code === 200) {
+ MonitorCardKit.showMessage(this, res.msg || "鎿嶄綔鎴愬姛", "success");
} else {
- that.$message({
- message: res.msg,
- type: "warning",
- });
+ MonitorCardKit.showMessage(this, (res && res.msg) || "鎿嶄綔澶辫触", "warning");
}
- },
+ }.bind(this)
});
},
- controlCommandMove() {
- let that = this;
- $.ajax({
- url: baseUrl + "/crn/command/move",
- headers: {
- token: localStorage.getItem("token"),
- },
- contentType: "application/json",
- method: "post",
- data: JSON.stringify(that.controlParam),
- success: (res) => {
- if (res.code == 200) {
- that.$message({
- message: res.msg,
- type: "success",
- });
- } else {
- that.$message({
- message: res.msg,
- type: "warning",
- });
- }
- },
- });
+ controlCommandTransport: function () {
+ this.postControl("/crn/command/take", this.controlParam);
},
- controlCommandTaskComplete() {
- let that = this;
- $.ajax({
- url: baseUrl + "/crn/command/taskComplete",
- headers: {
- token: localStorage.getItem("token"),
- },
- contentType: "application/json",
- method: "post",
- data: JSON.stringify(that.controlParam),
- success: (res) => {
- if (res.code == 200) {
- that.$message({
- message: res.msg,
- type: "success",
- });
- } else {
- that.$message({
- message: res.msg,
- type: "warning",
- });
- }
- },
- });
+ controlCommandMove: function () {
+ this.postControl("/crn/command/move", this.controlParam);
},
- },
+ controlCommandTaskComplete: function () {
+ this.postControl("/crn/command/taskComplete", this.controlParam);
+ }
+ }
});
--
Gitblit v1.9.1