diff --git a/src/api/qualityManagement/gp12/qcGp12Service.js b/src/api/qualityManagement/gp12/qcGp12Service.js index 6916485..ecca728 100644 --- a/src/api/qualityManagement/gp12/qcGp12Service.js +++ b/src/api/qualityManagement/gp12/qcGp12Service.js @@ -45,3 +45,75 @@ export function AnalyzeLabel(query) { params: query, }) } + +/** + * GP12质量开始工单 + * @param {查询条件} data + */ +export function StartGP12WorkOrder(query) { + return request({ + url: '/mes/qc/gp12/QcGp12Controller/StartGP12WorkOrder', + method: 'post', + data: query, + }) +} + +/** + * GP12质量缺陷项修改 + * @param {查询条件} data + */ +export function ChangeWorkOrderDefect(query) { + return request({ + url: '/mes/qc/gp12/QcGp12Controller/ChangeWorkOrderDefect', + method: 'post', + data: query, + }) +} + +/** + * GP12工单的质量缺陷项信息获取 + * @param {查询条件} data + */ +export function GetWorkOrderDefectList(query) { + return request({ + url: '/mes/qc/gp12/QcGp12Controller/GetWorkOrderDefectList', + method: 'get', + params: query, + }) +} + +/** + * 标签工单内扫描 + * @param {查询条件} data + */ +export function ScanInnerLabel(query) { + return request({ + url: '/mes/qc/gp12/QcGp12Controller/ScanInnerLabel', + method: 'post', + data: query, + }) +} + +/** + * 结束工单,并生成质量报表 + * @param {查询条件} data + */ +export function EndGP12WorkOrderAndCreateStatistics(query) { + return request({ + url: '/mes/qc/gp12/QcGp12Controller/EndGP12WorkOrderAndCreateStatistics', + method: 'get', + params: query, + }) +} + +/** + * 更新工单数据 + * @param {查询条件} data + */ +export function UpdateWorkOrderDetail(query) { + return request({ + url: '/mes/qc/gp12/QcGp12Controller/UpdateWorkOrderDetail', + method: 'get', + params: query, + }) +} diff --git a/src/views/qualityManagement/gp12/touchScreen/main/components/header.vue b/src/views/qualityManagement/gp12/touchScreen/main/components/header.vue index 6daeb94..7178475 100644 --- a/src/views/qualityManagement/gp12/touchScreen/main/components/header.vue +++ b/src/views/qualityManagement/gp12/touchScreen/main/components/header.vue @@ -58,7 +58,7 @@ export default { /* 明亮的蓝色 */ color: #ecf0f1; /* 浅灰色文字颜色 */ - padding: 20px 20px; + padding: 5px; /* 增加标题高度 */ } @@ -76,7 +76,7 @@ export default { .menu { display: flex; align-items: center; - margin-right: 15px; + margin-right: 20px; /* 图标按钮靠近时间左边 */ } diff --git a/src/views/qualityManagement/gp12/touchScreen/main/index.vue b/src/views/qualityManagement/gp12/touchScreen/main/index.vue index a0e1f4e..010afac 100644 --- a/src/views/qualityManagement/gp12/touchScreen/main/index.vue +++ b/src/views/qualityManagement/gp12/touchScreen/main/index.vue @@ -8,14 +8,17 @@
-
+ + + +
@@ -34,13 +37,16 @@ \ No newline at end of file diff --git a/src/views/qualityManagement/gp12/touchScreen/workorder/index.vue b/src/views/qualityManagement/gp12/touchScreen/workorder/index.vue index 88db6b2..8c0497c 100644 --- a/src/views/qualityManagement/gp12/touchScreen/workorder/index.vue +++ b/src/views/qualityManagement/gp12/touchScreen/workorder/index.vue @@ -1,5 +1,5 @@ @@ -134,6 +287,7 @@ export default { components: { scanInput }, data() { return { + sessionKey: '_touchScreenA01', groups: [ { groupName: '油漆', children: [] }, { groupName: '设备', children: [] }, @@ -157,18 +311,20 @@ export default { ], teamOptions: [], siteOptions: [], + // 站点工单执行状态 1-初始状态(扫外箱标签) 2-工单执行中(扫内标签) + formStatus: 1, + team: '', + site: '', formData: { - // W20250102001 - workOrder: 'W20250102001', - team: '', - site: '', + workOrder: '', + partnumber: '', specification: '', color: '', description: '', - isOnetime: false, - isBack: false, - isPolish: false, - isOut: false, + isOnetime: 0, + isBack: 0, + isPolish: 0, + isOut: 0, }, messageClass: 'text-green', message: '正常', @@ -178,43 +334,168 @@ export default { updateDialogShow: false, updateName: '', updateCode: '', - updateNum: 0 + updateNum: 0, + // 开始工单弹框 + startWorkOrderDialog: { + show: false, + loading: false, + title: '开始工单', + partnumber: '', + specification: '', + color: '', + description: '', + number: '', + labelCode: '', + siteNo: '', + comNo: '', + isOnetime: 0, + isBack: 0, + isPolish: 0, + isOut: 0, + }, + // 结束工单弹框 + endWorkOrderDialog: { + show: false, + loading: false, + title: '结束工单', + partnumber: '', + specification: '', + color: '', + description: '', + number: '', + labelCode: '', + siteNo: '', + comNo: '', + isOnetime: 0, + isBack: 0, + isPolish: 0, + isOut: 0, + } }; }, computed: { // 20250103 TODO 投入数,合格数,合格率,抛光数,打磨数,报废数 计算 + qualifiedRate() { + try { + if (this.formData.requireNumber * 1 > 0) { + return Math.floor(this.formData.qualifiedNumber * 1 / this.formData.requireNumber * 1) * 100 + '%'; + } else { + return "0%"; + } + } catch (error) { + return "0%"; + } + } }, created() { this.init(); }, + mounted() { + this.doMounted(); + }, + beforeDestroy() { + this.dobeforeDestroy(); + }, methods: { async init() { - // 初始化方法 - let team = await QcGp12Api.GetGroupOptions() - let site = await QcGp12Api.GetStieOptions() + // 初始化数据 + let teams = await QcGp12Api.GetGroupOptions() + let sites = await QcGp12Api.GetStieOptions() let groups = await QcGp12Api.GetDefectInitOptions() - this.teamOptions = team.data - this.siteOptions = site.data + this.teamOptions = teams.data + this.siteOptions = sites.data this.groups = groups.data + // 缓存数据读取 + this.getLocalStorage() }, - doRefresh() { - this.init() + selectChange() { + this.setLocalStorage() + }, + setLocalStorage() { + const data = { + team: this.team, + site: this.site + } + localStorage.setItem(this.sessionKey, JSON.stringify(data)); + }, + getLocalStorage() { + const data = JSON.parse(localStorage.getItem(this.sessionKey)); + this.team = data.team + this.site = data.site + }, + doMounted() { + const options = { passive: true }; + this.$refs.container.addEventListener('touchmove', this.handleTouchMove, options); + }, + dobeforeDestroy() { + this.$refs.container.removeEventListener('touchmove', this.handleTouchMove); + this.closeWriter(); + this.closeReader(); + if (this.serialPort && this.serialPort.readable) { + this.serialPort.close(); + } + }, + handleTouchMove(event) { + // 处理 touchmove 事件(如果需要) + }, + async doRefresh() { + await this.init() + this.getDefectListByWorkOrder() + }, + clearFormData() { + this.formData = { + workOrder: '', + partnumber: '', + specification: '', + color: '', + description: '', + isOnetime: 0, + isBack: 0, + isPolish: 0, + isOut: 0, + } + }, + // 更新工单数据 + updateFormData() { + const params = { + workOrder: this.formData.workOrder + } + if (params.workOrder === '' || params.workOrder === null) { + return; + } + QcGp12Api.UpdateWorkOrderDetail(params).then(res => { + if (res.code === 200) { + this.formData = res.data + } + }) }, handlerScanInput(value) { this.handleAnalyzeLabel(value) }, - handleAnalyzeLabel(label = '') { + // 工单开始按钮 + doBtnStartWorkOrder() { + this.clearAddFormData() + this.startWorkOrderDialog.show = true + }, + // 扫外箱标签的情况 + handleScanBoxOutLabel(label = '') { const params = { label, + // type === 1 获取详细物料信息 2只判断零件号是否正确 type: 1 } QcGp12Api.AnalyzeLabel(params).then(res => { - console.log(res); if (res.code === 200 && res.data.isOk) { this.message = '正常'; this.messageClass = 'text-green'; + this.startWorkOrderDialog.partnumber = res.data.partnumber; + this.startWorkOrderDialog.specification = res.data.specification; + this.startWorkOrderDialog.color = res.data.color; + this.startWorkOrderDialog.number = res.data.number; + this.startWorkOrderDialog.description = res.data.description; + this.startWorkOrderDialog.labelCode = res.data.labelCode; } else { - this.$confirm('标签异常', '提示', { + this.$confirm('标签异常:' + res.data.msg, '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning', @@ -222,14 +503,145 @@ export default { }).then(() => { }).catch(() => { }); - this.message = '标签异常'; + this.message = '标签存在异常'; this.messageClass = 'text-red'; } }) }, - handleClick(item) { - console.log('Clicked on:', item); - // 在这里可以添加点击事件的具体逻辑 + // 确认开始工单 + startWorkOrder() { + const params = { + partNumber: this.startWorkOrderDialog.partnumber, + description: this.startWorkOrderDialog.description, + specification: this.startWorkOrderDialog.specification, + color: this.startWorkOrderDialog.color, + team: this.team, + siteNo: this.site, + comNo: "COM1", + isOnetime: this.startWorkOrderDialog.isPolish === 0 ? 1 : 0, + isBack: this.startWorkOrderDialog.isBack, + isPolish: this.startWorkOrderDialog.isPolish, + isOut: this.startWorkOrderDialog.isOut, + label: this.startWorkOrderDialog.labelCode, + } + if (params.partNumber === '' || params.label === '') { + this.$confirm('未扫描正确箱标签', '提示', { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning', + center: true + }).then(() => { + }).catch(() => { + }); + return; + } + this.startWorkOrderDialog.loading = true + // 开始工单 + QcGp12Api.StartGP12WorkOrder(params).then(res => { + if (res.code == 200) { + this.$message.success("开始工单成功!"); + this.formData = res.data + // 进入内标签扫码模式 + this.formStatus = 2 + this.getDefectListByWorkOrder() + this.closeStartWorkOrderDialog() + this.startWorkOrderDialog.loading = false + } else { + this.$message.error("开始工单异常!"); + this.closeStartWorkOrderDialog() + this.startWorkOrderDialog.loading = false + } + }); + }, + clearAddFormData() { + this.startWorkOrderDialog.loading = false; + this.startWorkOrderDialog.partnumber = ''; + this.startWorkOrderDialog.specification = ''; + this.startWorkOrderDialog.color = ''; + this.startWorkOrderDialog.number = ''; + this.startWorkOrderDialog.description = ''; + this.startWorkOrderDialog.labelCode = ''; + this.startWorkOrderDialog.isOnetime = 0; + this.startWorkOrderDialog.isPolish = 0; + this.startWorkOrderDialog.isBack = 0; + this.startWorkOrderDialog.isOut = 0; + }, + closeStartWorkOrderDialog() { + this.startWorkOrderDialog.show = false + this.clearAddFormData() + }, + closeEndWorkOrderDialog() { + this.endWorkOrderDialog.show = false + this.endWorkOrderDialog.loading = false; + }, + // 扫内标签的情况 + handleScanInnerLabel(label = '', comNo = "COM1") { + const params = { + workOrder: this.formData.workOrder, + partNumber: this.formData.partNumber, + team: this.team, + siteNo: this.site, + comNo: comNo, + labelType: 2, + label, + } + QcGp12Api.ScanInnerLabel(params).then(res => { + if (res.code === 200 && res.data === "ok") { + this.updateFormData() + } else { + this.$message.error("扫描内标签异常!" + res.data); + } + }); + }, + // 工单结束按钮 + doBtnEndWorkOrder() { + this.endWorkOrderDialog.show = true + // this.formStatus = 1 + }, + endWorkOrder() { + this.$confirm('是否确认完成工单并生成报表!', '提示', { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'info', + center: true + }).then(() => { + QcGp12Api.EndGP12WorkOrderAndCreateStatistics(this.formData).then(res => { + if (res.code === 200 && res.data === "ok") { + this.$message.success("结束工单并生成报表成功!"); + this.clearFormData(); + this.formStatus = 1 + this.endWorkOrderDialog.show = false + } else { + this.$message.error("结束工单异常!" + res.msg); + } + }); + }).catch(() => { + }); + }, + + handleAnalyzeLabel(label = '') { + const params = { + label, + // type === 1 获取详细物料信息 2只判断零件号是否正确 + type: 1 + } + QcGp12Api.AnalyzeLabel(params).then(res => { + if (res.code === 200 && res.data.isOk) { + this.message = '正常'; + this.messageClass = 'text-green'; + } else { + this.$confirm('标签异常:' + res.data.msg, '提示', { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning', + center: true + }).then(() => { + }).catch(() => { + }); + this.message = '标签存在异常'; + this.messageClass = 'text-red'; + } + }) }, handleStart(event, item) { // 如果是触摸事件,阻止其默认行为(如滚动) @@ -239,12 +651,13 @@ export default { // 设置新的定时器,用于判断长按 this.pressTimer = setTimeout(() => { this.isLongPress = true; - console.log('长按'); + //console.log('长按'); // 这里执行长按的逻辑 this.showUpdateDialog(item); }, 500); // 长按的阈值设为500毫秒 }, - handleEnd(item) { + handleEnd(event, item = null) { + if (!item) return; // 清除定时器 if (this.pressTimer) clearTimeout(this.pressTimer); // 这里执行短按或长按结束的逻辑 @@ -256,7 +669,7 @@ export default { if (this.isLongPress) { return; } - console.log('短按'); + //console.log('短按'); const workOrder = this.formData.workOrder; if (workOrder === null || workOrder === '') { this.$confirm('未生成有效工单,请扫描箱标签', '提示', { @@ -271,20 +684,24 @@ export default { this.messageClass = 'text-red'; return; } - const newNum = this.getClickItemNum(item) + 1; - // const params = { - // WorkOrder: this.formData.workOrder, - // DefectCode: item.code, - // num: item.num || 0, - // checkName: this.checkName - // }; - // FQCApi.AddDefectNum(params).then((res) => { - // if (res.code !== 200) { - // this.$message.error('添加缺陷项异常'); - // return; - // } - // }); - this.$set(item, 'num', newNum); + const params = { + workOrder: this.formData.workOrder, + defectCode: item.code, + defectNum: item.num || 0, + // 1-短按 2-长按 + type: "1", + }; + + QcGp12Api.ChangeWorkOrderDefect(params).then(res => { + if (res.code === 200) { + // const newNum = this.getClickItemNum(item) + 1; + //this.$set(item, 'num', newNum); + this.getDefectListByWorkOrder() + this.updateFormData() + } else { + this.$message.error('缺陷项点击异常'); + } + }) }, showUpdateDialog(item) { const workOrder = this.formData.workOrder; @@ -305,6 +722,7 @@ export default { this.updateCode = item.code; this.updateNum = this.getClickItemNum(item); this.updateDialogShow = true; + }, updateDefectNum() { const workOrder = this.formData.workOrder; @@ -322,37 +740,22 @@ export default { return; } const params = { - WorkOrder: this.formData.workOrder, - DefectCode: this.updateCode, - num: this.updateNum, - checkName: this.checkName + workOrder: this.formData.workOrder, + defectCode: this.updateCode, + defectNum: this.updateNum || 0, + // 1-短按 2-长按 + type: "2", }; - this.setDefectNum(params.DefectCode, params.num); - this.updateDialogShow = false; - // FQCApi.UpdateDefectNum(params).then((res) => { - // if (res.code === 200) { - // this.$confirm('修改成功', '提示', { - // type: 'success', - // center: true - // }).then(() => { - // }).catch(() => { - // }); - // this.message = '正常'; - // this.messageClass = 'text-green'; - // this.setDefectNum(params.DefectCode, params.num); - // this.updateDialogShow = false; - // } else { - // this.$confirm('修改失败', '提示', { - // type: 'error', - // center: true - // }).then(() => { - // }).catch(() => { - // }); - // this.message = '修改异常'; - // this.messageClass = 'text-red'; - // return; - // } - // }); + QcGp12Api.ChangeWorkOrderDefect(params).then(res => { + if (res.code === 200) { + this.getDefectListByWorkOrder() + this.updateFormData() + this.updateDialogShow = false; + this.isLongPress = false; + } else { + this.$message.error('缺陷项点击异常'); + } + }) }, getClickItemNum(item) { if (!item.num) { @@ -370,6 +773,93 @@ export default { } } } + }, + // 获取工单缺陷项(刷新) + getDefectListByWorkOrder() { + const params = { + workOrder: this.formData.workOrder, + }; + if (params.workOrder == null || params.workOrder == '') { + return; + } + QcGp12Api.GetWorkOrderDefectList(params).then(res => { + if (res.code === 200 && res.data.length > 0) { + let _list = res.data; + for (let item of _list) { + this.setDefectNum(item.defectCode, item.defectNum); + } + } + }) + }, + async connectSerialPort() { + try { + // 请求用户选择串口 + this.serialPort = await navigator.serial.requestPort(); + // 打开串口 + await this.serialPort.open({ baudRate: 9600 }); + // 创建读取器 + const decoder = new TextDecoderStream(); + this.reader = this.serialPort.readable.pipeThrough(decoder).getReader(); + // 读取数据 + while (true) { + const { value, done } = await this.reader.read(); + this.$message.success('数据:' + value) + if (done) { + break; + } + console.log("value", value); + this.handleScanInnerLabel(value) + } + } catch (error) { + this.$message.error('无法连接到串口:' + error) + console.error("无法连接到串口:", error); + } + }, + // 测试发数据 + async sendData() { + if (!this.serialPort || !this.serialPort.writable) { + this.$message.error('请先连接串口!'); + return; + } + if (!this.writer) { + try { + this.writer = this.serialPort.writable.getWriter(); + } catch (error) { + console.error('无法创建写入器:', error); + this.$message.error('无法创建写入器: ' + error.message); + return; + } + } + const message = '发送了串口数据!\n'; + const encoder = new TextEncoder(); + const data = encoder.encode(message); + try { + await this.writer.write(data); + console.log('消息发送:', message); + } catch (error) { + console.error('错误:', error); + this.$message.error('错误: ' + error.message); + } + }, + closeWriter() { + if (this.writer) { + try { + this.writer.releaseLock(); + this.writer = null; + } catch (error) { + console.error('Error releasing writer lock:', error); + } + } + }, + closeReader() { + if (this.reader) { + try { + this.reader.cancel(); + this.reader = null; + } catch (error) { + console.error('Error canceling reader:', error); + } + } } } }; @@ -436,20 +926,32 @@ export default { margin-bottom: 10px; } +.workorder-card-action-box { + width: 100%; + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 10px; + font-size: 20px; + font-weight: 600; +} + .defect-item-left { + height: 120px; font-size: 24px; font-weight: 600; display: flex; align-items: center; justify-content: center; + writing-mode: vertical-lr; } .defect-item-box { min-width: 100%; border-radius: 5%; - margin-top: 10px; - margin-bottom: 10px; + margin-top: 5px; + margin-bottom: 5px; background-color: #016129; display: flex; flex-direction: column; @@ -470,13 +972,15 @@ export default { .defect-item-name { width: 100%; - height: 80px; - font-size: 22px; + height: 100px; + font-size: 20px; font-weight: 600; text-align: center; display: flex; align-items: center; justify-content: center; + /* writing-mode: vertical-lr; */ + letter-spacing: 5px; } .defect-item-number {