From 5a6d6b9f3bb00b93e70d316c0fafcb34ddd0c510 Mon Sep 17 00:00:00 2001
From: 懒羊羊 <15939171744@163.com>
Date: 星期二, 09 一月 2024 14:25:13 +0800
Subject: [PATCH] 工位终端优化

---
 jcdm-framework/src/main/java/com/jcdm/framework/config/SecurityConfig.java     |    2 
 jcdm-framework/src/main/java/com/jcdm/framework/websocket/WebSocketConfig.java |   20 ++
 jcdm-ui/src/views/main/rm/repairData/index.vue                                 |    8 
 jcdm-ui/src/views/main/cfkb/Instructions/index.vue                             |    6 
 jcdm-framework/pom.xml                                                         |    6 
 jcdm-ui/src/views/main/kb/stationTerminal/index.vue                            |  110 ++++++++++--
 jcdm-framework/src/main/java/com/jcdm/framework/websocket/SemaphoreUtils.java  |   58 +++++++
 jcdm-framework/src/main/java/com/jcdm/framework/websocket/WebSocketUsers.java  |  140 +++++++++++++++++
 jcdm-framework/src/main/java/com/jcdm/framework/websocket/WebSocketServer.java |  103 ++++++++++++
 9 files changed, 424 insertions(+), 29 deletions(-)

diff --git a/jcdm-framework/pom.xml b/jcdm-framework/pom.xml
index 68ce210..396e795 100644
--- a/jcdm-framework/pom.xml
+++ b/jcdm-framework/pom.xml
@@ -59,6 +59,12 @@
             <artifactId>jcdm-system</artifactId>
         </dependency>
 
+        <!-- SpringBoot Websocket -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-websocket</artifactId>
+        </dependency>
+
     </dependencies>
 
 </project>
\ No newline at end of file
diff --git a/jcdm-framework/src/main/java/com/jcdm/framework/config/SecurityConfig.java b/jcdm-framework/src/main/java/com/jcdm/framework/config/SecurityConfig.java
index 353fda4..ea060a2 100644
--- a/jcdm-framework/src/main/java/com/jcdm/framework/config/SecurityConfig.java
+++ b/jcdm-framework/src/main/java/com/jcdm/framework/config/SecurityConfig.java
@@ -111,7 +111,7 @@
                 // 杩囨护璇锋眰
                 .authorizeRequests()
                 // 瀵逛簬鐧诲綍login 娉ㄥ唽register 楠岃瘉鐮乧aptchaImage 鍏佽鍖垮悕璁块棶
-                .antMatchers("/login", "/register", "/captchaImage").permitAll()
+                .antMatchers("/login", "/register", "/captchaImage","/websocket/**").permitAll()
                 // 闈欐�佽祫婧愶紝鍙尶鍚嶈闂�
                 .antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()
                 .antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()
diff --git a/jcdm-framework/src/main/java/com/jcdm/framework/websocket/SemaphoreUtils.java b/jcdm-framework/src/main/java/com/jcdm/framework/websocket/SemaphoreUtils.java
new file mode 100644
index 0000000..56eecbd
--- /dev/null
+++ b/jcdm-framework/src/main/java/com/jcdm/framework/websocket/SemaphoreUtils.java
@@ -0,0 +1,58 @@
+package com.jcdm.framework.websocket;
+
+import java.util.concurrent.Semaphore;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * 淇″彿閲忕浉鍏冲鐞�
+ * 
+ * @author ruoyi
+ */
+public class SemaphoreUtils
+{
+    /**
+     * SemaphoreUtils 鏃ュ織鎺у埗鍣�
+     */
+    private static final Logger LOGGER = LoggerFactory.getLogger(SemaphoreUtils.class);
+
+    /**
+     * 鑾峰彇淇″彿閲�
+     * 
+     * @param semaphore
+     * @return
+     */
+    public static boolean tryAcquire(Semaphore semaphore)
+    {
+        boolean flag = false;
+
+        try
+        {
+            flag = semaphore.tryAcquire();
+        }
+        catch (Exception e)
+        {
+            LOGGER.error("鑾峰彇淇″彿閲忓紓甯�", e);
+        }
+
+        return flag;
+    }
+
+    /**
+     * 閲婃斁淇″彿閲�
+     * 
+     * @param semaphore
+     */
+    public static void release(Semaphore semaphore)
+    {
+
+        try
+        {
+            semaphore.release();
+        }
+        catch (Exception e)
+        {
+            LOGGER.error("閲婃斁淇″彿閲忓紓甯�", e);
+        }
+    }
+}
diff --git a/jcdm-framework/src/main/java/com/jcdm/framework/websocket/WebSocketConfig.java b/jcdm-framework/src/main/java/com/jcdm/framework/websocket/WebSocketConfig.java
new file mode 100644
index 0000000..ab24e76
--- /dev/null
+++ b/jcdm-framework/src/main/java/com/jcdm/framework/websocket/WebSocketConfig.java
@@ -0,0 +1,20 @@
+package com.jcdm.framework.websocket;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.socket.server.standard.ServerEndpointExporter;
+
+/**
+ * websocket 閰嶇疆
+ * 
+ * @author ruoyi
+ */
+@Configuration
+public class WebSocketConfig
+{
+    @Bean
+    public ServerEndpointExporter serverEndpointExporter()
+    {
+        return new ServerEndpointExporter();
+    }
+}
diff --git a/jcdm-framework/src/main/java/com/jcdm/framework/websocket/WebSocketServer.java b/jcdm-framework/src/main/java/com/jcdm/framework/websocket/WebSocketServer.java
new file mode 100644
index 0000000..b2a1b6a
--- /dev/null
+++ b/jcdm-framework/src/main/java/com/jcdm/framework/websocket/WebSocketServer.java
@@ -0,0 +1,103 @@
+package com.jcdm.framework.websocket;
+
+import java.util.concurrent.Semaphore;
+import javax.websocket.OnClose;
+import javax.websocket.OnError;
+import javax.websocket.OnMessage;
+import javax.websocket.OnOpen;
+import javax.websocket.Session;
+import javax.websocket.server.ServerEndpoint;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+/**
+ * websocket 娑堟伅澶勭悊
+ * 
+ * @author ruoyi
+ */
+@Component
+@ServerEndpoint("/websocket/message")
+public class WebSocketServer
+{
+    /**
+     * WebSocketServer 鏃ュ織鎺у埗鍣�
+     */
+    private static final Logger LOGGER = LoggerFactory.getLogger(WebSocketServer.class);
+
+    /**
+     * 榛樿鏈�澶氬厑璁稿悓鏃跺湪绾夸汉鏁�100
+     */
+    public static int socketMaxOnlineCount = 100;
+
+    private static Semaphore socketSemaphore = new Semaphore(socketMaxOnlineCount);
+
+    /**
+     * 杩炴帴寤虹珛鎴愬姛璋冪敤鐨勬柟娉�
+     */
+    @OnOpen
+    public void onOpen(Session session) throws Exception
+    {
+        boolean semaphoreFlag = false;
+        // 灏濊瘯鑾峰彇淇″彿閲�
+        semaphoreFlag = SemaphoreUtils.tryAcquire(socketSemaphore);
+        if (!semaphoreFlag)
+        {
+            // 鏈幏鍙栧埌淇″彿閲�
+            LOGGER.error("\n 褰撳墠鍦ㄧ嚎浜烘暟瓒呰繃闄愬埗鏁�- {}", socketMaxOnlineCount);
+            WebSocketUsers.sendMessageToUserByText(session, "褰撳墠鍦ㄧ嚎浜烘暟瓒呰繃闄愬埗鏁帮細" + socketMaxOnlineCount);
+            session.close();
+        }
+        else
+        {
+            // 娣诲姞鐢ㄦ埛
+            WebSocketUsers.put(session.getId(), session);
+            LOGGER.info("\n 寤虹珛杩炴帴 - {}", session);
+            LOGGER.info("\n 褰撳墠浜烘暟 - {}", WebSocketUsers.getUsers().size());
+            WebSocketUsers.sendMessageToUserByText(session, "杩炴帴鎴愬姛");
+        }
+    }
+
+    /**
+     * 杩炴帴鍏抽棴鏃跺鐞�
+     */
+    @OnClose
+    public void onClose(Session session)
+    {
+        LOGGER.info("\n 鍏抽棴杩炴帴 - {}", session);
+        // 绉婚櫎鐢ㄦ埛
+        WebSocketUsers.remove(session.getId());
+        // 鑾峰彇鍒颁俊鍙烽噺鍒欓渶閲婃斁
+        SemaphoreUtils.release(socketSemaphore);
+    }
+
+    /**
+     * 鎶涘嚭寮傚父鏃跺鐞�
+     */
+    @OnError
+    public void onError(Session session, Throwable exception) throws Exception
+    {
+        if (session.isOpen())
+        {
+            // 鍏抽棴杩炴帴
+            session.close();
+        }
+        String sessionId = session.getId();
+        LOGGER.info("\n 杩炴帴寮傚父 - {}", sessionId);
+        LOGGER.info("\n 寮傚父淇℃伅 - {}", exception);
+        // 绉诲嚭鐢ㄦ埛
+        WebSocketUsers.remove(sessionId);
+        // 鑾峰彇鍒颁俊鍙烽噺鍒欓渶閲婃斁
+        SemaphoreUtils.release(socketSemaphore);
+    }
+
+    /**
+     * 鏈嶅姟鍣ㄦ帴鏀跺埌瀹㈡埛绔秷鎭椂璋冪敤鐨勬柟娉�
+     */
+    @OnMessage
+    public void onMessage(String message, Session session)
+    {
+        String msg = message.replace("浣�", "鎴�").replace("鍚�", "");
+        WebSocketUsers.sendMessageToUserByText(session, msg);
+    }
+}
diff --git a/jcdm-framework/src/main/java/com/jcdm/framework/websocket/WebSocketUsers.java b/jcdm-framework/src/main/java/com/jcdm/framework/websocket/WebSocketUsers.java
new file mode 100644
index 0000000..db0c715
--- /dev/null
+++ b/jcdm-framework/src/main/java/com/jcdm/framework/websocket/WebSocketUsers.java
@@ -0,0 +1,140 @@
+package com.jcdm.framework.websocket;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import javax.websocket.Session;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * websocket 瀹㈡埛绔敤鎴烽泦
+ * 
+ * @author ruoyi
+ */
+public class WebSocketUsers
+{
+    /**
+     * WebSocketUsers 鏃ュ織鎺у埗鍣�
+     */
+    private static final Logger LOGGER = LoggerFactory.getLogger(WebSocketUsers.class);
+
+    /**
+     * 鐢ㄦ埛闆�
+     */
+    private static Map<String, Session> USERS = new ConcurrentHashMap<String, Session>();
+
+    /**
+     * 瀛樺偍鐢ㄦ埛
+     *
+     * @param key 鍞竴閿�
+     * @param session 鐢ㄦ埛淇℃伅
+     */
+    public static void put(String key, Session session)
+    {
+        USERS.put(key, session);
+    }
+
+    /**
+     * 绉婚櫎鐢ㄦ埛
+     *
+     * @param session 鐢ㄦ埛淇℃伅
+     *
+     * @return 绉婚櫎缁撴灉
+     */
+    public static boolean remove(Session session)
+    {
+        String key = null;
+        boolean flag = USERS.containsValue(session);
+        if (flag)
+        {
+            Set<Map.Entry<String, Session>> entries = USERS.entrySet();
+            for (Map.Entry<String, Session> entry : entries)
+            {
+                Session value = entry.getValue();
+                if (value.equals(session))
+                {
+                    key = entry.getKey();
+                    break;
+                }
+            }
+        }
+        else
+        {
+            return true;
+        }
+        return remove(key);
+    }
+
+    /**
+     * 绉诲嚭鐢ㄦ埛
+     *
+     * @param key 閿�
+     */
+    public static boolean remove(String key)
+    {
+        LOGGER.info("\n 姝e湪绉诲嚭鐢ㄦ埛 - {}", key);
+        Session remove = USERS.remove(key);
+        if (remove != null)
+        {
+            boolean containsValue = USERS.containsValue(remove);
+            LOGGER.info("\n 绉诲嚭缁撴灉 - {}", containsValue ? "澶辫触" : "鎴愬姛");
+            return containsValue;
+        }
+        else
+        {
+            return true;
+        }
+    }
+
+    /**
+     * 鑾峰彇鍦ㄧ嚎鐢ㄦ埛鍒楄〃
+     *
+     * @return 杩斿洖鐢ㄦ埛闆嗗悎
+     */
+    public static Map<String, Session> getUsers()
+    {
+        return USERS;
+    }
+
+    /**
+     * 缇ゅ彂娑堟伅鏂囨湰娑堟伅
+     *
+     * @param message 娑堟伅鍐呭
+     */
+    public static void sendMessageToUsersByText(String message)
+    {
+        Collection<Session> values = USERS.values();
+        for (Session value : values)
+        {
+            sendMessageToUserByText(value, message);
+        }
+    }
+
+    /**
+     * 鍙戦�佹枃鏈秷鎭�
+     *
+     * @param userName 鑷繁鐨勭敤鎴峰悕
+     * @param message 娑堟伅鍐呭
+     */
+    public static void sendMessageToUserByText(Session session, String message)
+    {
+        if (session != null)
+        {
+            try
+            {
+                session.getBasicRemote().sendText(message);
+            }
+            catch (IOException e)
+            {
+                LOGGER.error("\n[鍙戦�佹秷鎭紓甯竇", e);
+            }
+        }
+        else
+        {
+            LOGGER.info("\n[浣犲凡绂荤嚎]");
+        }
+    }
+}
diff --git a/jcdm-ui/src/views/main/cfkb/Instructions/index.vue b/jcdm-ui/src/views/main/cfkb/Instructions/index.vue
index 7d33e70..2bf164b 100644
--- a/jcdm-ui/src/views/main/cfkb/Instructions/index.vue
+++ b/jcdm-ui/src/views/main/cfkb/Instructions/index.vue
@@ -75,7 +75,7 @@
 import {listFormulaChild} from "@/api/main/bs/formulaChild/formulaChild";
 
 export default {
-  name: "index",
+  name: "Instructions",
   data() {
     return {
       queryParams: {
@@ -144,6 +144,10 @@
     this.changeProducts(this.productCode)
     // this.autoShow()
   },
+  beforeDestroy() {
+    clearInterval(this.intervalId)
+    this.intervalId = null
+  },
   methods: {
     // 瀹氭椂瑙﹀彂
     autoShow() {
diff --git a/jcdm-ui/src/views/main/kb/stationTerminal/index.vue b/jcdm-ui/src/views/main/kb/stationTerminal/index.vue
index 6169b62..859fdc5 100644
--- a/jcdm-ui/src/views/main/kb/stationTerminal/index.vue
+++ b/jcdm-ui/src/views/main/kb/stationTerminal/index.vue
@@ -14,7 +14,7 @@
      <el-col :span="12">
        <el-card shadow="never">
          <span class="head-font">鎬绘垚缂栫爜 : {{headContent.sfcCode}}</span>
-         <el-input v-model="input" style="float: right;width: 150px;" placeholder="璇疯緭鍏ュ唴瀹�"></el-input>
+         <el-input v-model="content" style="float: right;width: 150px;" placeholder="璇疯緭鍏ュ唴瀹�"></el-input>
          <el-button @click="scanCompleted" style="float: right" type="primary">鎵爜瀹屾垚</el-button>
          <el-button @click="clearClick" style="float: right" type="danger">娓呴櫎</el-button>
        </el-card>
@@ -86,8 +86,8 @@
 
      </el-col>
      <el-col :span="18">
-       <el-tabs type="border-card"  style="height: 600px">
-         <el-tab-pane>
+       <el-tabs type="border-card"  style="height: 600px" v-model="activeName" @tab-click="changeMenu">
+         <el-tab-pane name="first">
            <span slot="label"> <a class="el-icon-date"></a>棣栭〉</span>
            <el-col :span="8">
              <el-table>
@@ -99,27 +99,27 @@
              <el-image style="height: 520px;width: 100%" :src="imgSrc"></el-image>
            </el-col>
          </el-tab-pane>
-         <el-tab-pane>
+         <el-tab-pane name="second">
            <span slot="label"> <b class="el-icon-date"></b>鐗╂枡BOM</span>
-           <el-empty >
+           <el-empty>
              <span slot="description">鏆傛棤鏁版嵁</span>
            </el-empty>
          </el-tab-pane>
-         <el-tab-pane>
-           <span slot="label"> <c class="el-icon-date"></c>閲囬泦娓呭崟</span>
-           <el-empty >
+         <el-tab-pane name="third">
+           <span slot="label"> <b class="el-icon-date"></b>閲囬泦娓呭崟</span>
+           <el-empty>
              <span slot="description">鏆傛棤鏁版嵁</span>
            </el-empty>
          </el-tab-pane>
-         <el-tab-pane>
-           <span slot="label"> <d class="el-icon-date"></d>瀹夌伅鐘舵��</span>
-           <el-empty >
+         <el-tab-pane name="fourth">
+           <span slot="label"> <b class="el-icon-date"></b>瀹夌伅鐘舵��</span>
+           <el-empty>
              <span slot="description">鏆傛棤鏁版嵁</span>
            </el-empty>
          </el-tab-pane>
-         <el-tab-pane>
-           <span slot="label"> <e class="el-icon-date"></e>宸ヨ壓閰嶆柟</span>
-           <el-empty >
+         <el-tab-pane name="fifth">
+           <span slot="label"> <b class="el-icon-date"></b>宸ヨ壓閰嶆柟</span>
+           <el-empty>
              <span slot="description">鏆傛棤鏁版嵁</span>
            </el-empty>
          </el-tab-pane>
@@ -137,7 +137,6 @@
   data() {
     return {
       ipAddress: '',
-      input: null,
       imgSrc: '',
       headContent: {
         processesCode: 'OP1010',
@@ -164,22 +163,26 @@
         scanFinish: 0,
         startWork: 0,
         release: 0 //鍏佽鏀捐
-      }
+      },
+      content: '',
+      activeName: 'first'
     }
   },
   created() {
-    this.getIPAddress();
     this.getStationConfList();
   },
   methods: {
+    changeMenu(tab, event) {
+      console.log(tab, event);
+    },
     clearClick(){
       this.$message('杩欐槸涓�鏉℃竻闄ゆ秷鎭彁绀�');
       this.headContent.sfcCode = null
     },
     scanCompleted(){
-      this.$message('鎵爜瀹屾垚'+this.input);
-      this.headContent.sfcCode = this.input
-      this.queryParams.sfcCode = this.input
+      this.$message('鎵爜瀹屾垚'+this.content);
+      this.headContent.sfcCode = this.content
+      this.queryParams.sfcCode = this.content
       this.getList()
       this.cakeLamp.scanFinish = 1
     },
@@ -200,9 +203,6 @@
       clearInterval(this.timer);
       this.$message('淇濆瓨鑺傛媿涓�'+this.workpieceInformation.beat+'绉�');
     },
-    getIPAddress() {
-      this.ipAddress = window.location.hostname;
-    },
     /** 鏌ヨ宸ヤ綅缁堢閰嶇疆鍒楄〃 */
     getStationConfList() {
       let queryParams = {
@@ -213,6 +213,10 @@
       });
       listStationConf(queryParams).then(response => {
         let rows = response.rows[0]
+        if(response.rows.length===0){
+          this.$message('鏀筰p娌掓湁閰嶇疆宸ュ簭宸ヤ綅锛岃珛閲嶈│锛�');
+          return
+        }
         this.headContent.processesName = rows.processesName
         this.headContent.processesCode = rows.processesCode
       });
@@ -255,3 +259,63 @@
   font-size: 15px;
 }
 </style>
+<!--<template>-->
+<!--  <div>-->
+<!--    <el-input v-model="url" type="text" style="width: 20%" /> &nbsp; &nbsp;-->
+<!--    <el-button @click="join" type="primary">杩炴帴</el-button>-->
+<!--    <el-button @click="exit" type="danger">鏂紑</el-button>-->
+
+<!--    <br />-->
+<!--    <el-input type="textarea" v-model="message" :rows="9" />-->
+<!--    <el-button type="info" @click="send">鍙戦�佹秷鎭�</el-button>-->
+<!--    <br />-->
+<!--    <br />-->
+<!--    <el-input type="textarea" v-model="text_content" :rows="9" /> 杩斿洖鍐呭-->
+<!--    <br />-->
+<!--    <br />-->
+<!--  </div>-->
+<!--</template>-->
+
+<!--<script>-->
+<!--export default {-->
+<!--  data() {-->
+<!--    return {-->
+<!--      url: "ws://127.0.0.1:8081/websocket/message",-->
+<!--      message: "",-->
+<!--      text_content: "",-->
+<!--      ws: null,-->
+<!--    };-->
+<!--  },-->
+<!--  methods: {-->
+<!--    join() {-->
+<!--      const wsuri = this.url;-->
+<!--      this.ws = new WebSocket(wsuri);-->
+<!--      const self = this;-->
+<!--      this.ws.onopen = function (event) {-->
+<!--        self.text_content = self.text_content + "宸茬粡鎵撳紑杩炴帴!" + "\n";-->
+<!--      };-->
+<!--      this.ws.onmessage = function (event) {-->
+<!--        console.log("鍚庣鍙戣繃鏉ョ殑娑堟伅"+event.data)-->
+<!--        self.text_content = event.data + "\n";-->
+<!--      };-->
+<!--      this.ws.onclose = function (event) {-->
+<!--        self.text_content = self.text_content + "宸茬粡鍏抽棴杩炴帴!" + "\n";-->
+<!--      };-->
+<!--    },-->
+<!--    exit() {-->
+<!--      if (this.ws) {-->
+<!--        this.ws.close();-->
+<!--        this.ws = null;-->
+<!--      }-->
+<!--    },-->
+<!--    send() {-->
+<!--      if (this.ws) {-->
+<!--        this.ws.send(this.message);-->
+<!--      } else {-->
+<!--        alert("鏈繛鎺ュ埌鏈嶅姟鍣�");-->
+<!--      }-->
+<!--    },-->
+<!--  },-->
+<!--};-->
+<!--</script>-->
+
diff --git a/jcdm-ui/src/views/main/rm/repairData/index.vue b/jcdm-ui/src/views/main/rm/repairData/index.vue
index 082f05f..dbaa47a 100644
--- a/jcdm-ui/src/views/main/rm/repairData/index.vue
+++ b/jcdm-ui/src/views/main/rm/repairData/index.vue
@@ -144,19 +144,19 @@
           </el-empty>
         </el-tab-pane>
         <el-tab-pane>
-          <span slot="label"> <c class="el-icon-date"></c>澶栨紡妫�娴�</span>
+          <span slot="label"> <b class="el-icon-date"></b>澶栨紡妫�娴�</span>
           <el-empty >
             <span slot="description">鏆傛棤鏁版嵁</span>
           </el-empty>
         </el-tab-pane>
         <el-tab-pane>
-          <span slot="label"> <d class="el-icon-date"></d>鏈鸿酱鍔犳敞</span>
+          <span slot="label"> <b class="el-icon-date"></b>鏈鸿酱鍔犳敞</span>
           <el-empty >
             <span slot="description">鏆傛棤鏁版嵁</span>
           </el-empty>
         </el-tab-pane>
         <el-tab-pane>
-          <span slot="label"> <e class="el-icon-date"></e>宸ヤ綅缁撴灉</span>
+          <span slot="label"> <b class="el-icon-date"></b>宸ヤ綅缁撴灉</span>
           <el-empty >
             <span slot="description">鏆傛棤鏁版嵁</span>
           </el-empty>
@@ -222,7 +222,7 @@
 import { listRepairData, getRepairData, delRepairData, addRepairData, updateRepairData } from "@/api/main/rm/repairData/repairData";
 
 export default {
-  name: "RepairData",
+  name: "rmRepairData",
   dicts: ['qualified_status'],
   data() {
     return {

--
Gitblit v1.9.3