feat: MOM 扫码入库对接 Track 产品身份证自动填充

- 半成品/成品入库弹窗顶部新增'扫码入库'按钮,打开扫码面板(扫码枪/摄像头)
- 扫码 Track 身份证后自动填充物料信息与序列号,不再二次搜索
- 后端新增 track_query_service(httpx 调 Track lookup)、track-lookup 接口
- 入库成功后 notify_track 通知 Track 闭环
This commit is contained in:
yueli
2026-09-01 13:52:56 +08:00
parent 9bc3c94dd1
commit bee037f925
13 changed files with 576 additions and 2 deletions

View File

@ -2,6 +2,8 @@
from flask import Blueprint, request, jsonify
from app.services.inbound.product_service import ProductInboundService
from app.utils.decorators import permission_required, audit_log
from app.models.base import MaterialBase
from app.services.track_query_service import lookup_product
import traceback
# === 这一行非常关键,绝对不能丢!===
@ -136,6 +138,57 @@ def submit():
traceback.print_exc()
return jsonify({"code": 500, "msg": str(e)}), 500
@inbound_product_bp.route('/track-lookup', methods=['GET'])
@permission_required('inbound_product')
def track_lookup():
"""扫码入库:根据 Track 身份证查询产品信息,并匹配 MOM 物料库"""
try:
code = (request.args.get('code') or '').strip()
if not code:
return jsonify({"code": 400, "msg": "code 参数不能为空"}), 400
track_info = lookup_product(code)
if not track_info:
return jsonify({"code": 404, "msg": "未在 Track 系统中找到该身份证对应的产品"}), 404
material_id = track_info.get('material_id')
material = None
if material_id:
try:
material_id = int(material_id)
except (TypeError, ValueError):
material_id = None
if material_id:
material = MaterialBase.query.filter(
MaterialBase.id == material_id,
MaterialBase.is_enabled == True
).first()
if material is None:
return jsonify({
"code": 404,
"msg": "扫码产品的物料在 MOM 物料库中不存在,请先在【基础信息】中完善该物料后再入库"
}), 404
return jsonify({
"code": 200,
"msg": "success",
"data": {
"track": track_info,
"material": {
"id": material.id,
"company_name": material.company_name,
"name": material.name,
"spec": material.spec_model,
"category": material.category,
"unit": material.unit,
"type": material.material_type,
}
}
})
except Exception as e:
traceback.print_exc()
return jsonify({"code": 500, "msg": str(e)}), 500
@inbound_product_bp.route('/<int:id>', methods=['PUT'])
@permission_required('inbound_product:operation')
@audit_log(

View File

@ -2,6 +2,8 @@
from flask import Blueprint, request, jsonify
from app.services.inbound.semi_service import SemiInboundService
from app.utils.decorators import permission_required, audit_log
from app.models.base import MaterialBase
from app.services.track_query_service import lookup_product
import traceback
# === 这一行非常关键,绝对不能丢!===
@ -130,6 +132,57 @@ def submit():
traceback.print_exc()
return jsonify({"code": 500, "msg": str(e)}), 500
@inbound_semi_bp.route('/track-lookup', methods=['GET'])
@permission_required('inbound_semi')
def track_lookup():
"""扫码入库:根据 Track 身份证查询产品信息,并匹配 MOM 物料库"""
try:
code = (request.args.get('code') or '').strip()
if not code:
return jsonify({"code": 400, "msg": "code 参数不能为空"}), 400
track_info = lookup_product(code)
if not track_info:
return jsonify({"code": 404, "msg": "未在 Track 系统中找到该身份证对应的产品"}), 404
material_id = track_info.get('material_id')
material = None
if material_id:
try:
material_id = int(material_id)
except (TypeError, ValueError):
material_id = None
if material_id:
material = MaterialBase.query.filter(
MaterialBase.id == material_id,
MaterialBase.is_enabled == True
).first()
if material is None:
return jsonify({
"code": 404,
"msg": "扫码产品的物料在 MOM 物料库中不存在,请先在【基础信息】中完善该物料后再入库"
}), 404
return jsonify({
"code": 200,
"msg": "success",
"data": {
"track": track_info,
"material": {
"id": material.id,
"company_name": material.company_name,
"name": material.name,
"spec": material.spec_model,
"category": material.category,
"unit": material.unit,
"type": material.material_type,
}
}
})
except Exception as e:
traceback.print_exc()
return jsonify({"code": 500, "msg": str(e)}), 500
@inbound_semi_bp.route('/<int:id>', methods=['PUT'])
@permission_required('inbound_semi:operation')
@audit_log(