diff --git a/sf_manufacturing/__manifest__.py b/sf_manufacturing/__manifest__.py index 35501367..71f4027a 100644 --- a/sf_manufacturing/__manifest__.py +++ b/sf_manufacturing/__manifest__.py @@ -45,6 +45,8 @@ 'sf_manufacturing/static/src/scss/kanban_change.scss', 'sf_manufacturing/static/src/xml/button_show_on_tree.xml', 'sf_manufacturing/static/src/js/workpiece_delivery_wizard_confirm.js', + 'sf_manufacturing/static/src/js/qr.js', + 'sf_manufacturing/static/src/xml/qr.xml', ] }, diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index 23129578..01977926 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -1105,9 +1105,11 @@ class ResMrpWorkOrder(models.Model): if self.routing_type == '装夹预调': # 判断是否有坯料的序列号信息 boolean = False - if self.production_id.move_raw_ids[0].move_line_ids: - if self.production_id.move_raw_ids[0].move_line_ids[0].lot_id.name: - boolean = True + if self.production_id.move_raw_ids: + if self.production_id.move_raw_ids[0].move_line_ids: + if self.production_id.move_raw_ids[0].move_line_ids: + if self.production_id.move_raw_ids[0].move_line_ids[0].lot_id.name: + boolean = True if not boolean: raise UserError('制造订单【%s】缺少组件的序列号信息!' % self.production_id.name) self.pro_code = self.production_id.move_raw_ids[0].move_line_ids[0].lot_id.name diff --git a/sf_manufacturing/static/src/js/qr.js b/sf_manufacturing/static/src/js/qr.js new file mode 100644 index 00000000..fd501f27 --- /dev/null +++ b/sf_manufacturing/static/src/js/qr.js @@ -0,0 +1,115 @@ +/** @odoo-module **/ +import { registry } from '@web/core/registry'; +import { Component } from '@odoo/owl'; + +class QRCodeWidget extends Component { + // 初始化组件 + setup() { + console.log('QRCodeWidget setup'); + this.qrCodeValue = ''; // 初始化为空字符串,用于存储条码 + this.inputBuffer = ''; // 存储临时输入的字符 + this.inputTimer = null; // 定时器 + + // 显式绑定上下文 + this.onGlobalKeyDown = this.onGlobalKeyDown.bind(this); + window.addEventListener('keydown', this.onGlobalKeyDown); + } + + // 清理事件监听器,防止内存泄漏 + willUnmount() { + window.removeEventListener('keydown', this.onGlobalKeyDown); + if (this.inputTimer) { + clearTimeout(this.inputTimer); + } + } + + // 全局键盘事件监听器 + onGlobalKeyDown(event) { + + // 如果是Tab键,表示扫码输入结束 + if (event.key === 'Tab' || event.key === 'Enter') { + this.qrCodeValue = this.inputBuffer; // 完整条码赋值 + console.log('完整条码:', this.qrCodeValue); + this.onQRCodeChange(this.qrCodeValue); // 调用父组件的 onQRCodeChange 方法 + this.inputBuffer = ''; // 清空临时缓冲区 + event.preventDefault(); // 阻止Tab键的默认行为 + return; + } + + // 只处理可打印字符 + if (event.key.length === 1) { + this.inputBuffer += event.key; // 添加到缓冲区 + // console.log('当前缓冲区:', this.inputBuffer); + + // 清除之前的定时器,重新开始计时 + if (this.inputTimer) { + clearTimeout(this.inputTimer); + } + + // 启动一个定时器,如果500ms内没有新的输入,则认为条码输入完成 + this.inputTimer = setTimeout(() => { + this.qrCodeValue = this.inputBuffer; + // console.log('定时器触发,完整条码:', this.qrCodeValue); + this.inputBuffer = ''; // 清空缓冲区 + }, 500); // 可以根据需要调整时间 + } + + } + + // 处理二维码输入变更 + async onQRCodeChange(qrCodeValue) { + console.log('onQRCodeChange二维码输入变更', qrCodeValue); // 检查二维码的输入是否被捕获 + + if (qrCodeValue) { + // console.log('二维码输入变更'); + try { + // 发起 RPC 请求 + const result = await this.env.services.rpc('/web/dataset/call_kw', { + model: 'mrp.workorder', + method: 'search_read', + args: [ + [['rfid_code', '=', qrCodeValue]], // 查询条件 + ['id'] // 返回的字段 + ], + kwargs: {} + }); + + if (result.length > 0) { + console.log('该二维码对应的工单存在!'); + } else { + console.log('未找到对应的工单。'); + + const routingTypeField = document.querySelector('[name="routing_type"]'); + if (routingTypeField) { + let fieldValue = routingTypeField.querySelector('span').getAttribute('raw-value'); + console.log('Routing Type Value:', fieldValue); + // 清理多余的引号 + fieldValue = fieldValue ? fieldValue.replace(/["]+/g, '') : null; + console.log(fieldValue); + + if (fieldValue && fieldValue === '装夹预调') { + // console.log('routing_type 为装夹预调'); + + // 检查 RFID 值 + if (!qrCodeValue || qrCodeValue.length <= 3) return; + + // 查找 name="button_start" 按钮并触发点击事件 + const startButton = document.querySelector('[name="button_start"]'); + if (startButton) { + startButton.click(); + } + } + } + } + } catch (error) { + console.error('查询工单时出错:', error); + } + } + } + + // 返回模板名称 + static template = 'sf_manufacturing.QRCodeWidgetTemplate'; +} + +// 将自定义字段注册到字段注册表 +registry.category('fields').add('qrcode_widget', QRCodeWidget); diff --git a/sf_manufacturing/static/src/xml/qr.xml b/sf_manufacturing/static/src/xml/qr.xml new file mode 100644 index 00000000..415c0cd8 --- /dev/null +++ b/sf_manufacturing/static/src/xml/qr.xml @@ -0,0 +1,12 @@ + + + + + + +
+ +
+
+
+ diff --git a/sf_manufacturing/views/mrp_workorder_view.xml b/sf_manufacturing/views/mrp_workorder_view.xml index f3aa70cc..708a9779 100644 --- a/sf_manufacturing/views/mrp_workorder_view.xml +++ b/sf_manufacturing/views/mrp_workorder_view.xml @@ -125,9 +125,9 @@ mrp.workorder - -