From 093982c9eb38fa51944975b0864d23e0f2942654 Mon Sep 17 00:00:00 2001 From: Junjie <540245094@qq.com> Date: 星期四, 21 八月 2025 10:36:42 +0800 Subject: [PATCH] # --- src/main/webapp/views/index.html | 3 src/main/webapp/views/lift.html | 454 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 457 insertions(+), 0 deletions(-) diff --git a/src/main/webapp/views/index.html b/src/main/webapp/views/index.html index ad86ad1..b4d18cf 100644 --- a/src/main/webapp/views/index.html +++ b/src/main/webapp/views/index.html @@ -42,6 +42,9 @@ }else if (id == "shuttle") { window.open('./shuttleNew.html') return + }else if (id == "lift") { + window.open('./lift.html') + return } $('.nav-select').attr("class", "nav-unselect"); $('#'+id).attr("class", "nav-select"); diff --git a/src/main/webapp/views/lift.html b/src/main/webapp/views/lift.html new file mode 100644 index 0000000..a2362b1 --- /dev/null +++ b/src/main/webapp/views/lift.html @@ -0,0 +1,454 @@ +<!DOCTYPE html> +<html lang="zh-CN"> +<head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>鎻愬崌鏈虹洃鎺х郴缁�</title> + <link rel="stylesheet" href="../static/vue/element/element.css"> + <link rel="stylesheet" href="../static/css/shuttle_page.min.css"> + <script src="../static/js/shuttle_page.js"></script> + <script type="text/javascript" src="../static/js/jquery/jquery-3.3.1.min.js"></script> + <script type="text/javascript" src="../static/js/common.js"></script> + <script type="text/javascript" src="../static/vue/js/vue.min.js"></script> + <script type="text/javascript" src="../static/vue/element/element.js"></script> + <style> + body { + font-family: 'Noto Sans SC', sans-serif; + background-color: #0f172a; + color: #e2e8f0; + } + .card { + background-color: #1e293b; + border-radius: 0.75rem; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); + transition: all 0.3s ease; + } + /*.card:hover {*/ + /* transform: translateY(-2px);*/ + /* box-shadow: 0 10px 15px rgba(0, 0, 0, 0.2);*/ + /*}*/ + .btn { + background-color: #3b82f6; + color: white; + border-radius: 0.5rem; + padding: 0.5rem 1rem; + transition: all 0.3s ease; + } + .btn:hover { + background-color: #2563eb; + transform: translateY(-1px); + } + .status-active { + color: #4ade80; + } + .status-inactive { + color: #f87171; + } + .progress-bar { + height: 0.75rem; + border-radius: 0.375rem; + background-color: #334155; + } + .progress-fill { + height: 100%; + border-radius: 0.375rem; + background-color: #4ade80; + transition: width 0.5s ease; + } + .table-striped tbody tr:nth-child(odd) { + background-color: #1e293b; + } + .table-striped tbody tr:nth-child(even) { + background-color: #1a2537; + } + </style> +</head> +<body class="min-h-screen"> + <div id="app"> + <div class="container mx-auto px-4 py-8"> + <!-- 椤堕儴鏍囬鍜岀姸鎬佹爮 --> + <div class="flex flex-col md:flex-row justify-between items-center mb-8"> + <h1 class="text-3xl font-bold text-blue-400 mb-4 md:mb-0"> + <i class="fas fa-robot mr-2"></i>鎻愬崌鏈虹洃鎺х郴缁� + </h1> + <div class="flex items-center space-x-4"> + <div class="flex items-center"> + <div class="w-3 h-3 rounded-full bg-green-500 mr-2"></div> + <span>鍦ㄧ嚎: {{ deviceStatusCountMap.online }}</span> + </div> + <div class="flex items-center"> + <div class="w-3 h-3 rounded-full bg-yellow-500 mr-2"></div> + <span>鏁呴殰: {{ deviceStatusCountMap.error }}</span> + </div> + <div class="flex items-center"> + <div class="w-3 h-3 rounded-full bg-red-500 mr-2"></div> + <span>绂荤嚎: {{ deviceStatusCountMap.offline }}</span> + </div> + </div> + </div> + + <!-- 涓昏鐩戞帶鍖哄煙 --> + <div class="card p-6 mb-8"> + <!-- 鎻愬崌鏈虹姸鎬佽〃鏍� --> + <div class="card p-6"> + <div class="flex justify-between items-center mb-4"> + <h2 class="text-xl font-semibold text-blue-300"> + <i class="fas fa-list-alt mr-2"></i>鎻愬崌鏈虹姸鎬� + </h2> + <div class="relative"> + <select v-model="selectListStatus" class="bg-slate-700 text-white rounded px-3 py-1 pr-8"> + <option value="all">鍏ㄩ儴鐘舵��</option> + <option value="online">鍦ㄧ嚎</option> + <option value="idle">绌洪棽</option> + <option value="running">杩愯涓�</option> + <option value="offline">绂荤嚎</option> + <option value="error">鏁呴殰</option> + </select> + </div> + </div> + <div class="overflow-auto" style="height: 500px;"> + <table class="w-full table-striped"> + <thead> + <tr class="text-left text-slate-300 border-b border-slate-600 bg-slate-800 sticky top-0 z-10"> + <th class="py-3 px-4">缂栧彿</th> + <th class="py-3 px-4">宸ヤ綔鍙�</th> + <th class="py-3 px-4">PLC宸ヤ綔鍙�</th> + <th class="py-3 px-4">璁惧妯″紡</th> + <th class="py-3 px-4">浠诲姟鐘舵��</th> + <th class="py-3 px-4">浠诲姟妯″紡</th> + <th class="py-3 px-4">鍙栬揣鏁版嵁</th> + <th class="py-3 px-4">鏀捐揣鏁版嵁</th> + <th class="py-3 px-4">鍑哄叆搴撴ā寮�</th> + <th class="py-3 px-4">鎵樼洏</th> + <th class="py-3 px-4">灏忚溅</th> + <th class="py-3 px-4">鏁呴殰鐮�</th> + <th class="py-3 px-4">灞�</th> + <th class="py-3 px-4">绔欑偣淇℃伅</th> + </tr> + </thead> + <tbody> + <tr v-for="(item,idx) in liftList" :key="idx" class="hover:bg-slate-700"> + <td class="py-3 px-4">{{ item.liftNo }}</td> + <td class="py-3 px-4">{{ item.taskNo }}</td> + <td class="py-3 px-4">{{ item.plcTaskNo }}</td> + <td class="py-3 px-4">{{ item.model$ }}</td> + <td class="py-3 px-4">{{ item.protocolStatus$ }}</td> + <td class="py-3 px-4">{{ item.taskMode$ }}</td> + <td class="py-3 px-4">{{ item.pick }}</td> + <td class="py-3 px-4">{{ item.put }}</td> + <td class="py-3 px-4">{{ item.iOMode$ }}</td> + <td class="py-3 px-4">{{ item.hasTray ? '鏈�':'鏃�' }}</td> + <td class="py-3 px-4">{{ item.hasCar ? '鏈�':'鏃�' }}</td> + <td class="py-3 px-4">{{ item.errorCode }}</td> + <td class="py-3 px-4">{{ item.lev }}</td> + <td class="py-3 px-4"> + <div v-for="(sta,id) in item.liftStaProtocols" :key="id"> + {{ sta.lev }}灞傦紝鎵樼洏锛歿{ sta.hasTray ? 'Y':'N' }}锛屽皬杞︼細{{ sta.hasCar ? 'Y':'N' }} + </div> + </td> + </tr> + </tbody> + </table> + </div> + </div> + </div> + + <!-- 鎿嶄綔鎺у埗鍖哄煙 --> + <div class="card p-6 mb-8"> + <h2 class="text-xl font-semibold text-blue-300 mb-4"> + <i class="fas fa-sliders-h mr-2"></i>鎺у埗闈㈡澘 + </h2> + <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-2 gap-2"> + <div class="bg-slate-700 p-4 rounded-lg"> + <h3 class="text-lg font-medium mb-2">璁惧鎺у埗</h3> + <div class="flex flex-wrap gap-2" style="display: flex;justify-content: center;"> + <div> + <el-input @change="changeControlLiftNo" v-model="controlData.liftNo" style="width: 150px;" placeholder="缂栧彿"></el-input> + </div> + <div> + <el-input v-model="controlData.sourceStaNo" style="width: 200px;" placeholder="婧愮珯"></el-input> + </div> + <div> + <el-input v-model="controlData.staNo" style="width: 200px;" placeholder="鐩爣绔�"></el-input> + </div> + </div> + </div> + <div class="bg-slate-700 p-4 rounded-lg"> + <h3 class="text-lg font-medium mb-2">璁惧鎸囦护</h3> + <div class="flex flex-wrap gap-2" style="display: flex;justify-content: center;"> + <button class="btn bg-slate-600 hover:bg-slate-500" @click="liftOperator('movePallet')"> + <i class="fas fa-level-up mr-1"></i>绉诲姩鎵樼洏 + </button> + <button class="btn bg-slate-600 hover:bg-slate-500" @click="liftOperator('switchShuttle')"> + <i class="fas fa-level-down mr-1"></i>灏忚溅鎹㈠眰 + </button> + <button class="btn bg-slate-600 hover:bg-slate-500" @click="liftOperator('move')"> + <i class="fas fa-battery-three-quarters mr-1"></i>绉诲姩 + </button> + <button class="btn bg-slate-600 hover:bg-slate-500" @click="liftOperator('reset')"> + <i class="fas fa-home mr-1"></i>澶嶄綅 + </button> + </div> + </div> + </div> + </div> + + </div> + </div> +</body> + +<script> + var app = new Vue({ + el: '#app', + data: { + ws: null, + liftList: [], //鎻愬崌鏈洪泦鍚� + liftAllList: [], + selectListStatus: "all", + deviceStatusCountMap: {}, + controlData: { + liftNo: "", + taskNo: "", + sourceLocNo: "", + targetLocNo: "" + }, + controlLiftInfo: null, + }, + created() { + this.init() + }, + watch: { + + }, + methods: { + init() { + this.consoleInterval = setInterval(() => { + this.websocketConnect(); + + this.getLiftStateInfo() //鑾峰彇鎻愬崌鏈轰俊鎭� + }, 1000) + }, + getLiftStateInfo() { + this.sendWs(JSON.stringify({ + "url": "/lift/table/lift/state", + "data": {} + })) + }, + setLiftStateInfo(res) { + // 鎻愬崌鏈轰俊鎭〃鑾峰彇 + if (res.code == 200) { + let list = res.data; + + let allList = [] + let runningList = [] + let idleList = [] + let errorList = [] + let offlineList = [] + let onlineList = [] + + list.forEach((item) => { + allList.push(item) + + if(item.protocolStatusType == "WORKING") { + runningList.push(item) + } + + if(item.protocolStatusType == "IDLE") { + idleList.push(item) + } + + if(item.errorCode > 0) { + errorList.push(item) + } + + if (item.protocolStatusType == "NONE") { + offlineList.push(item) + }else { + onlineList.push(item) + } + }) + + if (this.selectListStatus == "all") { + this.liftList = allList; + }else if (this.selectListStatus == "running") { + this.liftList = runningList; + }else if (this.selectListStatus == "idle") { + this.liftList = idleList; + }else if (this.selectListStatus == "error") { + this.liftList = errorList; + }else if (this.selectListStatus == "offline") { + this.liftList = offlineList; + }else if (this.selectListStatus == "online") { + this.liftList = onlineList; + } + + let tmpMap = { + idle: idleList.length, + running: runningList.length, + error: errorList.length, + offline: offlineList.length, + online: idleList.length + runningList.length, + } + this.deviceStatusCountMap = tmpMap; + + this.liftAllList = allList; + if (this.controlLiftInfo != null) { + allList.forEach((item) => { + if(item.liftNo == this.controlLiftInfo.liftNo) { + this.controlLiftInfo = item; + } + }); + } + } + }, + liftOperator(type) { + let that = this; + if (this.controlData.liftNo == null || this.controlData.liftNo == "") { + this.$message({ + message: '璇疯緭鍏ヨ澶囩紪鍙�', + type: 'warning' + }); + return; + } + + let requestParam = { + liftNo: this.controlData.liftNo + }; + + if (type == 'movePallet') { + if (this.controlData.sourceStaNo == null || this.controlData.sourceStaNo == "") { + this.$message({ + message: '璇疯緭鍏ユ簮绔�', + type: 'warning' + }); + return; + } + + if (this.controlData.staNo == null || this.controlData.staNo == "") { + this.$message({ + message: '璇疯緭鍏ョ洰鏍囩珯', + type: 'warning' + }); + return; + } + + requestParam.liftTaskMode = 1; + requestParam.sourceStaNo = this.controlData.sourceStaNo; + requestParam.staNo = this.controlData.staNo; + }else if (type == 'switchShuttle') { + if (this.controlData.sourceStaNo == null || this.controlData.sourceStaNo == "") { + this.$message({ + message: '璇疯緭鍏ユ簮绔�', + type: 'warning' + }); + return; + } + + if (this.controlData.staNo == null || this.controlData.staNo == "") { + this.$message({ + message: '璇疯緭鍏ョ洰鏍囩珯', + type: 'warning' + }); + return; + } + + requestParam.liftTaskMode = 2; + requestParam.sourceStaNo = this.controlData.sourceStaNo; + requestParam.staNo = this.controlData.staNo; + }else if (type == 'move') { + if (this.controlData.sourceStaNo == null || this.controlData.sourceStaNo == "") { + this.$message({ + message: '璇疯緭鍏ユ簮绔�', + type: 'warning' + }); + return; + } + + if (this.controlData.staNo == null || this.controlData.staNo == "") { + this.$message({ + message: '璇疯緭鍏ョ洰鏍囩珯', + type: 'warning' + }); + return; + } + + requestParam.liftTaskMode = 3; + requestParam.sourceStaNo = this.controlData.sourceStaNo; + requestParam.staNo = this.controlData.staNo; + }else if (type == 'reset') { + requestParam.liftTaskMode = 9996; + } + + $.ajax({ + url: baseUrl + "/lift/operator/lift", + headers: {'token': localStorage.getItem('token')}, + method: 'POST', + data: requestParam, + success: function (res) { + if (res.code === 200) { + that.$message({ + message: res.msg, + type: 'success' + }); + } else if (res.code === 403) { + window.location.href = baseUrl + "/login"; + } else { + that.$message({ + message: res.msg, + type: 'warning' + }); + } + } + }); + }, + changeControlLiftNo() { + let liftNo = this.controlData.liftNo; + if (liftNo == null || liftNo == "") { + this.controlLiftInfo = null + } + + this.liftAllList.forEach((item) => { + if (item.liftNo == liftNo) { + this.controlLiftInfo = item; + } + }); + }, + websocketConnect() { + if (this.ws == null) { + this.ws = new WebSocket("ws://" + window.location.host + baseUrl + "/console/websocket"); + this.ws.onopen = this.webSocketOnOpen + this.ws.onerror = this.webSocketOnError + this.ws.onmessage = this.webSocketOnMessage + this.ws.onclose = this.webSocketClose + } + }, + webSocketOnOpen(e) { + console.log("open"); + }, + webSocketOnError(e) { + this.ws = null; + console.log(e); + }, + webSocketOnMessage(e) { + const result = JSON.parse(e.data); + if (result.url == "/lift/table/lift/state") { + this.setLiftStateInfo(JSON.parse(result.data)) + } + }, + webSocketClose(e) { + this.ws = null; + console.log("close"); + }, + sendWs(message) { + if (this.ws == null) { + return; + } + + if (this.ws.readyState == WebSocket.OPEN) { + this.ws.send(message); + } + } + } + }) +</script> +</html> \ No newline at end of file -- Gitblit v1.9.1