wuyouming666
2024-05-24 03f241781205b4aaafa6cee66e7402a41ef97fc1
增加websocket 推送下片数据给前端
10个文件已修改
4个文件已添加
498 ■■■■■ 已修改文件
UI-Project/src/utils/WebSocketService.js 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/utils/constants.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/views/Returns/returns.vue 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/views/UnLoadGlass/Landingindication.vue 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/views/UnLoadGlass/Landingindicationtwo.vue 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/views/UnLoadGlass/loadmachinerack.vue 207 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/UnLoadGlassModule/pom.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/AppRunnerConfig.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/downworkstation/controller/DownWorkstationController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/job/DownCacheGlassTask.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/job/Downpush.java 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/tools/WebSocketConfig.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/tools/WebSocketServer.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/resources/application.yml 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/utils/WebSocketService.js
New file
@@ -0,0 +1,39 @@
// WebSocketService.js
let socket = null;
export const initializeWebSocket = (socketUrl, messageHandler) => {
    if (typeof WebSocket === "undefined") {
      console.log("Your browser does not support WebSocket");
      return null;
    }
    const socket = new WebSocket(socketUrl);
    socket.onopen = function () {
      console.log("WebSocket is now open");
    };
    socket.onmessage = (msg) => {
      if (!msg.data) {
        return;
      }
      const obj = JSON.parse(msg.data);
      // 调用消息处理函数,将数据传递给 Vue 组件
      if (messageHandler) {
        messageHandler(obj);
      }
    };
    return socket;
  };
  export const closeWebSocket = (socket) => {
    if (socket && socket.readyState === WebSocket.OPEN) {
        socket.close();
        console.log("WebSocket connection closed");
    }
};
UI-Project/src/utils/constants.js
New file
@@ -0,0 +1 @@
export const WebSocketHost = "localhost";
UI-Project/src/views/Returns/returns.vue
@@ -400,9 +400,10 @@
      ElMessage.success(response.message);
      // window.location.reload() 
      blinda.value = false;
      // tableData.value = response.data
      // tableData.value = [];
      state.updateKey ++
      tableData.splice([]);
    console.log(response)
    console.log(tableData)
      // state.updateKey ++
    } else {
      // 请求失败,显示错误消息
      ElMessage.error(response.msg);
UI-Project/src/views/UnLoadGlass/Landingindication.vue
@@ -32,9 +32,12 @@
</template>
<script  setup>
import { ref, watchEffect } from 'vue';
import { ref, watchEffect ,onMounted} from 'vue';
import Swal from 'sweetalert2'
import request from "@/utils/request";
import { initializeWebSocket } from '@/utils/WebSocketService';
 import { WebSocketHost } from '@/utils/constants';
const racks = ref([
  { x: 50, y: 100, height: 100, width: 60, fillColor: '#6a6da9', item: { height: 90, width: 10, fillColor: 'yellow', content: 'NG123456' } },
 
@@ -110,9 +113,40 @@
  }
};
fetchFlowCardId()
// setTimeout(fetchFlowCardId(),1000);
//setInterval(fetchFlowCardId, 2000)
const socketUrl = `ws://${WebSocketHost}:8085/api/talk/unloadglass2`;
// 定义消息处理函数,更新 receivedData 变量
const handleMessage = (data) => {
  // 更新 tableData 的数据
  data.glassinfo[0].forEach((itemData, index) => {
  if (index < racks.value.length) {
    const rack = racks.value[index];
    const newItem = {
      content: itemData.item.content,
      fillColor: itemData.item.fillColor,
      width: itemData.item.width === 0 ? "" : 10,
      height: itemData.item.height === 0 ? "" : 90
    };
    if (index === 2 && itemData.item.width > 0) {
      newItem.width = 100;
      newItem.height = 20;
    }
    rack.item = newItem;
   // console.log("显示图1",racks.value); // 打印更新后的 racks 值
  }
});
};
// 初始化 WebSocket,并传递消息处理函数
onMounted(() => {
  fetchFlowCardId(); // 获取数据
  initializeWebSocket(socketUrl, handleMessage);
});
const showCustomAlert = (content) => {
UI-Project/src/views/UnLoadGlass/Landingindicationtwo.vue
@@ -32,10 +32,12 @@
</template>
<script setup>
import { ref, watchEffect } from 'vue';
import { ref, watchEffect ,onMounted} from 'vue';
import Swal from 'sweetalert2'
import request from "@/utils/request";
import { initializeWebSocket } from '@/utils/WebSocketService';
 import { WebSocketHost } from '@/utils/constants';
const racks = ref([
  { x: 50, y: 100, height: 100, width: 60, fillColor: '#6a6da9', item: { height: 90, width: 10, fillColor: 'yellow', content: 'NG123456' } },
 
@@ -110,7 +112,41 @@
  }
};
fetchFlowCardId()
const socketUrl = `ws://${WebSocketHost}:8085/api/talk/unloadglass3`;
// 定义消息处理函数,更新 receivedData 变量
const handleMessage = (data) => {
  // 更新 tableData 的数据
  data.glassinfo2[0].forEach((itemData, index) => {
  if (index < racks.value.length) {
    const rack = racks.value[index];
    const newItem = {
      content: itemData.item.content,
      fillColor: itemData.item.fillColor,
      width: itemData.item.width === 0 ? "" : 10,
      height: itemData.item.height === 0 ? "" : 90
    };
    if (index === 2 && itemData.item.width > 0) {
      newItem.width = 100;
      newItem.height = 20;
    }
    rack.item = newItem;
    //console.log("显示图2",racks.value); // 打印更新后的 racks 值
  }
});
};
// 初始化 WebSocket,并传递消息处理函数
onMounted(() => {
  fetchFlowCardId(); // 获取数据
  initializeWebSocket(socketUrl, handleMessage);
});
// const showCustomAlert = (content) => {
//   var str="架号   :      111\n" +
UI-Project/src/views/UnLoadGlass/loadmachinerack.vue
@@ -1,6 +1,7 @@
<script setup>
import {Search} from "@element-plus/icons-vue";
import {reactive,  onMounted} from "vue";
import {reactive, onMounted, onBeforeUnmount} from "vue";
import {useRouter} from "vue-router"
const router = useRouter()
@@ -9,75 +10,24 @@
import Landingindication from "./Landingindication.vue";
import Landingindicationtwo from "./Landingindicationtwo.vue";
import request from "@/utils/request";
import { initializeWebSocket, closeWebSocket } from '@/utils/WebSocketService';
 import { WebSocketHost } from '@/utils/constants';
const dialogFormVisiblea = ref(false)
const dialogFormVisiblea2 = ref(false)
let socket;
const initWebSocket = (token) =>{ //初始化we
let viewname = "unloadglass";
if (typeof WebSocket === "undefined") {
  console.log("您的浏览器不支持WebSocket");
} else {
  let socketUrl = "ws://" + "localhost"+":88" + "/api/talk/" + viewname;
  if (socket != null) {
    socket.close();
    socket = null;
  }
  // 开启一个websocket服务
  socket = new WebSocket(socketUrl);
  // 打开事件
  socket.onopen = function () {
    console.log("websocket已打开");
  };
socket.onmessage = (msg) => {
if (!msg.data) {
return; // 如果收到空数据,则直接返回,不执行后续逻辑
}
    let obj = JSON.parse(msg.data);
      console.log('收到消息:', obj.data);
  }
  }
  }
// 数据
const loading = ref(false);
// 弹框显示控制
const dialogFormVisible = ref(false);
// 表单数据
const workstationId = ref('');
const flowCardId = ref('');
const flowCardOptions = ref([]);
const tableData = reactive([]);
// 方法
const handleSelectionChange = () => {
  // 处理表格行选择事件
@@ -85,15 +35,10 @@
const handleBindRack = (row) => {
  workstationId.value = row.workstationId; // 假设rackNumber是架号字段的属性名
  // 发起接口请求获取流程卡号
    fetchFlowCardId(); 
  dialogFormVisiblea.value = true; // 打开绑定架子对话框
};
//获取流程卡号
const fetchFlowCardId = async () => {
@@ -101,9 +46,12 @@
    const response = await request.get('unLoadGlass/downWorkStation/getflowCardId');
    console.log(response)
    if (response.code === 200) {
      flowCardOptions.value = response.data.map(item => ({ flowcard_id: item.flow_card_Id }));
      console.log(flowCardOptions.value)
    } else {
  flowCardOptions.value = response.data
    .filter(item => item !== null)
    .map(item => ({ flowcard_id: item.flow_card_Id }));
  console.log(flowCardOptions.value);
}
 else {
      ElMessage.error(response.msg);
    }
  } catch (error) {
@@ -141,19 +89,12 @@
  // 假设你的页面上有一个名为 tableData 的 Vue 组件
  // 你可以直接更新 tableData 的数据
  fetchTableData()
  // 使用 $forceUpdate() 强制更新组件
};
const handleBindRack2 = (row) => {
  workstationId.value = row.workstationId; // 假设rackNumber是架号字段的属性名
  dialogFormVisiblea2.value = true; // 打开绑定架子对话框
};
//清除内容
@@ -185,9 +126,6 @@
};
// 发送获取表格数据的请求
const fetchTableData = async () => {
  try {
@@ -210,89 +148,36 @@
};
const socketUrl = `ws://${WebSocketHost}:8085/api/talk/unloadglass`;
// 定义消息处理函数,更新 receivedData 变量
const handleMessage = (data) => {
  // 更新 tableData 的数据
  tableData.splice(0, tableData.length, ...data.params[0]);
 // console.log("更新后数据", tableData);
};
// 初始化 WebSocket,并传递消息处理函数
onMounted(() => {
  fetchFlowCardId();
  fetchTableData(); // 获取数据
  initializeWebSocket(socketUrl, handleMessage);
});
onBeforeUnmount(() => {
  console.log("关闭了")
  closeWebSocket();
});
// beforeUnmount(() => {
//   closeWebSocket();
// });
// initWebSocket();
onMounted(fetchTableData);
// setInterval(fetchTableData, 2000)
const open = () => {
  ElMessageBox.confirm(
    '是否删除该条信息?',
    '提示',
    {
      confirmButtonText: '是',
      cancelButtonText: '取消',
      type: 'warning',
    }
  )
    .then(() => {
      ElMessage({
        type: 'success',
        message: '删除成功!',
      })
    })
    .catch(() => {
      ElMessage({
        type: 'info',
        message: '删除失败',
      })
    })
}
const getTableRow = (row,type) =>{
  switch (type) {
    case 'edit' :{
      //alert('我接收到子组件传送的编辑信息')
      router.push({path: '/main/returns/createReturns', query: { ReturnID: 'TH24010101' }})
      break
    }
    case 'delete':{
      alert('我接收到子组件传送的删除信息')
      break
    }
  }
}
const gridOptions = reactive({
  border:  "full",//表格加边框
  keepSource: true,//保持源数据
  align: 'center',//文字居中
  stripe:true,//斑马纹
  rowConfig: {isCurrent: true, isHover: true,height: 50},//鼠标移动或选择高亮
  id: 'OrderList',
  showFooter: true,//显示脚
  printConfig: {},
  importConfig: {},
  exportConfig: {},
  scrollY:{ enabled: true },//开启虚拟滚动
  showOverflow:true,
  columnConfig: {
    resizable: true,
    useKey: true
  },
  filterConfig: {   //筛选配置项
    remote: true
  },
  customConfig: {
    storage: true
  },
  editConfig: {
    trigger: 'click',
    mode: 'row',
    showStatus: true
  },
  data:  [
    {
      'id': '1',
      'long': '5',
      'wide': '1005',
      'thick': '183.6',
    }
  ],
})
</script>
@@ -311,7 +196,19 @@
          <el-table-column prop="racksnumber" align="center" label="已落架数量" min-width="120" />
          <el-table-column prop="work_state" align="center" label="状态" min-width="120" />
          <el-table-column prop="deviceId" align="center" label="设备号" min-width="120" />
          <el-table-column prop="enableState" align="center" label="启用状态" min-width="120" />
          <el-table-column
            align="center"
            label="启用状态"
            min-width="80"
            prop="enableState"
          >
          <template #default="scope">
            <el-tag type="success" >{{ scope.row.enableState==1?"启用":"未启用"  }}</el-tag>
          </template>
          </el-table-column>
          <el-table-column fixed="right" label="操作" align="center" width="200">
            <template #default="scope">
            <el-button size="mini" type="text" plain v-show="scope.row.enableState !== '已启用' " @click="handleBindRack(scope.row)">绑定架子</el-button>
hangzhoumesParent/moduleService/UnLoadGlassModule/pom.xml
@@ -31,6 +31,11 @@
            <version>4.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>
    </dependencies>
    <properties>
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/AppRunnerConfig.java
@@ -20,7 +20,7 @@
    @Override
    public void run(ApplicationArguments args) throws Exception {
        log.info("启动完成");
        S7object.getinstance().start();
        //S7object.getinstance().start();
    }
}
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/downworkstation/controller/DownWorkstationController.java
@@ -149,7 +149,7 @@
        }
    }
    @ApiOperation("获取工位显示图1")
    @ApiOperation("获取工位显示图2")
    @GetMapping("/getwo2")
    public ResponseEntity<Map<String, Object>> getw2o() {
        Map<String, Object> responseData = new HashMap<>();
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/job/DownCacheGlassTask.java
@@ -2,6 +2,7 @@
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.mes.common.S7object;
import com.mes.common.config.Const;
@@ -21,6 +22,7 @@
import com.mes.glassinfo.service.GlassInfoService;
import com.mes.downglassinfo.entity.DownGlassTask;
import com.mes.downglassinfo.service.DownGlassTaskService;
import com.mes.tools.WebSocketServer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
@@ -28,6 +30,7 @@
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@@ -63,7 +66,7 @@
//    @Value("${mes.threshold}")
    private int threshold;
    //@Scheduled(fixedDelay = 1000)
  // @Scheduled(fixedDelay = 1000)
    public void plcdownGlassTask() {
   //   PlcParameterObject plcParameterObject = S7object.getinstance().PlcMesObject;
//        String taskRequestTypeValue = plcParameterObject.getPlcParameter("A06_request_word").getValue();
@@ -74,14 +77,14 @@
      // String G06RobotTaskRequestWord = plcParameterObject.getPlcParameter("G06RobotTaskRequestWord").getAddress();
                String taskRequestTypeValue ="3";
                String taskRequestTypeValue ="0";
        String glassIdeValue ="NG24041101C002-2-6-1-6";
        String confirmationWrodValue ="1";
        String outGlassstate="1";
        String confirmationWrodAddress="1";
        String G11RobotTaskRequestWord ="1";
        String G06RobotTaskRequestWord ="1";
        String G13RobotTaskRequestWord ="1";
        String G11RobotTaskRequestWord ="0";
        String G06RobotTaskRequestWord ="0";
        String G13RobotTaskRequestWord ="0";
                log.info("1、获取到的请求字为:{},获取到的扫描ID为:{},获取到的确认字为:{},获取到的出片状态为:{}",
                taskRequestTypeValue, glassIdeValue, confirmationWrodValue, outGlassstate);
@@ -127,6 +130,8 @@
    }
    /**
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/job/Downpush.java
New file
@@ -0,0 +1,68 @@
package com.mes.job;
import cn.hutool.json.JSONObject;
import com.mes.downworkstation.entity.DownWorkstation;
import com.mes.downworkstation.service.DownWorkstationService;
import com.mes.tools.WebSocketServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Slf4j
@Component
public class Downpush {
    @Autowired
    private DownWorkstationService downWorkstationService;
    @Scheduled(fixedDelay = 1000)
    public void Downpush() {
        JSONObject jsonObject = new JSONObject();
        JSONObject jsonObject2 = new JSONObject();
        JSONObject jsonObject3 = new JSONObject();
        List<DownWorkstation> data = downWorkstationService.getoneDownWorkstations(1,6);
        List<Map<String, Object>> glassinfodata = downWorkstationService.getTotalGlassDimensionsByWorkstation(1,3);
        List<Map<String, Object>> glassinfodata2 = downWorkstationService.getTotalGlassDimensionsByWorkstation(4,6);
        jsonObject.append("params",data);
        jsonObject2.append("glassinfo",glassinfodata);
        jsonObject3.append("glassinfo2",glassinfodata2);
        log.info(jsonObject.toString());
        ArrayList<WebSocketServer> sendwServer = WebSocketServer.sessionMap.get("unloadglass");
        ArrayList<WebSocketServer> sendwServer2 = WebSocketServer.sessionMap.get("unloadglass2");
        ArrayList<WebSocketServer> sendwServer3 = WebSocketServer.sessionMap.get("unloadglass3");
        //  log.info(sendwServer.toString());
        if (sendwServer != null) {
            for (WebSocketServer webserver : sendwServer) {
                if (webserver != null&&webserver.session.isOpen()) {
                    webserver.sendMessage(jsonObject.toString());
                }
            }
        }
        if (sendwServer2 != null) {
            for (WebSocketServer webserver : sendwServer2) {
                if (webserver != null&&webserver.session.isOpen()) {
                    webserver.sendMessage(jsonObject2.toString());
                }
            }
        }
        if (sendwServer3 != null) {
            for (WebSocketServer webserver : sendwServer3) {
                if (webserver != null&&webserver.session.isOpen()) {
                    webserver.sendMessage(jsonObject3.toString());
                }
            }
        }
    }
}
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/tools/WebSocketConfig.java
New file
@@ -0,0 +1,16 @@
package com.mes.tools;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
@Configuration
public class WebSocketConfig {
     @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/tools/WebSocketServer.java
@@ -1,28 +1,35 @@
package com.mes.tools;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.stereotype.Component;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
@ServerEndpoint(value = "/api/talk/{username}")
@Component("webSocketServer")
@Component
public class WebSocketServer {
    // @Autowired
    // HomeMapper homeMapper;
    public static ConfigurableApplicationContext applicationContext;
    static ConfigurableApplicationContext applicationContext;
    // 解决无法注入mapper问题 //使用方法
    // homeMapper=WebSocketServer.applicationContext.getBean(HomeMapper.class);
@@ -38,7 +45,7 @@
    public static final Map<String, ArrayList<WebSocketServer>> sessionMap = new ConcurrentHashMap<>();
    String username;
    Session session;
    public Session session;
    public WebSocketServer() {
        this.messages = new ArrayList<>();
@@ -58,6 +65,15 @@
            sessionMap.put(username, arrayListwebserver);
        } else {
            webSocketServers.add(this);
            // Short i=0;
            // for (WebSocketServer webSocketServer : webSocketServers) {
            //     if(webSocketServer==this){
            //         i++;
            //     }
            // }
            // if(i==0){
            //     webSocketServers.add(this);
            // }
        }
        log.info("有新用户加入,username={}, 当前在线人数为:{}", username, sessionMap.get(username).size());
@@ -81,15 +97,15 @@
    public void onClose(Session session, @PathParam("username") String username) {
        List<WebSocketServer> webSocketServers = sessionMap.get(username);
        ArrayList<WebSocketServer> arrayListwebserver = new ArrayList<WebSocketServer>();
        if (webSocketServers.size() > 1) {
        if (webSocketServers.size()>1) {
            for (WebSocketServer webSocketServer : webSocketServers) {
                if (webSocketServer != this) {
                if(webSocketServer!=this){
                    arrayListwebserver.add(webSocketServer);
                }
            }
            sessionMap.put(username, arrayListwebserver);
            log.info("移除username={}一名用户session, {}的当前在线人数为:{}", username, username, sessionMap.get(username).size());
        } else {
        }else{
            sessionMap.remove(username);
            log.info("移除username={}一名用户session, {}连接关闭, 当前连接数为:{}", username, username, sessionMap.size());
        }
@@ -157,6 +173,4 @@
    public void clearMessages() {
        messages.clear();
    }
}
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/resources/application.yml
@@ -6,6 +6,8 @@
    active: prod
  application:
    name: unLoadGlass
mybatis-plus:
  mapper-locations: classpath*:mapper/*.xml
  configuration: