懒羊羊
2024-03-13 b64ed2c784bde6dea9d18149ca706ebe532c857d
jcdm-ui/src/views/main/kb/stationTerminal/index.vue
@@ -1,38 +1,40 @@
<template>
  <div class="app-container">
   <el-row :gutter="5">
     <el-col :span="6">
     <el-col :span="7">
       <el-card shadow="never">
         <span class="head-font">工位编号 : {{headContent.processesCode}}</span>
       </el-card>
     </el-col>
     <el-col :span="6">
     <el-col :span="7">
       <el-card shadow="never">
         <span class="head-font">工位名称 : {{headContent.processesName}}</span>
       </el-card>
     </el-col>
     <el-col :span="12">
     <el-col :span="10">
       <el-card shadow="never">
         <span class="head-font">总成编码 : {{headContent.sfcCode}}</span>
         <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>
         <span class="head-font">产品序列号 : {{headContent.sfcCode}}</span>
<!--         <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 type="primary" style="float: right" icon="el-icon-search" size="mini" @click="serialLink">串口连接</el-button>
         <el-button @click="clearClick" style="float: right" type="danger" size="mini">清除</el-button>
       </el-card>
     </el-col>
   </el-row>
   <el-row :gutter="5" style="margin-top: 5px">
     <el-col :span="6" >
     <el-col :span="7" >
       <el-card class="bottom-card">
         <div slot="header" class="clearfix">
           <i class="el-icon-tickets"></i>
           <span style="font-weight: bold">当前工件信息</span>
         </div>
         <el-descriptions :column="1" :label-style="{'font-size': '15px'}" border :content-style="{'min-width': '150px'}">
         <el-descriptions :column="1" border :content-style="{'min-width': '140px'}">
<!--         <el-descriptions :column="1" :label-style="{'font-size': '15px'}" border :content-style="{'min-width': '150px'}">-->
           <el-descriptions-item label="工单编号">
               <span>{{workpieceInformation.workOrderCode}}</span>
               <span>{{workpieceInformation.workOrderNo}}</span>
           </el-descriptions-item>
           <el-descriptions-item label="产品编号">
           <el-descriptions-item label="产品序列号">
             <span>{{workpieceInformation.productCode}}</span>
           </el-descriptions-item>
           <el-descriptions-item label="产品型号">
@@ -41,9 +43,9 @@
           <el-descriptions-item label="产品名称">
             <span>{{workpieceInformation.productName}}</span>
           </el-descriptions-item>
           <el-descriptions-item label="节拍">
             <span>{{workpieceInformation.beat}}</span>
           </el-descriptions-item>
<!--           <el-descriptions-item label="节拍">-->
<!--             <span>{{workpieceInformation.beat}}</span>-->
<!--           </el-descriptions-item>-->
         </el-descriptions>
         <el-divider></el-divider>
         <el-row>
@@ -83,27 +85,27 @@
           </el-col>
         </el-row>
         <el-row style="margin-top: 20px">
           <el-col :span="12">
             <el-input v-model="serialPortContent" style="width: 150px;" placeholder="请输入内容"></el-input>
<!--         <el-row style="margin-top: 20px">-->
<!--           <el-col :span="12">-->
<!--             <el-input v-model="serialPortContent" style="width: 150px;" placeholder="请输入内容"></el-input>-->
           </el-col>
           <el-col :span="12">
             <el-button @click="serialPortMethod" type="primary">串口获取数据</el-button>
<!--           </el-col>-->
<!--           <el-col :span="12">-->
<!--             <el-button @click="serialPortMethod" type="primary">串口获取数据</el-button>-->
           </el-col>
         </el-row>
<!--           </el-col>-->
<!--         </el-row>-->
         <el-row style="margin-top: 20px">
             <el-button @click="Release" type="primary">放行</el-button>
         </el-row>
       </el-card>
     </el-col>
     <el-col :span="18">
     <el-col :span="17">
       <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-col :span="10">
             <el-table :cell-style="rowStyle" :data="formulaChildList">
               <el-table-column label="排序" width="60" align="center" prop="stepSort">
               </el-table-column>
@@ -111,7 +113,7 @@
               </el-table-column>
             </el-table>
           </el-col>
           <el-col :span="16">
           <el-col :span="14">
             <el-image style="height: 520px;width: 100%" :src="imgSrc"></el-image>
           </el-col>
         </el-tab-pane>
@@ -142,12 +144,154 @@
       </el-tabs>
     </el-col>
   </el-row>
    <el-dialog v-dialogpop-up :title="title" :visible.sync="open1" width="1000" append-to-body>
      <el-row
        type="flex"
        class="row-bg"
        justify="center"
        v-show="portsList.length === 0"
      >
        <el-col :span="7">
          <div style="margin-top: 400px">
          <span style="display: block">
            仅支持Chrome 89+或者Edge 89+浏览器(安全上下文(HTTPS)中可用)
          </span>
            <el-button type="primary" @click="obtainAuthorization">授权</el-button>
          </div>
        </el-col>
      </el-row>
      <el-form
        v-show="portsList.length > 0"
        ref="form1"
        :model="form1"
        label-width="100px">
        <el-row>
          <el-col :span="24"
          ><div>
            <el-form-item label="串口">
              <el-select
                v-model="form1.port"
                filterable
                placeholder="请选择串口"
                :disabled="isDisable"
              >
                <el-option
                  v-for="item in portsList"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value"
                >
                </el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="波特率">
              <el-autocomplete
                popper-class="my-autocomplete"
                v-model="form1.baudRate"
                :fetch-suggestions="querySearch"
                placeholder="请输入波特率"
                :disabled="isDisable"
              >
                <i class="el-icon-edit el-input__icon" slot="suffix"> </i>
                <template slot-scope="{ item }">
                  <div class="name">{{ item.value }}</div>
                  <span class="addr">{{ item.address }}</span>
                </template>
              </el-autocomplete>
            </el-form-item>
            <el-form-item label="数据位">
              <el-select
                v-model="form1.dataBits"
                placeholder="请选择数据位"
                :disabled="isDisable"
              >
                <el-option label="7" value="7"></el-option>
                <el-option label="8" value="8"></el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="停止位">
              <el-select
                v-model="form1.stopBits"
                placeholder="请选择停止位"
                :disabled="isDisable"
              >
                <el-option label="1" value="1"></el-option>
                <el-option label="2" value="2"></el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="校验位">
              <el-select
                v-model="form1.parity"
                placeholder="请选择校验位"
                :disabled="isDisable"
              >
                <el-option label="None" value="none"></el-option>
                <el-option label="Even" value="even"></el-option>
                <el-option label="Odd" value="odd"></el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="流控制">
              <el-select
                v-model="form1.flowControl"
                placeholder="请选择流控制"
                :disabled="isDisable"
              >
                <el-option label="None" value="none"></el-option>
                <el-option label="HardWare" value="hardware"></el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="显示历史">
              <el-switch
                v-model="form1.isShowHistory"
                @change="loadHistory"
              ></el-switch>
              <el-button
                type="danger"
                icon="el-icon-delete"
                circle
                title="清空历史"
                @click="clearHistory"
              ></el-button>
            </el-form-item>
            <el-form-item label="发送区设置" v-show="isShowSendArea">
              <el-form-item label="发送格式">
                <el-radio-group v-model="form1.type">
                  <el-radio label="1">ASCII</el-radio>
                  <el-radio label="2">HEX</el-radio>
                </el-radio-group>
              </el-form-item>
              <el-form-item label="发送信息">
                <el-input type="textarea" v-model="form1.sendMsg"></el-input>
              </el-form-item>
              <el-button type="primary" @click="sendCommon">发送</el-button>
            </el-form-item>
            <el-form-item>
              <el-button :type="btnType" @click="connectBtn">{{
                  btnText
                }}</el-button>
              <el-button type="info" @click="obtainAuthorization"
              >新增授权</el-button
              >
            </el-form-item>
          </div>
          </el-col>
        </el-row>
      </el-form>
    </el-dialog>
  </div>
</template>
<script>
import {listWorkReport} from "@/api/main/om/workReport/workReport";
import {listStationConf,getIpv4} from "@/api/main/sc/stationConf";
import {listFormulaChild, releaseCheck, updateResults, workpieceRelease} from "@/api/main/bs/formulaChild/formulaChild";
import MySerialPort from "@/utils/MySerialPort";
import USBDevice from "@/utils/usb.json";
import {listProductionOrde} from "@/api/main/om/productionOrde/productionOrde";
import {addPassingStationCollection} from "@/api/main/da/passingStationCollection/passingStationCollection";
import {addBasicParameters, addParamCollection} from "@/api/main/da/paramCollection/paramCollection";
export default {
  name: "stationTerminal",
@@ -168,10 +312,10 @@
      headContent: {
        processesCode: 'OP1010',
        processesName: '贴标机-贴码',
        sfcCode: '1000000000000001',
        sfcCode: '10',
      },
      workpieceInformation: {
        workOrderCode: null,
        workOrderNo: null,
        productCode: null,
        productModel: null,
        productName: null,
@@ -199,11 +343,34 @@
      },
      content: '',
      activeName: 'first',
      url: "ws://192.168.10.252:8080/websocket/message/",
      url: "ws://192.168.11.134:8080/websocket/message/",
      message: "",
      text_content: "",
      ws: null,
      inputValue: '9'
      inputValue: '9',
      open1: false,
      input: "",
      keepReading: true,
      form1: {
        baudRate: "9600",
        dataBits: "8",
        stopBits: "1",
        parity: "none",
        flowControl: "none",
        desc: "",
        type: "1",
        isShowHistory: false,
      },
      btnType: "primary",
      btnText: "连接串口",
      restaurants: [],
      portsList: [],
      isShowSendArea: false,
      readType: 1,
      title: "",
      passingStationForm: {},
    }
  },
  beforeDestroy() {
@@ -217,30 +384,68 @@
    // }, 3000);
  },
  mounted() {
    if ("serial" in navigator) {
      this.myserialport = new MySerialPort();
      this.getPorts();
      navigator.serial.addEventListener("connect", (e) => {
        this.$message.success("设备已连接");
        this.getPorts();
      });
      navigator.serial.addEventListener("disconnect", (e) => {
        this.$message.error("设备已断开");
      });
      this.restaurants = this.loadAll();
    } else {
      this.$message.error(
        "当前为HTTP模式或者浏览器版本过低,不支持网页连接串口"
      );
    }
  },
  computed: {
    isDisable() {
      return this.btnType === "danger";
    },
  },
  methods: {
    Release(){
      let formulaChildParams = {
        productCode: this.workpieceInformation.productCode,
        processesCode: this.headContent.processesCode
      }
      releaseCheck(formulaChildParams).then(response => {
        if(response.data === 0){
          //改变状态
          workpieceRelease(formulaChildParams).then(response => {
          });
          this.$message('放行成功!');
          this.formulaChildList = []
          this.getListFormulaChild()
        }else {
          this.$message('步骤未完成不许放行!');
        }
      });
    serialLink() {
      this.open1 = true
    },
    serialPortMethod(){
    Release(){
      // this.$message('portsList!'+this.portsList.length);
      if(this.btnType === "danger"){
        this.$message('连接了!');
      }else {
        this.$message('mei连接了!');
      }
      // //判断是否可以释放
      // let formulaChildParams = {
      //   productCode: this.workpieceInformation.productCode,
      //   processesCode: this.headContent.processesCode
      // }
      // releaseCheck(formulaChildParams).then(response => {
      //   if(response.data === 0){
      //     //改变状态
      //     workpieceRelease(formulaChildParams).then(response => {
      //     });
      //     this.$message('放行成功!');
      //     this.formulaChildList = []
      //     this.getListFormulaChild()
      //     // this.resetting()
      //   }else {
      //     this.$message('步骤未完成不许放行!');
      //   }
      // });
    },
    serialPortMethod(value){
      let formulaChildParams = {
        materialCode: this.serialPortContent
        materialCode: value,
        workOrderNo: this.workpieceInformation.workOrderNo,
        productCode: this.workpieceInformation.productCode,
        locationCode: this.headContent.processesCode,
        collectionTime: new Date()
      }
      updateResults(formulaChildParams).then(response => {
        this.getListFormulaChild()
@@ -279,12 +484,12 @@
      this.cakeLamp.startWork = 1
    },
    /** 查询报工记录 表列表 */
    /** 查询工单列表 */
    async getList() {
      await listWorkReport(this.queryParams).then(response => {
      await listProductionOrde(this.queryParams).then(response => {
        let rowsData = response.rows[0];
        console.log(rowsData)
        this.workpieceInformation.workOrderCode = rowsData.workOrderCode;
        this.workpieceInformation.workOrderNo = rowsData.workOrderNo;
        this.workpieceInformation.productCode = rowsData.productCode;
        this.workpieceInformation.productModel = rowsData.productModel;
        this.workpieceInformation.productName = rowsData.productName;
@@ -293,7 +498,24 @@
        }, 1000);
      });
      this.getListFormulaChild()
      this.addOverStationCollection()
    },
    /** 入站增加过站采集记录 **/
    addOverStationCollection(){
      this.passingStationForm = {
        id: null,
        workOrderNo: this.workpieceInformation.workOrderNo,
        productCode: this.workpieceInformation.productCode,
        locationCode: this.headContent.processesCode,
        model: this.workpieceInformation.productModel,
        productBarcode: this.headContent.sfcCode,
        inboundTime: new Date()
      }
      addPassingStationCollection(this.passingStationForm).then(response => {
      });
      addBasicParameters(this.passingStationForm).then(response => {
      });
    },
    allowRelease(){
      clearInterval(this.timer);
@@ -373,30 +595,241 @@
        this.$message('websocket连接成功!');
      };
      this.ws.onmessage = function (event) {
        self.text_content = event.data + "\n";
        console.log(event.data)
        if(event.data === "IN"){
          self.cakeLamp.InPlace = 1
        }else if(event.data === "OUT"){
          self.cakeLamp.release = 1
          setTimeout(() => {
            this.resetting()
          }, 2000); // 延时2秒触发
        }else if(event.data === 'TIGHTEN'){
          console.log('开始拧紧')
          this.formulaChildList = []
          self.getListFormulaChild()
        const DELAY_TIME = 2000;
        switch (event.data) {
          case "IN":
            self.cakeLamp.InPlace = 1;
            break;
          case "IN0":
            self.cakeLamp.InPlace = 0;
            break;
          case "OUT":
            self.cakeLamp.release = 1;
            setTimeout(() => {
              self.cakeLamp.InPlace = 0;
              self.cakeLamp.release = 0;
              self.cakeLamp.startWork = 0;
              self.cakeLamp.scanFinish = 0;
              self.Release();
            }, DELAY_TIME);
            break;
          case "TIGHTEN":
            this.formulaChildList = [];
            self.getListFormulaChild();
            break;
          default:
            break;
        }
      };
    },
    resetting() {
      this.cakeLamp = {
        InPlace: 0,
        release: 0,
        startWork: 0,
        scanFinish: 0,
    //接受数据的回调
    callBack(value) {
      if (this.form1.isShowHistory) this.form1.desc = this.readLi().join("");
      else {
        const scanValue = this.myserialport.hex2atostr(value).replace(/[\r\n]/g, '');
        // if (value.length > 0)
          // this.form1.desc = this.myserialport.hex2atostr(value);
        this.$message('扫码完成'+this.content);
        if (/T/.test(scanValue)) {
          console.log('字符串包含字母"T"');
          this.serialPortMethod(scanValue)
        } else {
          console.log('字符串不包含字母"T"');
          this.headContent.sfcCode = scanValue;
          this.queryParams.sfcCode = scanValue;
          this.getList()
          // this.getListFormulaChild()
          this.cakeLamp.scanFinish = 1
          this.cakeLamp.startWork = 1
        }
      }
    }
    },
    clearHistory() {
      this.form1.desc = "";
      this.myserialport.state.readValue = [];
    },
    loadHistory() {
      if (this.form1.isShowHistory) this.form1.desc = this.readLi().join("");
      else {
        let temp = this.readLi();
        if (temp.length > 0) this.form1.desc = temp[temp.length - 1].join("");
      }
    },
    readLi() {
      let readType = this.readType;
      return this.myserialport.state.readValue.map((items, index) => {
        const item = items.value;
        const type = items.type; // 1接收,2发送
        let body = [];
        if (item !== undefined) {
          let strArr = [];
          for (let hex of Array.from(item)) {
            strArr.push(hex.toString(16).toLocaleUpperCase());
          }
          if (strArr.includes("D") && strArr.includes("A")) {
            if (strArr.indexOf("A") - strArr.indexOf("D") === 1) {
              strArr.splice(strArr.indexOf("D"), 1);
              strArr.splice(strArr.indexOf("A"), 1, <br key={0} />);
            }
          }
          strArr = strArr.map((item) => {
            if (typeof item === "string") {
              if (readType === 1) {
                return this.myserialport.hex2a(parseInt(item, 16));
              } else if (readType === 2) {
                return item + " ";
              }
            }
            return item;
          });
          if (typeof strArr[strArr.length - 1] === "string") {
            strArr.push("\r\n");
          }
          body.push(strArr.join(""));
        }
        return body;
      });
    },
    //连接
    async connectBtn() {
      if (this.btnType === "primary") {
        try {
          this.myserialport.state.baudRate = this.form1.baudRate;
          this.myserialport.state.dataBits = this.form1.dataBits;
          this.myserialport.state.stopBits = this.form1.stopBits;
          this.myserialport.state.parity = this.form1.parity;
          this.myserialport.state.flowControl = this.form1.flowControl;
          await this.myserialport.openPort(this.form1.port, true, this.callBack);
        } catch (error) {
          this.$message.error("串口连接失败!请检查串口是否已被占用");
        }
        if (this.myserialport.state.isOpen) {
          this.$message.success("串口连接成功");
          this.open1 = false
          this.btnType = "danger";
          this.btnText = "关闭串口";
        }
      } else {
        this.myserialport.openPort(this.form1.port, false, this.callBack);
        this.$message.success("串口关闭成功");
        this.btnType = "primary";
        this.btnText = "连接串口";
      }
    },
    //授权
    async obtainAuthorization() {
      if ("serial" in navigator) {
        console.log("The Web Serial API is supported.");
        if (!this.myserialport) this.myserialport = new MySerialPort();
        try {
          await this.myserialport.handleRequestPort();
          this.$message.success("串口授权成功");
          this.getPortInfo(this.myserialport.state.ports);
        } catch (error) {
          this.$message.warning("未选择新串口授权!");
        }
      } else {
        this.$message.error(
          "当前为HTTP模式或者浏览器版本过低,不支持网页连接串口"
        );
      }
    },
    //串口列表初始化
    getPortInfo(portList) {
      this.portsList = [];
      portList.map((port, index) => {
        const { usbProductId, usbVendorId } = port.getInfo();
        if (usbProductId === undefined || usbVendorId === undefined) {
          this.portsList.push({ label: "未知设备" + index, value: index });
        } else {
          const usbVendor = USBDevice.filter(
            (item) => parseInt(item.vendor, 16) === usbVendorId
          );
          let usbProduct = [];
          if (usbVendor.length === 1) {
            usbProduct = usbVendor[0].devices.filter(
              (item) => parseInt(item.devid, 16) === usbProductId
            );
          }
          this.portsList.push({ label: usbProduct[0].devname, value: index });
        }
      });
    },
    // 发送
    async sendCommon() {
      if (this.myserialport.state.isOpen) {
        if (this.form1.sendMsg.length !== 0) {
          const writeType = this.form1.type;
          let value = this.form1.sendMsg;
          let arr = [];
          if (writeType === 1) {
            // ASCII
            for (let i = 0; i < value.length; i++) {
              arr.push(this.myserialport.a2hex(value[i]));
            }
          } else if (writeType === 2) {
            // HEX
            if (/^[0-9A-Fa-f]+$/.test(value) && value.length % 2 === 0) {
              for (let i = 0; i < value.length; i = i + 2) {
                arr.push(parseInt(value.substring(i, i + 2), 16));
              }
            } else {
              this.$message.error("格式错误");
              return;
            }
          }
          this.myserialport.writeText(arr);
        } else {
          this.$message.warning("请输入发送的信息");
        }
      } else {
        this.$message.warning("串口处于关闭状态,请连接串口");
      }
    },
    async getPorts() {
      await this.myserialport.getPorts();
      this.getPortInfo(this.myserialport.state.ports);
    },
    querySearch(queryString, cb) {
      var restaurants = this.restaurants;
      var results = queryString
        ? restaurants.filter(this.createFilter(queryString))
        : restaurants;
      // 调用 callback 返回建议列表的数据
      cb(results);
    },
    createFilter(queryString) {
      return (restaurant) => {
        return (
          restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) ===
          0
        );
      };
    },
    loadAll() {
      return [
        { value: "110" },
        { value: "300" },
        { value: "600" },
        { value: "1200" },
        { value: "2400" },
        { value: "4800" },
        { value: "7200" },
        { value: "9600" },
        { value: "14400" },
        { value: "19200" },
        { value: "28800" },
        { value: "38400" },
        { value: "56000" },
        { value: "57600" },
        { value: "76800" },
        { value: "115200" },
        { value: "230400" },
        { value: "460800" },
      ];
    },
  }
}
@@ -428,8 +861,8 @@
    }
  }
.head-font{
  font-weight: bold;
  font-size: 25px;
  /*font-weight: bold;*/
  /*font-size: 25px;*/
}
span{
  font-size: 15px;