春风项目四线(合箱线、总装线)
wujian
2024-10-23 2c65c31aceb16c1d06c692266e3fb555ecafdfb5
提交 | 用户 | 时间
3cef24 1 <template>
A 2   <div>
3     <el-row
4       type="flex"
5       class="row-bg"
6       justify="center"
7       v-show="portsList.length == 0"
8     >
9       <el-col :span="7"
10       ><div style="margin-top: 400px">
11           <span style="display: block">
12             仅支持Chrome 89+或者Edge 89+浏览器(安全上下文(HTTPS)中可用)
13           </span>
14         <el-button type="primary" @click="obtainAuthorization"
15         >授权</el-button
16         >
17       </div></el-col
18       >
19     </el-row>
20     <el-form
21       v-show="portsList.length > 0"
22       ref="form"
23       :model="form"
24       label-width="100px"
25     >
26       <el-row>
27         <el-col :span="6"
28         ><div>
29           <el-form-item label="串口">
30             <el-select
31               v-model="form.port"
32               filterable
33               placeholder="请选择串口"
34               :disabled="isDisable"
35             >
36               <el-option
37                 v-for="item in portsList"
38                 :key="item.value"
39                 :label="item.label"
40                 :value="item.value"
41               >
42               </el-option>
43             </el-select>
44           </el-form-item>
45           <el-form-item label="波特率">
46             <el-autocomplete
47               popper-class="my-autocomplete"
48               v-model="form.baudRate"
49               :fetch-suggestions="querySearch"
50               placeholder="请输入波特率"
51               :disabled="isDisable"
52             >
53               <i class="el-icon-edit el-input__icon" slot="suffix"> </i>
54               <template slot-scope="{ item }">
55                 <div class="name">{{ item.value }}</div>
56                 <span class="addr">{{ item.address }}</span>
57               </template>
58             </el-autocomplete>
59           </el-form-item>
60           <el-form-item label="数据位">
61             <el-select
62               v-model="form.dataBits"
63               placeholder="请选择数据位"
64               :disabled="isDisable"
65             >
66               <el-option label="7" value="7"></el-option>
67               <el-option label="8" value="8"></el-option>
68             </el-select>
69           </el-form-item>
70           <el-form-item label="停止位">
71             <el-select
72               v-model="form.stopBits"
73               placeholder="请选择停止位"
74               :disabled="isDisable"
75             >
76               <el-option label="1" value="1"></el-option>
77               <el-option label="2" value="2"></el-option>
78             </el-select>
79           </el-form-item>
80
81           <el-form-item label="校验位">
82             <el-select
83               v-model="form.parity"
84               placeholder="请选择校验位"
85               :disabled="isDisable"
86             >
87               <el-option label="None" value="none"></el-option>
88               <el-option label="Even" value="even"></el-option>
89               <el-option label="Odd" value="odd"></el-option>
90             </el-select>
91           </el-form-item>
92
93           <el-form-item label="流控制">
94             <el-select
95               v-model="form.flowControl"
96               placeholder="请选择流控制"
97               :disabled="isDisable"
98             >
99               <el-option label="None" value="none"></el-option>
100               <el-option label="HardWare" value="hardware"></el-option>
101             </el-select>
102           </el-form-item>
103           <el-form-item label="显示历史">
104             <el-switch
105               v-model="form.isShowHistory"
106               @change="loadHistory"
107             ></el-switch>
108             <el-button
109               type="danger"
110               icon="el-icon-delete"
111               circle
112               title="清空历史"
113               @click="clearHistory"
114             ></el-button>
115           </el-form-item>
116           <el-form-item label="发送区设置" v-show="isShowSendArea">
117             <el-form-item label="发送格式">
118               <el-radio-group v-model="form.type">
119                 <el-radio label="1">ASCII</el-radio>
120                 <el-radio label="2">HEX</el-radio>
121               </el-radio-group>
122             </el-form-item>
123             <el-form-item label="发送信息">
124               <el-input type="textarea" v-model="form.sendMsg"></el-input>
125             </el-form-item>
126             <el-button type="primary" @click="sendCommon">发送</el-button>
127           </el-form-item>
128
129           <el-form-item>
130             <el-button :type="btnType" @click="connectBtn">{{
131                 btnText
132               }}</el-button>
133             <el-button type="info" @click="obtainAuthorization"
134             >新增授权</el-button
135             >
136           </el-form-item>
137         </div>
138         </el-col>
139         <el-col :span="10"
140         ><div>
141           <el-form-item label="电子秤信息">
142             <el-input
143               type="textarea"
144               v-model="form.desc"
145               disabled
146               :autosize="{ minRows: 21, maxRows: 25 }"
147             ></el-input>
148           </el-form-item></div
149         ></el-col>
150       </el-row>
151     </el-form>
152   </div>
153 </template>
154
155 <script>
156 import MySerialPort from "@/utils/MySerialPort";
157 import USBDevice from "@/utils/usb.json";
158 export default {
159   data() {
160     return {
161       input: "",
162       keepReading: true,
163       form: {
164         baudRate: "9600",
165         dataBits: "8",
166         stopBits: "1",
167         parity: "none",
168         flowControl: "none",
169         desc: "",
170         type: "1",
171         isShowHistory: false,
172       },
173       btnType: "primary",
174       btnText: "连接串口",
175       restaurants: [],
176       portsList: [],
177       isShowSendArea: true,
178       readType: 1,
179     };
180   },
181   mounted() {
182     if ("serial" in navigator) {
183       this.myserialport = new MySerialPort();
184       this.getPorts();
185       navigator.serial.addEventListener("connect", (e) => {
186         this.$message.success("设备已连接");
187         this.getPorts();
188       });
189       navigator.serial.addEventListener("disconnect", (e) => {
190         this.$message.error("设备已断开");
191       });
192       this.restaurants = this.loadAll();
193     } else {
194       this.$message.error(
195         "当前为HTTP模式或者浏览器版本过低,不支持网页连接串口"
196       );
197     }
198   },
199   computed: {
200     isDisable() {
201       return this.btnType == "danger";
202     },
203   },
204   methods: {
205     //接受数据的回调
206     callBack(value) {
207       if (this.form.isShowHistory) this.form.desc = this.readLi().join("");
208       else {
209         if (value.length > 0)
210           this.form.desc = this.myserialport.hex2atostr(value);
211       }
212     },
213     clearHistory() {
214       this.form.desc = "";
215       this.myserialport.state.readValue = [];
216     },
217     loadHistory() {
218       if (this.form.isShowHistory) this.form.desc = this.readLi().join("");
219       else {
220         let temp = this.readLi();
221         if (temp.length > 0) this.form.desc = temp[temp.length - 1].join("");
222       }
223     },
224     readLi() {
225       let readType = this.readType;
226       return this.myserialport.state.readValue.map((items, index) => {
227         const item = items.value;
228         const type = items.type; // 1接收,2发送
229         let body = [];
230         if (item !== undefined) {
231           let strArr = [];
232           for (let hex of Array.from(item)) {
233             strArr.push(hex.toString(16).toLocaleUpperCase());
234           }
235           if (strArr.includes("D") && strArr.includes("A")) {
236             if (strArr.indexOf("A") - strArr.indexOf("D") === 1) {
237               strArr.splice(strArr.indexOf("D"), 1);
238               strArr.splice(strArr.indexOf("A"), 1, <br key={0} />);
239             }
240           }
241           strArr = strArr.map((item) => {
242             if (typeof item === "string") {
243               if (readType === 1) {
244                 return this.myserialport.hex2a(parseInt(item, 16));
245               } else if (readType === 2) {
246                 return item + " ";
247               }
248             }
249             return item;
250           });
251           if (typeof strArr[strArr.length - 1] === "string") {
252             strArr.push("\r\n");
253           }
254           body.push(strArr.join(""));
255         }
256         return body;
257       });
258     },
259     //连接
260     async connectBtn() {
261       if (this.btnType == "primary") {
262         try {
263           this.myserialport.state.baudRate = this.form.baudRate;
264           this.myserialport.state.dataBits = this.form.dataBits;
265           this.myserialport.state.stopBits = this.form.stopBits;
266           this.myserialport.state.parity = this.form.parity;
267           this.myserialport.state.flowControl = this.form.flowControl;
268           await this.myserialport.openPort(this.form.port, true, this.callBack);
269         } catch (error) {
270           this.$message.error("串口连接失败!请检查串口是否已被占用");
271         }
272         if (this.myserialport.state.isOpen) {
273           this.$message.success("串口连接成功");
274           this.btnType = "danger";
275           this.btnText = "关闭串口";
276         }
277       } else {
278         this.myserialport.openPort(this.form.port, false, this.callBack);
279         this.$message.success("串口关闭成功");
280         this.btnType = "primary";
281         this.btnText = "连接串口";
282       }
283     },
284     //授权
285     async obtainAuthorization() {
286       if ("serial" in navigator) {
287         console.log("The Web Serial API is supported.");
288         if (!this.myserialport) this.myserialport = new MySerialPort();
289         try {
290           await this.myserialport.handleRequestPort();
291           this.$message.success("串口授权成功");
292           this.getPortInfo(this.myserialport.state.ports);
293         } catch (error) {
294           this.$message.warning("未选择新串口授权!");
295         }
296       } else {
297         this.$message.error(
298           "当前为HTTP模式或者浏览器版本过低,不支持网页连接串口"
299         );
300       }
301     },
302     //串口列表初始化
303     getPortInfo(portList) {
304       this.portsList = [];
305       portList.map((port, index) => {
306         const { usbProductId, usbVendorId } = port.getInfo();
307         if (usbProductId === undefined || usbVendorId === undefined) {
308           this.portsList.push({ label: "未知设备" + index, value: index });
309         } else {
310           const usbVendor = USBDevice.filter(
311             (item) => parseInt(item.vendor, 16) === usbVendorId
312           );
313           let usbProduct = [];
314           if (usbVendor.length === 1) {
315             usbProduct = usbVendor[0].devices.filter(
316               (item) => parseInt(item.devid, 16) === usbProductId
317             );
318           }
319           this.portsList.push({ label: usbProduct[0].devname, value: index });
320         }
321       });
322     },
323     // 发送
324     async sendCommon() {
325       if (this.myserialport.state.isOpen) {
326         if (this.form.sendMsg.length !== 0) {
327           const writeType = this.form.type;
328           let value = this.form.sendMsg;
329           let arr = [];
330           if (writeType == 1) {
331             // ASCII
332             for (let i = 0; i < value.length; i++) {
333               arr.push(this.myserialport.a2hex(value[i]));
334             }
335           } else if (writeType == 2) {
336             // HEX
337             if (/^[0-9A-Fa-f]+$/.test(value) && value.length % 2 === 0) {
338               for (let i = 0; i < value.length; i = i + 2) {
339                 arr.push(parseInt(value.substring(i, i + 2), 16));
340               }
341             } else {
342               this.$message.error("格式错误");
343               return;
344             }
345           }
346           this.myserialport.writeText(arr);
347         } else {
348           this.$message.warning("请输入发送的信息");
349         }
350       } else {
351         this.$message.warning("串口处于关闭状态,请连接串口");
352       }
353     },
354     async getPorts() {
355       await this.myserialport.getPorts();
356       this.getPortInfo(this.myserialport.state.ports);
357     },
358     querySearch(queryString, cb) {
359       var restaurants = this.restaurants;
360       var results = queryString
361         ? restaurants.filter(this.createFilter(queryString))
362         : restaurants;
363       // 调用 callback 返回建议列表的数据
364       cb(results);
365     },
366     createFilter(queryString) {
367       return (restaurant) => {
368         return (
369           restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) ===
370           0
371         );
372       };
373     },
374     loadAll() {
375       return [
376         { value: "110" },
377         { value: "300" },
378         { value: "600" },
379         { value: "1200" },
380         { value: "2400" },
381         { value: "4800" },
382         { value: "7200" },
383         { value: "9600" },
384         { value: "14400" },
385         { value: "19200" },
386         { value: "28800" },
387         { value: "38400" },
388         { value: "56000" },
389         { value: "57600" },
390         { value: "76800" },
391         { value: "115200" },
392         { value: "230400" },
393         { value: "460800" },
394       ];
395     },
396   },
397 };
398 </script>
399
400 <style scoped>
401 /* ::v-deep .el-textarea__inner {
402   height: 320px !important;
403   width: 80% !important;
404 } */
405 </style>