wu
2024-10-15 865e425cdf7395fece0a53a6def75e2c84d6dbf0
Merge remote-tracking branch 'origin/master'
11个文件已修改
2个文件已添加
793 ■■■■ 已修改文件
.idea/vcs.xml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
JiuMuMesParent/common/servicebase/src/main/java/com/mes/service/ModbusTcp.java 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
JiuMuMesParent/common/servicebase/src/main/java/com/mes/service/PlcAgreement.java 56 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
JiuMuMesParent/common/servicebase/src/main/java/com/mes/service/PlcParameter.java 28 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
JiuMuMesParent/common/servicebase/src/main/java/com/mes/tools/HexConversion.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
JiuMuMesParent/moduleService/DeviceInteractionModule/src/main/java/com/mes/job/MarkingTask.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
JiuMuMesParent/moduleService/DeviceInteractionModule/src/main/resources/application.yml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
JiuMuMesParent/moduleService/DeviceInteractionModule/src/test/java/com/mes/DeviceInteractionModuleApplicationTest.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
JiuMuMesParent/moduleService/DeviceInteractionModule/target/classes/application.yml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/layout/MainErpView.vue 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/views/GlueDispenser/glueDispenser.vue 262 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/views/Marking/marking.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/views/SilkScreen/SilkScreen.vue 264 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/vcs.xml
@@ -2,6 +2,5 @@
<project version="4">
  <component name="VcsDirectoryMappings">
    <mapping directory="" vcs="Git" />
    <mapping directory="$PROJECT_DIR$/jiumu" vcs="Git" />
  </component>
</project>
JiuMuMesParent/common/servicebase/src/main/java/com/mes/service/ModbusTcp.java
@@ -1,14 +1,18 @@
package com.mes.service;
import com.mes.tools.HexConversion;
import com.mes.utils.HexUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
@@ -21,23 +25,87 @@
    private Map<String,PlcAgreement> plcAgreement=new LinkedHashMap<String,PlcAgreement>();
    private String Ip;
    private int Port;
    public Socket socket =null;//通讯
    ModbusTcp(){}
    ModbusTcp(String Ip,int Port){
    public ModbusTcp(String Ip,int Port){
        this.Ip=Ip;
        this.Port=Port;
        try {
            socket=new Socket(Ip,Port);
        }catch (UnknownHostException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    //连接
    //@Scheduled(fixedDelay = 1000)
    public void a()throws Exception{
        //read();
        log.info("123");
    }
    public int getValueInt(){
        return 0;
    //读取数据
    public void read(PlcAgreement plcAgreement)throws Exception{
        int bufSizes = 0;
        byte[] msgs = new byte[2048];
        //写入读取地址
        DataOutputStream outToServer = new DataOutputStream(socket.getOutputStream());
        outToServer.write(HexConversion.stringToInt(plcAgreement.requestHead));
        outToServer.flush();
        //读取内容
        DataInputStream in = new DataInputStream(socket.getInputStream());
        bufSizes = in.read(msgs);
        String message = HexConversion.byteToHexString(bufSizes, msgs);//十进制字节数组转十六进制字符串
        //获取参数值
        Map<String, PlcParameter> plcParameters=plcAgreement.getPlcParameters();
        for (String key:plcParameters.keySet()){
            PlcParameter plcParameter=plcParameters.get(key);
            if("bit".equals(plcParameter.getType())){
                byte font=msgs[plcParameter.getAddressStart()];
                String[] fontBitString=String.format("%8s", Integer.toBinaryString((int)font)).replace(" ", "0").split("");
                byte[] bit=new byte[1];
                bit[0]=Byte.parseByte(fontBitString[plcParameter.getAddressLength()]);
                plcParameter.setReadByte(bit);
            }else{
                plcParameter.setReadByte(Arrays.copyOfRange(msgs,plcParameter.getAddressStart(),(plcParameter.getAddressStart()+plcParameter.getAddressLength())));
            }
        }
    }
    public double getValueDouble(){
        return 0;
    //写入数据
    public void write(PlcParameter plcParameter){
        try {
            if (plcParameter.getWriteValue() != null && !"".equals(plcParameter.getWriteValue())) {
                //写入发送数据
                DataOutputStream out = new DataOutputStream(socket.getOutputStream());
                out.write(HexConversion.stringToInt(plcParameter.getWriteValue().toString()));
                out.flush();
            }
        } catch (IOException e) {
            log.info("写入数据异常");
            throw new RuntimeException(e);
        }
    }
    //写入数据
    public void write(String key,String writeValue)throws Exception{
        if (writeValue != null && !"".equals(writeValue)) {
            //写入发送数据
            DataOutputStream out = new DataOutputStream(socket.getOutputStream());
            out.write(HexConversion.stringToInt(writeValue));
            out.flush();
        }
    }
    //写
    public String message(String senddate, String address) {
        String Herd = "0110" + address;
        int length = senddate.length() / 4;
        String dates = Herd + HexUtil.intTo2ByteHex(length) + HexUtil.intTo1ByteHex(length * 2) + senddate;
        int lengths = dates.length() / 2;
        String date = "00000000" + HexUtil.intTo2ByteHex(lengths) + dates;
        return date;
    }
    public PlcAgreement getPlcAgreement(String key){
        return plcAgreement.get(key);
    }
}
JiuMuMesParent/common/servicebase/src/main/java/com/mes/service/PlcAgreement.java
@@ -20,7 +20,7 @@
@Slf4j
public class PlcAgreement {
    public Socket socket =null;//通讯
    //public Socket socket =null;//通讯
    /**
     * 协议参数
     */
@@ -86,46 +86,22 @@
        }
        return false;
    }
    //读取数据
    public void read()throws Exception{
        int bufSizes = 0;
        byte[] msgs = new byte[2048];
        //写入读取地址
        DataOutputStream outToServer = new DataOutputStream(socket.getOutputStream());
        outToServer.write(HexConversion.stringToInt(this.requestHead));
        outToServer.flush();
        //读取内容
        DataInputStream in = new DataInputStream(socket.getInputStream());
        bufSizes = in.read(msgs);
        String message = HexConversion.byteToHexString(bufSizes, msgs);//十进制字节数组转十六进制字符串
        //获取参数值
        for (String key:parameters.keySet()){
            parameters.get(key).setReadValue(message);
    //获取此地址全部参数
    public Map<String,PlcParameter> getPlcParameters(){
        return parameters;
    }
    //通过参数名称获取
    public PlcParameter getPlcParameter(String name){
        return parameters.get(name);
    }
    //通过参数序号获取
    public PlcParameter getPlcParameter(int index){
        String key=parameterKeys.get(index);
        if(key!=null&& !key.isEmpty()){
            return this.getPlcParameter(key);
        }
    }
    //写入数据
    public void write(String key,String writeValue)throws Exception{
        parameters.get(key);
        if (writeValue != null && !"".equals(writeValue)) {
            //写入发送数据
            DataOutputStream out = new DataOutputStream(socket.getOutputStream());
            out.write(HexConversion.stringToInt(writeValue));
            out.flush();
        }
    }
    //写
    public String message(String senddate, String address) {
        String Herd = "0110" + address;
        int length = senddate.length() / 4;
        String dates = Herd + HexUtil.intTo2ByteHex(length) + HexUtil.intTo1ByteHex(length * 2) + senddate;
        int lengths = dates.length() / 2;
        String date = "00000000" + HexUtil.intTo2ByteHex(lengths) + dates;
        return date;
    }
    public String getValueString(String key){
        return parameters.get(key).toString();
        log.info("无效下标:{},下标范围:0-{}",index,parameterKeys.size());
        return null;
    }
    public int getValueInt(){
        return 0;
JiuMuMesParent/common/servicebase/src/main/java/com/mes/service/PlcParameter.java
@@ -28,7 +28,7 @@
    /**
     * 起始地址
     */
    private int addressIndex=0;
    private int addressStart=0;
    /**
     * 长度
     */
@@ -39,7 +39,11 @@
    private String type="int";
    /**
     * 实时读取的值
     * 实时读取的byte值
     */
    private byte[] readByte=null;
    /**
     * 实时读取的byte值转换成 对应类型
     */
    private Object readValue=null;
@@ -51,9 +55,9 @@
    PlcParameter(){
    }
    PlcParameter(String codeId, int addressIndex, int addressLength, String type){
    PlcParameter(String codeId, int addressStart, int addressLength, String type){
        this.CodeId=codeId;
        this.addressIndex=addressIndex;
        this.addressStart=addressStart;
        this.addressLength=addressLength;
        this.type=type;
    }
@@ -66,12 +70,12 @@
        CodeId = codeId;
    }
    public int getAddressIndex() {
        return addressIndex;
    public int getAddressStart() {
        return addressStart;
    }
    public void setAddressIndex(int addressIndex) {
        this.addressIndex = addressIndex;
    public void setAddressStart(int addressIndex) {
        this.addressStart = addressStart;
    }
    public int getAddressLength() {
@@ -98,6 +102,14 @@
        this.readValue = readValue;
    }
    public byte[] getReadByte() {
        return this.readByte;
    }
    public void setReadByte(byte[] readByte) {
        this.readByte = readByte;
    }
    public Object getWriteValue() {
        return writeValue;
    }
JiuMuMesParent/common/servicebase/src/main/java/com/mes/tools/HexConversion.java
@@ -52,4 +52,20 @@
        numberHex = String.format("%2s", numberHex).replace(' ', '0');
        return numberHex;
    }
    /**
     * 从byte数组中取int数值,本方法适用于(低位在前,高位在后)的顺序,和和intToBytes()配套使用
     *
     * @param src: byte数组
     * @param offset: 从数组的第offset位开始
     * @return int数值
     */
    public static int bytesToInt(byte[] src, int offset) {
        int value;
        value = (int) ((src[offset] & 0xFF)
                | ((src[offset+1] & 0xFF)<<8)
                | ((src[offset+2] & 0xFF)<<16)
                | ((src[offset+3] & 0xFF)<<24));
        return value;
    }
}
JiuMuMesParent/moduleService/DeviceInteractionModule/src/main/java/com/mes/job/MarkingTask.java
@@ -14,6 +14,9 @@
import com.mes.md.mapper.TaskingMapper;
import com.mes.md.mapper.WorkTaskDetailMapper;
import com.mes.md.service.TaskingService;
import com.mes.service.ModbusTcp;
import com.mes.service.PlcAgreement;
import com.mes.service.PlcParameter;
import com.mes.tools.WebSocketServer;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
@@ -47,33 +50,41 @@
    public void plcMarkingTask(Long machineId) {
        Machine machine=machineMapper.selectById(machineId);
        PlcParameterObject plcParameterObject = S7object.getinstance().PlcMesObject;
        String taskRequestTypeValue = plcParameterObject.getPlcParameter("A06_request_word").getValue();
        String glassIdeValue = plcParameterObject.getPlcParameter("A05_scanning_ID").getValue();
        String confirmationWrodValue = plcParameterObject.getPlcParameter("MES_confirmation_word").getValue();
        String confirmationWrodAddress = plcParameterObject.getPlcParameter("MES_confirmation_word").getAddress();
        String currentSlot = plcParameterObject.getPlcParameter("Current_slot").getValue();
        if ("0".equals(taskRequestTypeValue)) {
            if ("0".equals(confirmationWrodValue)) {
        ModbusTcp modbusTcp =new ModbusTcp(machine.getIp(),machine.getPort());
        PlcAgreement plcAgreement=modbusTcp.getPlcAgreement("DB14.0");
        PlcParameter plcRequest =plcAgreement.getPlcParameter(0);//请求字
        PlcParameter plcRequestID =plcAgreement.getPlcParameter(1);//请求ID
        PlcParameter mesSend =plcAgreement.getPlcParameter(10);//发送字
        PlcParameter mesSendID =plcAgreement.getPlcParameter(11);//发送ID
        PlcParameter plcReport =plcAgreement.getPlcParameter(0);//汇报字
        PlcParameter plcReportID =plcAgreement.getPlcParameter(1);//汇报ID
        PlcParameter mesConfirm =plcAgreement.getPlcParameter(10);//确认字
        PlcParameter mesConfirmID =plcAgreement.getPlcParameter(11);//确认ID
        plcRequest.getReadValue();
        if ("0".equals(plcRequest.getReadValue())) {
            if ("0".equals(mesSend.getReadValue())) {
                log.info("2、获取到的请求字为0,且发送字为0,不执行任务");
                return;
            }
            log.info("2、获取到的请求字为0,将发送字改为0");
            S7object.getinstance().plccontrol.writeWord(confirmationWrodAddress, 0);
            mesSend.setWriteValue("0");
            modbusTcp.write(mesSend);//向PLC发送
            return;
        }
        if (!"0".equals(confirmationWrodValue)) {
        if (!"0".equals(mesSend.getReadValue())) {
            log.info("2、获取到的请求字不为0,将发送字不为0,直接结束");
            return;
        }
        if ("1".equals(taskRequestTypeValue)) {
            log.info("2、进片请求,且发送字为0,执行打标任务");
            plcRequest(glassIdeValue, confirmationWrodAddress, currentSlot,machine);
        }else if ("3".equals(taskRequestTypeValue)) {
            log.info("2、完成请求,执行完成任务");
            plcReport(glassIdeValue, confirmationWrodAddress, currentSlot,machine);
        if ("1".equals(mesConfirm.getReadValue())&&"0".equals(mesConfirm.getReadValue())) {
            log.info("2、汇报请求,且确认字为0,完成打标任务");
            plcReport(mesConfirm,machine);
        }else if ("1".equals(plcRequest.getReadValue())) {
            log.info("2、任务请求,执行发送任务");
            plcRequest(mesSend,machine);
        }
    }
    public void plcRequest(String glassIdeValue, String confirmationWrodAddress, String currentSlot, Machine machine) {
    public void plcRequest(PlcParameter mesSend, Machine machine) {
        //查找打标机任务
        Tasking tasking=taskingService.startMachineTask(machine);
        if(tasking!=null&&"开工".equals(machine.getState())){//有任务
@@ -83,13 +94,12 @@
        }
    }
    public void plcReport(String glassIdeValue, String confirmationWrodAddress, String currentSlot, Machine machine) {
    public void plcReport(PlcParameter mesConfirm, Machine machine) {
        //查找打标机工作的任务
        //查找打标机任务
        int finishCount=taskingService.finishMachineTask(machine);
        if(finishCount>0){//数据已标记完成
            log.info("正常汇报:");
        }else{
            log.info("当前无共工作的任务,无效汇报完成!");
        }
JiuMuMesParent/moduleService/DeviceInteractionModule/src/main/resources/application.yml
@@ -8,8 +8,8 @@
    name: deviceInteraction
mybatis-plus:
  mapper-locations: classpath*:mapper/*.xml
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
#  configuration:
#    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
mes:
  threshold: 3
  ratio: 10
JiuMuMesParent/moduleService/DeviceInteractionModule/src/test/java/com/mes/DeviceInteractionModuleApplicationTest.java
@@ -2,6 +2,7 @@
import com.mes.md.mapper.AccountMapper;
import com.mes.md.service.AccountService;
import com.mes.tools.HexConversion;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -9,7 +10,10 @@
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;
/**
 * @Author : yanzhixin
@@ -35,6 +39,23 @@
        log.info("完整路径");
    }
    @Test
    public void testByte() {
        //String url = getClass().getResource("").getPath();
        //log.info("完整路径:{}", Arrays.asList(url));
        byte[] msgs = new byte[2048];
        msgs[0]=(byte)0;
        msgs[1]=Byte.parseByte("1") ;
        int g=HexConversion.bytesToInt(msgs,0);
        String message = HexConversion.byteToHexString(4, msgs);
        byte font=msgs[1];
        String[] fontBit=String.format("%8s", Integer.toBinaryString((int)font)).replace(" ", "0").split("");
        byte[] bit=new byte[1];
        bit[0]=Byte.parseByte(fontBit[7]) ;
        log.info("结果:{},{}",fontBit,bit);
        //log.info("结果:{},{},{},{},{}",msgs,message,g,(msgs[0] & 0xFF),((msgs[1] & 0xFF)<<8));
    }
    @Test
    public void testFindAccount() {
        Map<String, Object> Account=accountService.selectAccount("beibo","57858555");
        if(Account.isEmpty()){
@@ -43,4 +64,6 @@
        log.info("{}",Account);
    }
}
JiuMuMesParent/moduleService/DeviceInteractionModule/target/classes/application.yml
@@ -8,8 +8,8 @@
    name: deviceInteraction
mybatis-plus:
  mapper-locations: classpath*:mapper/*.xml
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
#  configuration:
#    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
mes:
  threshold: 3
  ratio: 10
UI-Project/src/layout/MainErpView.vue
@@ -5,7 +5,8 @@
import {ElMessage} from 'element-plus'
import {ref, watch, onMounted } from 'vue'
import deepClone from '@/utils/deepClone'
import { useRouter } from 'vue-router';
import { useRouter } from 'vue-router';
import { useI18n } from 'vue-i18n'
const userData = ref(null)
let menuList = $ref([])
@@ -130,6 +131,7 @@
                       @click="quit"
                       round>
              <el-icon size="large">
                <CirclePlus />
                <SwitchButton size=""/>{{ $t('main.quit') }}
              </el-icon>
            </el-button>
@@ -147,7 +149,7 @@
        <el-row :span="20">
            <el-menu :default-active="activePath" class="el-menu-vertical-demo" >
              <div class="menu">
            <div v-for="items in menuList">
            <div v-for="items in menuList" :key="items">
              <div class='menu_title' v-show="!isCollapse"
                   @click="openMenu(items.menu_id)">
                <span>☰</span>
@@ -155,7 +157,7 @@
              </div>
              <ul class='enter-x-left'
                  v-show="openFlag==items.menu_id">
                <li v-for="page in items.pages"
                <li v-for="page in items.pages" :key="page"
                    style="margin-bottom:2px">
                  <router-link :to="{path:page.page_url}">
                    {{ page.page_name }}
UI-Project/src/views/GlueDispenser/glueDispenser.vue
New file
@@ -0,0 +1,262 @@
<!--  点胶机  -->
<script setup>
import request from "@/utils/request";
import { ElMessage, ElMessageBox } from "element-plus";
import { reactive, ref, onMounted, onBeforeUnmount,onUnmounted } from 'vue'
import { useI18n } from 'vue-i18n'
import { WebSocketHost ,host} from '@/utils/constants'
import { initializeWebSocket, closeWebSocket } from '@/utils/WebSocketService';
let language = ref(localStorage.getItem('lang') || 'zh')
const { t } = useI18n()
const requestData = reactive({
  account: '',
  password: '',
});
const loadData = ref([]);
const findMachine = ref([]);
const machineId=15;//当前页面的设备ID
//使用WebSocket方式展示数据
let socket = null;
const socketUrl = `ws://${WebSocketHost}:${host}/api/deviceInteraction/api/talk/glueDispenser`;
// 定义消息处理函数,更新 receivedData 变量
const handleMessage = (data) => {
  // 更新 tableData 的数据
  loadData.value = data.taskingList[0];
  findMachine.value = data.machine[0];
};
onUnmounted(() => {
  if (socket) {
    closeWebSocket(socket);
  }
});
onBeforeUnmount(() => {
  console.log("关闭了")
  closeWebSocket();
});
onMounted(async () => {
  //使用WebSocket方式展示数据
  socket = initializeWebSocket(socketUrl, handleMessage);// 初始化 WebSocket,并传递消息处理函数
});
//修改工作状态 【失败/正在工作/完工】
const workStatus = async(row,state) => {
  let url;
  if(state=="重发"){
    url="/deviceInteraction/tasking/loseMachineTask";
  }else if(state=="正在工作"){
    url="/deviceInteraction/tasking/startMachineTask";
  }else if(state=="完工"){
    url="/deviceInteraction/tasking/finishMachineTask";
  }else{
    return;
  }
  ElMessageBox.confirm(
        t('functionState.tips'),
        t('delivery.prompt'),
        {
          confirmButtonText: t('functionState.sure'),
          cancelButtonText: t('functionState.cancel'),
          type: 'warning',
        }
      )
        .then(() => {
          //开始修改
          request.post(url,
            {
              "id": machineId
            }).then((res) => { // 替换为你的API端点
              if (res.code === 200) {
                ElMessage.success(res.message);
              } else {
                ElMessage.warning(res.message)
              }
            })
        })
        .catch(() => {
          ElMessage({
            type: 'info',
            message: t('functionState.cancel'),
          })
        })
}
//开工/暂停
const machineStatus = async(state) => {
  ElMessageBox.confirm(
        t('functionState.tips'),
        t('delivery.prompt'),
        {
          confirmButtonText: t('functionState.sure'),
          cancelButtonText: t('functionState.cancel'),
          type: 'warning',
        }
      )
        .then(() => {
          //下线接口
          request.post("/deviceInteraction/machine/updateMachineState",
            {
              "id": machineId,
              "state": state
            }).then((res) => { // 替换为你的API端点
              if (res.code === 200) {
                ElMessage.success(res.message);
              } else {
                ElMessage.warning(res.message)
              }
            })
        })
        .catch(() => {
          ElMessage({
            type: 'info',
            message: t('functionState.cancel'),
          })
        })
}
//破损
const damagedTask = async(row) => {
  ElMessageBox.confirm(
        t('functionState.tips'),
        t('delivery.prompt'),
        {
          confirmButtonText: t('functionState.sure'),
          cancelButtonText: t('functionState.cancel'),
          type: 'warning',
        }
      )
        .then(() => {
          //下线接口
          request.post("/deviceInteraction/tasking/damagedTask",
            {
              "glassId": row.glassId
            }).then((res) => { // 替换为你的API端点
              if (res.code === 200) {
                ElMessage.success(res.message);
              } else {
                ElMessage.warning(res.message)
              }
            })
        })
        .catch(() => {
          ElMessage({
            type: 'info',
            message: t('functionState.cancel'),
          })
        })
}
//下线(拿走)
const glassDownLine = async(row) => {
  ElMessageBox.confirm(
        t('functionState.tips'),
        t('delivery.prompt'),
        {
          confirmButtonText: t('functionState.sure'),
          cancelButtonText: t('functionState.cancel'),
          type: 'warning',
        }
      )
        .then(() => {
          //下线接口
          request.post("/deviceInteraction/tasking/glassDownLine",
            {
              "glassId": row.glassId,
            }).then((res) => { // 替换为你的API端点
              if (res.code === 200) {
                ElMessage.success(res.message);
              } else {
                ElMessage.warning(res.message)
              }
            })
        })
        .catch(() => {
          ElMessage({
            type: 'info',
            message: t('functionState.cancel'),
          })
        })
}
//上线
const topLine = async() => {
}
</script>
<template>
  <div ref="content" style="padding:0 20px;">
    <div id="div-title" style="font-size: 20px; font-weight: bold; margin:10px 0 10px 0;padding-left: 20px;">
      {{$t('machine.glueDispenser')}}
    </div>
    <hr />
    <br>
    <div id="search" >
      <!-- 功能 -->
      <el-button :type="(findMachine['state']=='暂停'?'danger':'success')" id="ButtonMachineStatus"
      @click="machineStatus((findMachine['state']=='暂停'?'开工':'暂停'))">
      {{findMachine['state']=='开工'?$t('functionState.start'):$t('functionState.stop')}}</el-button>
      <el-button type="primary" id="ButtonTopLine" @click="topLine">{{$t('functionState.topLine')}}</el-button>
    </div>
    <div id="main-body" style="min-height:240px;">
      <!-- 表格内容 -->
      <el-table :data="loadData" stripe
        :header-cell-style="{ background: '#F2F3F5 ', color: '#1D2129', textAlign: 'center' }"
        :cell-style="{ textAlign: 'center' }">
        <!-- <el-table-column type="selection" min-width="30" /> -->
        <el-table-column type="index" :label="$t('glassInfo.number')" min-width="30" />
        <el-table-column prop="batchNumber" :label="$t('glassInfo.batchNumber')"/>
        <el-table-column prop="taskType" :label="$t('glassInfo.taskType')"/>
        <el-table-column prop="glassId" :label="$t('glassInfo.glassId')"/>
        <el-table-column prop="length" :label="$t('glassInfo.length')"/>
        <el-table-column prop="width" :label="$t('glassInfo.width')"/>
        <el-table-column prop="thickness" :label="$t('glassInfo.thickness')"/>
        <el-table-column prop="workState" :label="$t('glassInfo.workState')"/>
        <el-table-column fixed="right" :label="$t('productStock.operate')" align="center" width="270">
          <template #default="scope">
            <el-button size="mini" link type="primary" plain @click="workStatus(scope.row, '重发')" >{{$t('functionState.anew')}}</el-button>
            <el-button size="mini" link type="primary" plain @click="workStatus(scope.row, '完工')">{{$t('functionState.finish')}}</el-button>
            <el-button size="mini" link type="primary" plain @click="damagedTask(scope.row)">{{$t('functionState.lose')}}</el-button>
            <el-button size="mini" link type="primary" plain @click="glassDownLine(scope.row)">{{$t('functionState.downLine')}}</el-button>
          </template>
        </el-table-column>
      </el-table>
    </div>
    <!-- <div id="main-body" style="width: 100%; height: 460px;background-image: url(../../src/assets/自动打标机.png) ;background-size: 100% 100%;"> -->
      <!-- 画图内容 -->
      <!-- <div style="width: 100px; height: 100px; background-color: red; position: relative; top: 171px; left: 218px">
      </div> -->
    <!-- </div> -->
  </div>
</template>
<style scoped>
table {
  text-align: center;
  width: 100%;
  height: 100%;
  border-collapse: collapse;
  border-spacing: 0;
}
table td {
  text-align: center;
}
#main-body {
  width: 100%;
  height: 100%;
  border: 1px solid #ccc;
  margin-top: 25px;
}
#searchButton {
  width: 100px;
  height: 40px;
  font-size: 16px;
  border-radius: 5px;
  background-color: #409EFF;
  color: #fff;
  border: none;
  cursor: pointer;
}
</style>
UI-Project/src/views/Marking/marking.vue
@@ -206,6 +206,7 @@
        :cell-style="{ textAlign: 'center' }">
        <!-- <el-table-column type="selection" min-width="30" /> -->
        <el-table-column type="index" :label="$t('glassInfo.number')" min-width="30" />
        <el-table-column prop="isMarking" :label="$t('glassInfo.isMarking')"/>
        <el-table-column prop="batchNumber" :label="$t('glassInfo.batchNumber')"/>
        <el-table-column prop="taskType" :label="$t('glassInfo.taskType')"/>
        <el-table-column prop="glassId" :label="$t('glassInfo.glassId')"/>
UI-Project/src/views/SilkScreen/SilkScreen.vue
New file
@@ -0,0 +1,264 @@
<!--  丝印机  -->
<script setup>
import request from "@/utils/request";
import { ElMessage, ElMessageBox } from "element-plus";
import { reactive, ref, onMounted, onBeforeUnmount,onUnmounted } from 'vue'
import { useI18n } from 'vue-i18n'
import { WebSocketHost ,host} from '@/utils/constants'
import { initializeWebSocket, closeWebSocket } from '@/utils/WebSocketService';
let language = ref(localStorage.getItem('lang') || 'zh')
const { t } = useI18n()
const requestData = reactive({
  account: '',
  password: '',
});
const loadData = ref([]);
const findMachine = ref([]);
const machineId=13;//当前页面的设备ID
//使用WebSocket方式展示数据
let socket = null;
const socketUrl = `ws://${WebSocketHost}:${host}/api/deviceInteraction/api/talk/silkScreen`;
// 定义消息处理函数,更新 receivedData 变量
const handleMessage = (data) => {
  // 更新 tableData 的数据
  loadData.value = data.taskingList[0];
  findMachine.value = data.machine[0];
};
onUnmounted(() => {
  if (socket) {
    closeWebSocket(socket);
  }
});
onBeforeUnmount(() => {
  console.log("关闭了")
  closeWebSocket();
});
onMounted(async () => {
  //使用WebSocket方式展示数据
  socket = initializeWebSocket(socketUrl, handleMessage);// 初始化 WebSocket,并传递消息处理函数
});
//修改工作状态 【失败/正在工作/完工】
const workStatus = async(row,state) => {
  let url;
  if(state=="重发"){
    url="/deviceInteraction/tasking/loseMachineTask";
  }else if(state=="正在工作"){
    url="/deviceInteraction/tasking/startMachineTask";
  }else if(state=="完工"){
    url="/deviceInteraction/tasking/finishMachineTask";
  }else{
    return;
  }
  ElMessageBox.confirm(
        t('functionState.tips'),
        t('delivery.prompt'),
        {
          confirmButtonText: t('functionState.sure'),
          cancelButtonText: t('functionState.cancel'),
          type: 'warning',
        }
      )
        .then(() => {
          //开始修改
          request.post(url,
            {
              "id": machineId
            }).then((res) => { // 替换为你的API端点
              if (res.code === 200) {
                ElMessage.success(res.message);
              } else {
                ElMessage.warning(res.message)
              }
            })
        })
        .catch(() => {
          ElMessage({
            type: 'info',
            message: t('functionState.cancel'),
          })
        })
}
//开工/暂停
const machineStatus = async(state) => {
  ElMessageBox.confirm(
        t('functionState.tips'),
        t('delivery.prompt'),
        {
          confirmButtonText: t('functionState.sure'),
          cancelButtonText: t('functionState.cancel'),
          type: 'warning',
        }
      )
        .then(() => {
          //下线接口
          request.post("/deviceInteraction/machine/updateMachineState",
            {
              "id": machineId,
              "state": state
            }).then((res) => { // 替换为你的API端点
              if (res.code === 200) {
                ElMessage.success(res.message);
              } else {
                ElMessage.warning(res.message)
              }
            })
        })
        .catch(() => {
          ElMessage({
            type: 'info',
            message: t('functionState.cancel'),
          })
        })
}
//破损
const damagedTask = async(row) => {
  ElMessageBox.confirm(
        t('functionState.tips'),
        t('delivery.prompt'),
        {
          confirmButtonText: t('functionState.sure'),
          cancelButtonText: t('functionState.cancel'),
          type: 'warning',
        }
      )
        .then(() => {
          //下线接口
          request.post("/deviceInteraction/tasking/damagedTask",
            {
              "glassId": row.glassId
            }).then((res) => { // 替换为你的API端点
              if (res.code === 200) {
                ElMessage.success(res.message);
              } else {
                ElMessage.warning(res.message)
              }
            })
        })
        .catch(() => {
          ElMessage({
            type: 'info',
            message: t('functionState.cancel'),
          })
        })
}
//下线(拿走)
const glassDownLine = async(row) => {
  ElMessageBox.confirm(
        t('functionState.tips'),
        t('delivery.prompt'),
        {
          confirmButtonText: t('functionState.sure'),
          cancelButtonText: t('functionState.cancel'),
          type: 'warning',
        }
      )
        .then(() => {
          //下线接口
          request.post("/deviceInteraction/tasking/glassDownLine",
            {
              "glassId": row.glassId,
            }).then((res) => { // 替换为你的API端点
              if (res.code === 200) {
                ElMessage.success(res.message);
              } else {
                ElMessage.warning(res.message)
              }
            })
        })
        .catch(() => {
          ElMessage({
            type: 'info',
            message: t('functionState.cancel'),
          })
        })
}
//上线
const topLine = async() => {
}
</script>
<template>
  <div ref="content" style="padding:0 20px;">
    <div id="div-title" style="font-size: 20px; font-weight: bold; margin:10px 0 10px 0;padding-left: 20px;">
      {{$t('machine.silkScreen')}}
    </div>
    <hr />
    <br>
    <div id="search" >
      <!-- 功能 -->
      <el-button :type="(findMachine['state']=='暂停'?'danger':'success')" id="ButtonMachineStatus"
      @click="machineStatus((findMachine['state']=='暂停'?'开工':'暂停'))">
      {{findMachine['state']=='开工'?$t('functionState.start'):$t('functionState.stop')}}</el-button>
      <el-button type="primary" id="ButtonTopLine" @click="topLine">{{$t('functionState.topLine')}}</el-button>
    </div>
    <div id="main-body" style="min-height:240px;">
      <!-- 表格内容 -->
      <el-table :data="loadData" stripe
        :header-cell-style="{ background: '#F2F3F5 ', color: '#1D2129', textAlign: 'center' }"
        :cell-style="{ textAlign: 'center' }">
        <!-- <el-table-column type="selection" min-width="30" /> -->
        <el-table-column type="index" :label="$t('glassInfo.number')" min-width="30" />
        <el-table-column prop="isSilkScreen" :label="$t('glassInfo.isSilkScreen')"/>
        <el-table-column prop="batchNumber" :label="$t('glassInfo.batchNumber')"/>
        <el-table-column prop="taskType" :label="$t('glassInfo.taskType')"/>
        <el-table-column prop="glassId" :label="$t('glassInfo.glassId')"/>
        <el-table-column prop="length" :label="$t('glassInfo.length')"/>
        <el-table-column prop="width" :label="$t('glassInfo.width')"/>
        <el-table-column prop="silkScreenX" :label="$t('glassInfo.silkScreenX')"/>
        <el-table-column prop="silkScreenY" :label="$t('glassInfo.silkScreenY')"/>
        <el-table-column prop="workState" :label="$t('glassInfo.workState')"/>
        <el-table-column fixed="right" :label="$t('productStock.operate')" align="center" width="270">
          <template #default="scope">
            <el-button size="mini" link type="primary" plain @click="workStatus(scope.row, '重发')" >{{$t('functionState.anew')}}</el-button>
            <el-button size="mini" link type="primary" plain @click="workStatus(scope.row, '完工')">{{$t('functionState.finish')}}</el-button>
            <el-button size="mini" link type="primary" plain @click="damagedTask(scope.row)">{{$t('functionState.lose')}}</el-button>
            <el-button size="mini" link type="primary" plain @click="glassDownLine(scope.row)">{{$t('functionState.downLine')}}</el-button>
          </template>
        </el-table-column>
      </el-table>
    </div>
    <div id="main-body"
      style="width: 100%; height: 460px;background-image: url(../../src/assets/a.png) ;background-size: 100% 100%;">
      <!-- 画图内容 -->
      <div style="width: 100px; height: 100px; background-color: red; position: relative; top: 171px; left: 218px">
      </div>
    </div>
  </div>
</template>
<style scoped>
table {
  text-align: center;
  width: 100%;
  height: 100%;
  border-collapse: collapse;
  border-spacing: 0;
}
table td {
  text-align: center;
}
#main-body {
  width: 100%;
  height: 100%;
  border: 1px solid #ccc;
  margin-top: 25px;
}
#searchButton {
  width: 100px;
  height: 40px;
  font-size: 16px;
  border-radius: 5px;
  background-color: #409EFF;
  color: #fff;
  border: none;
  cursor: pointer;
}
</style>