From 55f37ee6bb68d069f6b77ae73e106a2fc4b30686 Mon Sep 17 00:00:00 2001
From: Junjie <fallin.jie@qq.com>
Date: 星期六, 07 三月 2026 09:47:56 +0800
Subject: [PATCH] #

---
 src/main/webapp/components/WatchRgvCard.js |  385 ++++++++++++++++++++++++++++---------------------------
 1 files changed, 196 insertions(+), 189 deletions(-)

diff --git a/src/main/webapp/components/WatchRgvCard.js b/src/main/webapp/components/WatchRgvCard.js
index 86cf8ee..3c19e76 100644
--- a/src/main/webapp/components/WatchRgvCard.js
+++ b/src/main/webapp/components/WatchRgvCard.js
@@ -1,83 +1,86 @@
 Vue.component("watch-rgv-card", {
   template: `
-    <div>
-        <div style="display: flex;margin-bottom: 10px;">
-            <div style="width: 100%;">RGV鐩戞帶</div>
-            <div style="width: 100%;text-align: right;display: flex;">
-              <el-input size="mini" v-model="searchRgvNo" placeholder="璇疯緭鍏GV鍙�"></el-input>
-              <el-button @click="getRgvStateInfo" size="mini">鏌ヨ</el-button>
+    <div class="mc-root">
+      <div class="mc-toolbar">
+        <div class="mc-title">RGV鐩戞帶</div>
+        <div class="mc-search">
+          <input class="mc-input" v-model="searchRgvNo" placeholder="璇疯緭鍏GV鍙�" />
+          <button type="button" class="mc-btn mc-btn-ghost" @click="getRgvStateInfo">鏌ヨ</button>
+        </div>
+      </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">RGV鍙�</span>
+            <input class="mc-input" v-model="controlParam.rgvNo" placeholder="渚嬪 1" />
+          </label>
+          <label class="mc-field">
+            <span class="mc-field-label">婧愮偣</span>
+            <input class="mc-input" v-model="controlParam.sourcePos" placeholder="杈撳叆婧愮偣" />
+          </label>
+          <label class="mc-field mc-span-2">
+            <span class="mc-field-label">鐩爣鐐�</span>
+            <input class="mc-input" v-model="controlParam.targetPos" 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 displayRgvList"
+          :key="item.rgvNo"
+          :class="['mc-item', { 'is-open': isActive(item.rgvNo) }]"
+        >
+          <button type="button" class="mc-head" @click="toggleItem(item)">
+            <div class="mc-head-main">
+              <div class="mc-head-title">{{ item.rgvNo }}鍙稲GV</div>
+              <div class="mc-head-subtitle">杞ㄩ亾浣� {{ orDash(item.trackSiteNo) }} | 浠诲姟 {{ orDash(item.taskNo) }}</div>
             </div>
-        </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 class="mc-head-right">
+              <span :class="['mc-badge', 'is-' + getStatusTone(item)]">{{ getStatusLabel(item) }}</span>
+              <span class="mc-chevron">{{ isActive(item.rgvNo) ? '鈻�' : '鈻�' }}</span>
             </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.rgvNo" placeholder="RGV鍙�"></el-input></div>
-                <div style="margin-bottom: 10px;width: 33%;"><el-input size="mini" v-model="controlParam.sourcePos" placeholder="婧愮偣"></el-input></div>
-                <div style="margin-bottom: 10px;width: 33%;"><el-input size="mini" v-model="controlParam.targetPos" 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>
+          </button>
+
+          <div v-if="isActive(item.rgvNo)" 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 displayRgvList" :name="item.rgvNo">
-            <template slot="title">
-                <div style="width: 100%;display: flex;">
-                   <div style="width: 50%;">{{ item.rgvNo }}鍙稲GV</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.rgvNo }}</el-descriptions-item>
-                <el-descriptions-item label="宸ヤ綔鍙�">{{ item.taskNo }}</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.trackSiteNo }}</el-descriptions-item>
-                <el-descriptions-item label="鏄惁鏈夌墿">{{ item.loading }}</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="rgvList.length">
-          </el-pagination>
-        </div>
+
+        <div v-if="displayRgvList.length === 0" class="mc-empty">褰撳墠娌℃湁鍙睍绀虹殑RGV鏁版嵁</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 {
       rgvList: [],
       activeNames: "",
@@ -88,154 +91,158 @@
         sourcePos: "",
         targetPos: ""
       },
-      pageSize: 25,
+      pageSize: 12,
       currentPage: 1,
       timer: null
     };
   },
-  created() {
-    if (this.autoRefresh) {
-      this.timer = setInterval(() => {
-        this.getRgvStateInfo();
-      }, 1000);
-    }
-  },
-  beforeDestroy() {
-    if (this.timer) {
-      clearInterval(this.timer);
-    }
-  },
   computed: {
-    displayRgvList() {
-      const start = (this.currentPage - 1) * this.pageSize;
-      const end = start + this.pageSize;
-      return this.rgvList.slice(start, end);
+    sourceList: function () {
+      return Array.isArray(this.items) ? this.items : this.rgvList;
+    },
+    filteredRgvList: function () {
+      var keyword = String(this.searchRgvNo || "").trim();
+      if (!keyword) {
+        return this.sourceList;
+      }
+      return this.sourceList.filter(function (item) {
+        return String(item.rgvNo) === keyword;
+      });
+    },
+    displayRgvList: function () {
+      var start = (this.currentPage - 1) * this.pageSize;
+      return this.filteredRgvList.slice(start, start + this.pageSize);
+    },
+    totalPages: function () {
+      return Math.max(1, Math.ceil(this.filteredRgvList.length / this.pageSize) || 1);
     }
   },
   watch: {
-    param: {
-      handler(newVal) {
-        if (newVal && newVal.rgvNo && newVal.rgvNo != 0) {
-          this.activeNames = newVal.rgvNo;
-          const idx = this.rgvList.findIndex(i => i.rgvNo == newVal.rgvNo);
-          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.rgvNo && newVal.rgvNo !== 0) {
+          this.focusRgv(newVal.rgvNo);
+        }
+      }
+    }
+  },
+  created: function () {
+    MonitorCardKit.ensureStyles();
+    if (this.autoRefresh) {
+      this.timer = setInterval(this.getRgvStateInfo, 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 (rgvNo) {
+      return String(this.activeNames) === String(rgvNo);
+    },
+    toggleItem: function (item) {
+      var next = String(item.rgvNo);
+      this.activeNames = this.activeNames === next ? "" : next;
+    },
+    focusRgv: function (rgvNo) {
+      this.searchRgvNo = String(rgvNo);
+      var index = this.filteredRgvList.findIndex(function (item) {
+        return String(item.rgvNo) === String(rgvNo);
+      });
+      this.currentPage = index >= 0 ? Math.floor(index / this.pageSize) + 1 : 1;
+      this.activeNames = String(rgvNo);
+    },
+    afterDataRefresh: function () {
+      if (this.currentPage > this.totalPages) {
+        this.currentPage = this.totalPages;
+      }
+      if (this.activeNames) {
+        var exists = this.filteredRgvList.some(function (item) {
+          return String(item.rgvNo) === 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;
-    },
-    getRgvStateInfo() {
-      if (this.$root.sendWs) {
+    getRgvStateInfo: function () {
+      if (this.$root && this.$root.sendWs) {
         this.$root.sendWs(JSON.stringify({
-          "url": "/rgv/table/rgv/state",
-          "data": {}
+          url: "/rgv/table/rgv/state",
+          data: {}
         }));
       }
     },
-    setRgvList(res) {
-      let that = this;
-      if (res.code == 200) {
-        let list = res.data || [];
-        if (that.searchRgvNo == "") {
-          that.rgvList = list;
-        } else {
-          let tmp = [];
-          list.forEach((item) => {
-            if (item.rgvNo == that.searchRgvNo) {
-              tmp.push(item);
-            }
-          });
-          that.rgvList = tmp;
-          that.currentPage = 1;
-        }
+    setRgvList: function (res) {
+      if (res && res.code === 200) {
+        this.rgvList = res.data || [];
+        this.afterDataRefresh();
       }
     },
-    openControl() {
+    openControl: function () {
       this.showControl = !this.showControl;
     },
-    controlCommandTransport() {
-      let that = this;
+    buildDetailEntries: function (item) {
+      return [
+        { label: "缂栧彿", value: this.orDash(item.rgvNo) },
+        { label: "宸ヤ綔鍙�", value: this.orDash(item.taskNo) },
+        { label: "妯″紡", value: this.orDash(item.mode) },
+        { label: "鐘舵��", value: this.orDash(item.status) },
+        { label: "杞ㄩ亾浣�", value: this.orDash(item.trackSiteNo) },
+        { label: "鏄惁鏈夌墿", value: MonitorCardKit.yesNo(item.loading) },
+        { 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 + "/rgv/command/transport",
+        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 + "/rgv/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("/rgv/command/transport", this.controlParam);
     },
-    controlCommandTaskComplete() {
-      let that = this;
-      $.ajax({
-        url: baseUrl + "/rgv/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("/rgv/command/move", this.controlParam);
     },
-  },
+    controlCommandTaskComplete: function () {
+      this.postControl("/rgv/command/taskComplete", this.controlParam);
+    }
+  }
 });

--
Gitblit v1.9.1