feat: MOM 扫码入库对接 Track 产品身份证自动填充
- 半成品/成品入库弹窗顶部新增'扫码入库'按钮,打开扫码面板(扫码枪/摄像头) - 扫码 Track 身份证后自动填充物料信息与序列号,不再二次搜索 - 后端新增 track_query_service(httpx 调 Track lookup)、track-lookup 接口 - 入库成功后 notify_track 通知 Track 闭环
This commit is contained in:
63
inventory-backend/app/services/track_query_service.py
Normal file
63
inventory-backend/app/services/track_query_service.py
Normal file
@ -0,0 +1,63 @@
|
||||
# app/services/track_query_service.py
|
||||
"""
|
||||
Track 系统产品查询服务(拉取侧)
|
||||
|
||||
扫码入库时,通过 httpx GET 调用 Track 的对外查询接口 /api/v1/external/products/lookup,
|
||||
根据身份证(serial_number)获取产品基础信息。
|
||||
|
||||
容错策略:
|
||||
- 未配置 TRACK_API_URL / TRACK_WEBHOOK_KEY 时返回 None。
|
||||
- 全包裹 try-except,任何异常(连接拒绝/超时/网络错误/4xx/5xx)仅记录日志,
|
||||
返回 None 交给上层决定如何提示,绝不抛出异常阻断业务。
|
||||
"""
|
||||
import logging
|
||||
|
||||
import httpx
|
||||
from flask import current_app
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# 请求超时(秒):查询属于同步交互,超时后由上层提示失败
|
||||
_QUERY_TIMEOUT = 5.0
|
||||
|
||||
|
||||
def lookup_product(code):
|
||||
"""
|
||||
根据身份证(16 位 serial_number)或业务序列号查询 Track 产品信息。
|
||||
|
||||
返回 Track 查询接口的 data 字典(含 serial_number/external_serial/material_id/
|
||||
sku/material_name/spec_model/material_type/order_no),未命中或异常返回 None。
|
||||
"""
|
||||
try:
|
||||
base_url = (current_app.config.get('TRACK_API_URL') or '').strip()
|
||||
api_key = (current_app.config.get('TRACK_WEBHOOK_KEY') or '').strip()
|
||||
if not base_url:
|
||||
logger.info("[TrackQuery] 未配置 TRACK_API_URL,跳过查询")
|
||||
return None
|
||||
if not api_key:
|
||||
logger.info("[TrackQuery] 未配置 TRACK_WEBHOOK_KEY,跳过查询")
|
||||
return None
|
||||
|
||||
url = f'{base_url}/api/v1/external/products/lookup'
|
||||
headers = {
|
||||
'Content-Type': 'application/json',
|
||||
# ★ 鉴权字段名必须为 X-API-Key,与 Track 接收端严格对齐
|
||||
'X-API-Key': api_key,
|
||||
}
|
||||
resp = httpx.get(url, params={'code': code}, headers=headers, timeout=_QUERY_TIMEOUT)
|
||||
if resp.status_code == 200:
|
||||
data = resp.json()
|
||||
track_info = (data or {}).get('data')
|
||||
if track_info:
|
||||
logger.info("[TrackQuery] 查询命中 code=%s", code)
|
||||
return track_info
|
||||
logger.info("[TrackQuery] 查询返回空数据 code=%s status=%s", code, resp.status_code)
|
||||
return None
|
||||
logger.info(
|
||||
"[TrackQuery] 查询未命中 code=%s status=%s body=%s",
|
||||
code, resp.status_code, resp.text[:200],
|
||||
)
|
||||
return None
|
||||
except Exception as e:
|
||||
logger.error("[TrackQuery] 查询失败 code=%s, err=%s", code, e)
|
||||
return None
|
||||
Reference in New Issue
Block a user