| | |
| | | <div style="margin-bottom: 10px;width: 33%;"><el-input size="mini" v-model="controlParam.taskNo" placeholder="工作号"></el-input></div> |
| | | <div style="margin-bottom: 10px;width: 33%;"><el-input size="mini" v-model="controlParam.targetStationId" placeholder="目标站"></el-input></div> |
| | | <div style="margin-bottom: 10px;"><el-button @click="controlCommand()" size="mini">下发</el-button></div> |
| | | <div style="margin-bottom: 10px;"><el-button @click="resetCommand()" size="mini">复位</el-button></div> |
| | | </div> |
| | | </div> |
| | | <div style="max-height: 55vh; overflow:auto;"> |
| | |
| | | <el-descriptions-item label="运行阻塞">{{ item.runBlock ? 'Y' : 'N' }}</el-descriptions-item> |
| | | <el-descriptions-item label="启动入库">{{ item.enableIn ? 'Y' : 'N' }}</el-descriptions-item> |
| | | <el-descriptions-item label="托盘高度">{{ item.palletHeight }}</el-descriptions-item> |
| | | <el-descriptions-item label="条码">{{ item.barcode }}</el-descriptions-item> |
| | | <el-descriptions-item label="条码"> |
| | | <el-popover v-if="item.barcode" placement="top" width="460" trigger="hover"> |
| | | <div style="text-align: center;"> |
| | | <img |
| | | :src="getBarcodePreview(item.barcode)" |
| | | :alt="'barcode-' + item.barcode" |
| | | style="display: block; max-width: 100%; height: auto; margin: 0 auto; image-rendering: pixelated; background: #fff;" |
| | | /> |
| | | <div style="margin-top: 4px; font-size: 12px; word-break: break-all;">{{ item.barcode }}</div> |
| | | </div> |
| | | <span slot="reference" style="cursor: pointer; color: #409EFF;">{{ item.barcode }}</span> |
| | | </el-popover> |
| | | <span v-else>-</span> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="重量">{{ item.weight }}</el-descriptions-item> |
| | | <el-descriptions-item label="故障代码">{{ item.error }}</el-descriptions-item> |
| | | <el-descriptions-item label="故障信息">{{ item.errorMsg }}</el-descriptions-item> |
| | |
| | | taskNo: "", |
| | | targetStationId: "", |
| | | }, |
| | | barcodePreviewCache: {}, |
| | | pageSize: 25, |
| | | currentPage: 1, |
| | | timer: null |
| | |
| | | this.pageSize = size; |
| | | this.currentPage = 1; |
| | | }, |
| | | getBarcodePreview(barcode) { |
| | | const value = String(barcode || "").trim(); |
| | | if (!value) { |
| | | return ""; |
| | | } |
| | | if (this.barcodePreviewCache[value]) { |
| | | return this.barcodePreviewCache[value]; |
| | | } |
| | | const encodeResult = this.encodeCode128(value); |
| | | if (!encodeResult) { |
| | | return ""; |
| | | } |
| | | const svg = this.buildCode128Svg(encodeResult, value); |
| | | const dataUrl = "data:image/svg+xml;charset=UTF-8," + encodeURIComponent(svg); |
| | | this.$set(this.barcodePreviewCache, value, dataUrl); |
| | | return dataUrl; |
| | | }, |
| | | encodeCode128(value) { |
| | | if (!value) { |
| | | return null; |
| | | } |
| | | const isNumeric = /^\d+$/.test(value); |
| | | if (isNumeric && value.length % 2 === 0) { |
| | | return this.encodeCode128C(value); |
| | | } |
| | | return this.encodeCode128B(value); |
| | | }, |
| | | encodeCode128B(value) { |
| | | const codes = [104]; |
| | | for (let i = 0; i < value.length; i++) { |
| | | const code = value.charCodeAt(i) - 32; |
| | | if (code < 0 || code > 94) { |
| | | return null; |
| | | } |
| | | codes.push(code); |
| | | } |
| | | return this.buildCode128Pattern(codes); |
| | | }, |
| | | encodeCode128C(value) { |
| | | if (value.length % 2 !== 0) { |
| | | return null; |
| | | } |
| | | const codes = [105]; |
| | | for (let i = 0; i < value.length; i += 2) { |
| | | codes.push(parseInt(value.substring(i, i + 2), 10)); |
| | | } |
| | | return this.buildCode128Pattern(codes); |
| | | }, |
| | | buildCode128Pattern(codes) { |
| | | const patterns = this.getCode128Patterns(); |
| | | let checksum = codes[0]; |
| | | for (let i = 1; i < codes.length; i++) { |
| | | checksum += codes[i] * i; |
| | | } |
| | | const checkCode = checksum % 103; |
| | | const fullCodes = codes.concat([checkCode, 106]); |
| | | let bars = ""; |
| | | for (let i = 0; i < fullCodes.length; i++) { |
| | | const code = fullCodes[i]; |
| | | if (patterns[code] == null) { |
| | | return null; |
| | | } |
| | | bars += patterns[code]; |
| | | } |
| | | bars += "11"; |
| | | return bars; |
| | | }, |
| | | buildCode128Svg(bars, text) { |
| | | const quietModules = 20; |
| | | const modules = quietModules * 2 + bars.split("").reduce((sum, n) => sum + parseInt(n, 10), 0); |
| | | const moduleWidth = modules > 300 ? 1 : 2; |
| | | const width = modules * moduleWidth; |
| | | const barTop = 10; |
| | | const barHeight = 110; |
| | | let x = quietModules * moduleWidth; |
| | | let black = true; |
| | | let rects = ""; |
| | | for (let i = 0; i < bars.length; i++) { |
| | | const w = parseInt(bars[i], 10) * moduleWidth; |
| | | if (black) { |
| | | rects += '<rect x="' + x + '" y="' + barTop + '" width="' + w + '" height="' + barHeight + '" fill="#000" shape-rendering="crispEdges" />'; |
| | | } |
| | | x += w; |
| | | black = !black; |
| | | } |
| | | return ( |
| | | '<svg xmlns="http://www.w3.org/2000/svg" width="' + width + '" height="145" viewBox="0 0 ' + width + ' 145">' + |
| | | '<rect width="100%" height="100%" fill="#fff" />' + |
| | | rects + |
| | | '<text x="' + (width / 2) + '" y="136" text-anchor="middle" font-family="monospace" font-size="14" fill="#111">' + |
| | | this.escapeXml(text) + |
| | | "</text>" + |
| | | "</svg>" |
| | | ); |
| | | }, |
| | | getCode128Patterns() { |
| | | return [ |
| | | "212222", "222122", "222221", "121223", "121322", "131222", "122213", "122312", "132212", "221213", |
| | | "221312", "231212", "112232", "122132", "122231", "113222", "123122", "123221", "223211", "221132", |
| | | "221231", "213212", "223112", "312131", "311222", "321122", "321221", "312212", "322112", "322211", |
| | | "212123", "212321", "232121", "111323", "131123", "131321", "112313", "132113", "132311", "211313", |
| | | "231113", "231311", "112133", "112331", "132131", "113123", "113321", "133121", "313121", "211331", |
| | | "231131", "213113", "213311", "213131", "311123", "311321", "331121", "312113", "312311", "332111", |
| | | "314111", "221411", "431111", "111224", "111422", "121124", "121421", "141122", "141221", "112214", |
| | | "112412", "122114", "122411", "142112", "142211", "241211", "221114", "413111", "241112", "134111", |
| | | "111242", "121142", "121241", "114212", "124112", "124211", "411212", "421112", "421211", "212141", |
| | | "214121", "412121", "111143", "111341", "131141", "114113", "114311", "411113", "411311", "113141", |
| | | "114131", "311141", "411131", "211412", "211214", "211232", "2331112" |
| | | ]; |
| | | }, |
| | | escapeXml(text) { |
| | | return String(text) |
| | | .replace(/&/g, "&") |
| | | .replace(/</g, "<") |
| | | .replace(/>/g, ">") |
| | | .replace(/"/g, """) |
| | | .replace(/'/g, "'"); |
| | | }, |
| | | getDevpStateInfo() { |
| | | if (this.readOnly) { |
| | | // Frontend filtering for readOnly mode |
| | |
| | | }, |
| | | }); |
| | | }, |
| | | resetCommand() { |
| | | let that = this; |
| | | //下发命令 |
| | | $.ajax({ |
| | | url: baseUrl + "/station/command/reset", |
| | | headers: { |
| | | token: localStorage.getItem("token"), |
| | | }, |
| | | contentType: "application/json", |
| | | method: "post", |
| | | data: JSON.stringify(that.controlParam), |
| | | success: (res) => { |
| | | if (res.code == 200) { |
| | | that.$message({ |
| | | message: res.msg, |
| | | type: "success", |
| | | }); |
| | | } else { |
| | | that.$message({ |
| | | message: res.msg, |
| | | type: "warning", |
| | | }); |
| | | } |
| | | }, |
| | | }); |
| | | }, |
| | | }, |
| | | }); |