Files
KCGL/inventory-backend/app/services/track_query_service.py
yueli 0f929468a8 fix(track): track-lookup 按公司路由,修复 LICA 扫码误报"物料不存在"
lookup_product() 此前写死读全局 TRACK_API_URL(指向 IRIS)。LICA 员工在
LICA 业务里扫码 → 请求打到 IRIS 库 → 查不到 → MOM 报"物料不存在"。

改用 get_current_company_filter() + resolve_track_route(…, 'api') 选实例,
复用既有工具而非另写一套。无请求/JWT 上下文时(脚本、后台任务)包一层
异常保护回落默认实例,不阻断查询。

实测(身份证 0000000000000001 只存在于 LICA 库):
  LICA 员工 → company_filter='LICA' → 命中 sn='0000000000000001'
  IRIS 员工 → company_filter='IRIS' → 未命中
改造前两者都会打到 IRIS,LICA 员工必然查不到。
2026-09-22 13:13:53 +08:00

77 lines
3.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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:
api_key = (current_app.config.get('TRACK_WEBHOOK_KEY') or '').strip()
if not api_key:
logger.info("[TrackQuery] 未配置 TRACK_WEBHOOK_KEY,跳过查询")
return None
# ★ 按当前用户所属公司路由到对应的 Track 实例(IRIS / LICA)。
# 复用 get_current_company_filter():超管/跨域用户返回 None → 回落默认实例。
# 改造前这里写死读 TRACK_API_URL,LICA 员工在 LICA 业务里扫码会打到 IRIS 库,
# 查不到 → MOM 误报"物料不存在"。
from app.services.track_webhook_service import resolve_track_route
from app.utils.decorators import get_current_company_filter
try:
company = get_current_company_filter()
except Exception:
# 无请求/JWT 上下文(脚本、后台任务)时回落默认实例,不阻断查询
company = None
base_url = resolve_track_route(company, 'api')
if not base_url:
logger.info("[TrackQuery] 未解析到 Track API 地址,跳过查询")
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