溯源系统需全程可追溯,核心是统一trace id贯穿请求入口到数据库写入各环节,并在operation_log表中记录关键操作快照,通过traceablelogbehavior行为解耦日志与业务,前后端对齐trace_id实现高效问题定位。

Yii开发溯源系统时,后端数据链路记录不能只靠日志打点或手动埋点,得从请求入口到数据库写入全程可追溯、可关联、可回查。核心是让每一条溯源数据(如批次录入、扫码验真、上链操作)都携带唯一上下文标识,并在各关键节点自动透传和落库。
统一请求追踪ID(Trace ID)贯穿全链路
每次外部请求(如扫码接口、生产信息提交)进入系统时,由入口中间件生成全局唯一的 trace_id(建议用 Yii2 的 yii\log\Logger::getLoggerId() 或自定义 UUIDv4),并注入到当前请求生命周期的 Yii::$app->params 或 Yii::$app->session(仅限调试)中。该 ID 需随以下环节自动携带:
- 控制器接收参数后,立即存入当前 ActiveRecord 模型的临时属性(如
$model->trace_id = Yii::$app->params['trace_id']) - 调用服务层方法时,显式作为参数传递(避免依赖全局状态)
- 写入数据库前,确保 trace_id 字段已写入对应表(如
product_batch、verify_log、blockchain_tx) - 若涉及异步任务(如 RabbitMQ 发送上链指令),需将 trace_id 序列化进消息体,消费者侧还原使用
关键业务节点自动记录操作快照
不是所有操作都要记全量数据,但核心溯源动作必须留痕。推荐在 ActiveRecord 的 beforeSave 或行为(Behavior)中统一拦截:
- 生产批次创建:记录产品 ID、原料批次、操作人、设备编号、时间戳、trace_id
- 防伪码生成:记录码值(哈希脱敏)、绑定批次号、生成时间、生成 IP、trace_id
- 消费者扫码验真:记录扫码时间、设备指纹(UA+IP)、地理位置(可选)、是否首次验证、trace_id
- 上链操作触发:记录交易哈希(待返回)、上链时间、调用方服务名、trace_id
这些字段建议统一归入一张 operation_log 表,结构精简(id, action, target_type, target_id, data_summary, trace_id, created_at),避免冗余大字段。
数据库变更与事件解耦记录
Yii2 原生支持 afterInsert/afterUpdate 等事件,但直接在模型里写日志易耦合。更稳妥的做法是:
- 定义一个
TraceableLogBehavior行为,挂载到所有需溯源的模型上 - 行为内监听
EVENT_AFTER_INSERT等事件,提取主键、变更字段(用$model->getDirtyAttributes())、当前 trace_id - 通过独立日志服务(如自建
LogService::record())异步写入,不阻塞主流程 - 对敏感字段(如防伪码明文)做脱敏处理(如仅存 SHA256 后 8 位)再入库
与前端/扫码端保持 trace_id 对齐
消费者扫码后,前端应将二维码中携带的业务 ID(如 batch_no 或 code_hash)连同设备信息一起发起验真请求,并在请求头中带上 X-Trace-ID(由前端生成或由扫码 SDK 注入)。后端收到后优先校验该 header 是否存在,不存在则自动生成并返回给前端用于后续调试定位。这样当用户反馈“扫码没反应”时,客服只需拿到 trace_id 就能快速串联起:扫码时间 → 请求到达 → 验真逻辑 → 数据库查询 → 缓存命中与否 → 上游服务响应。











