2026-06-09|供应风险预警推送逻辑完善方案设计
一、今日主要工作
- 围绕供应风险预警推送逻辑完善需求,完成现有推送链路的代码阅读、历史变更追溯和问题定位。
- 梳理当前”按订单号精准推送”的局限,明确其在无订单号场景下会出现无法推送销售的回归问题。
- 从产品型号、报价单、订单、销售和用户主数据之间的关系出发,探索并确认新的供应风险预警推送查询链路。
- 设计三类预警类型对应的数据查询逻辑:供应风险、产品退市、已下单风险分别走不同的数据匹配路径。
- 梳理
fcst_price_check_order、oms_order_data、sys_user等关键表结构、字段含义、关联关系和数据限制。 - 设计 seller 字段解析方案,将”姓名 + 工号”格式的销售字段解析为系统用户 ID,用于门户通知精准推送。
- 制定《供应风险预警推送完善 — 详细开发计划》,明确后续需要新增的 Mapper、SQL、Service 方法、测试用例和风险点。
- 沉淀《供应风险预警推送完善 — 需求梳理与方案探索全过程》。
二、核心完成内容
1. 现有推送逻辑阅读与问题定位
今天首先恢复了项目上下文,重新梳理供应风险预警模块的现有实现逻辑。在 PortalSupplyRiskService.createAndPublish() 中,现有逻辑大致为:
创建预警 → 保存 portal_supply_risk_alert → resolveOrderSalesUserIds(orderId) → 按订单号查询 Oracle processor → 匹配 SCM 用户 → 过滤 sales 角色 → 写入 portal_supply_risk_notification通过阅读当前代码和追溯历史提交,发现之前为了避免”全量推送给所有销售”的噪声问题,将推送逻辑改造成了按 orderId 精准匹配销售。但该改造也引入了新的问题:如果预警没有明确订单号,resolveOrderSalesUserIds(orderId) 会返回空列表,导致预警创建成功但没有任何销售收到通知。
2. 需求链路重新梳理
今天对供应风险预警推送需求进行了重新拆解。新的核心目标是:
从 productModels / product_name 出发 → 匹配报价单或订单 → 提取 seller → 解析为 sys_user_id → 写入门户通知表关键变化包括:入口从 orderId 改为 productModels、推送目标改为报价单 seller、不同 warningType 走不同链路、不再过滤 sales 角色、推送渠道仍走门户内通知表。
3. 三类预警类型查询链路设计
SUPPLY_RISK / EOL(产品维度预警):
productModels 关键词 → fcst_price_check_order.product_name LIKE 匹配 → 筛选审批完成 / 预审完成报价单 → 限制近 3 个月数据 → 排除已经转订单的报价单(NOT EXISTS oms_order_data.costApprovalNo) → 提取 seller → 解析为 sys_user_id → 写入 portal_supply_risk_notificationORDERED_RISK(已下单风险):
productModels 关键词 → fcst_price_check_order.product_name LIKE 匹配 → JOIN oms_order_data (costApprovalNo = price_approval_order_number) → orderState != 30 → 提取 seller → 解析为 sys_user_id → 写入通知表4. 数据表与字段关系梳理
fcst_price_check_order(SCM 数据源):产品名称、报价单号、seller 字段、审批状态、申请时间oms_order_data(SCM 数据源):costApprovalNo关联报价单号、orderState判断订单完成状态sys_user:通过code匹配 seller 尾部工号,得到user_id
5. seller 字段解析方案
seller 格式为”中文姓名 + 工号”(如”刘敏79574”),解析逻辑为:提取尾部连续数字 → 优先精确匹配 sys_user.code → 失败时 LIKE 后缀匹配 → 返回 user_id。无法匹配的 seller 跳过并记录日志。
6. Mapper 与 Service 改造计划
计划新增 SupplyRiskQueryMapper(标注 @ScmMapper),包含:
selectUnorderedQuotesByProductName:SUPPLY_RISK / EOL 查询selectUnshippedOrdersByProductName:ORDERED_RISK 查询
PortalSupplyRiskService.createAndPublish() 调整为按 warningType 路由,新增 splitProductKeywords、extractTrailingDigits、resolveSellerToSysUserId 等方法,删除旧 resolveOrderSalesUserIds,orderId 字段标记 @Deprecated。
三、今日工作产出
- 完成供应风险预警现有推送链路梳理,明确
orderId依赖的局限 - 定位”全量 sales 推送”改为”按订单号精准推送”后引入的回归问题
- 设计从产品型号到销售人员的完整查询链路
- 梳理三类预警类型数据查询路径和筛选条件
- 确认三张核心表及其关联关系
- 设计 seller 字段解析算法
- 制定 Service 改造计划和 Mapper 新增方案
- 形成 14 条测试用例,覆盖正常、边界和回归场景
- 沉淀两份技术文档
四、遇到的问题与解决情况
1. 原逻辑依赖 orderId,无法覆盖多数预警场景
- 问题:
orderId为空时没有销售收到通知 - 处理:将推送入口从订单号调整为产品型号
- 结果:形成了
productModels → product_name → seller → sys_user的新方案
2. 报价单与订单的关联关系需要验证
- 问题:需要确认
costApprovalNo是否可视为报价单号 - 处理:通过字段注释、代码注释和 CPQ 接口调用逻辑交叉验证
- 结果:确认语义一致,可作为关联字段
3. 报价单主表不在 Oracle 中
- 问题:按惯性在 Oracle EBS 中查找报价单表未找到
- 处理:扩大搜索到 SCM MySQL,定位到
fcst_price_check_order - 结果:确认该表为核心数据源
4. 未下单判断方式需要明确
- 问题:LEFT JOIN 语义不清晰,脏数据场景易误判
- 处理:改用
NOT EXISTS子查询 - 结果:逻辑更清晰,便于后续维护
5. seller 字段需要转换为系统用户 ID
- 问题:seller 是”姓名+工号”字符串,不能直接写入通知表
- 处理:设计尾部连续数字提取 +
sys_user.code匹配方案 - 结果:形成 seller 到
sys_user.user_id的解析方案
6. dev 数据过期影响测试
- 问题:dev 快照
approval_start_time最新为 2023 年,3 个月条件查不到数据 - 处理:标注测试限制,建议本地放宽时间条件,生产再端到端验证
- 结果:提前明确风险,避免误判代码错误
五、明日计划
- 优先新增
SupplyRiskQueryMapper和对应 XML SQL - 确认 Mapper 数据源方案,采用
@ScmMapper放入 SCM Mapper 包 - 修改
PortalSupplyRiskService.createAndPublish(),替换为按 warningType 路由 - 实现
splitProductKeywords、extractTrailingDigits、resolveSellerToSysUserId等基础方法 - 本地编译验证多数据源 Mapper 注册
- 使用放宽时间条件验证 SQL 查询链路
- 补充必要日志,便于观察 seller 匹配和推送情况
六、总结
今日主要围绕供应风险预警推送完善需求展开,重点完成了现有逻辑阅读、历史变更追溯、数据关系探索、查询链路设计和详细开发计划制定。通过分析发现,当前按订单号精准推送虽然避免了全量推送噪声,但无法覆盖无订单号的供应风险和产品退市场景。今天确认了以产品型号为入口,通过 fcst_price_check_order 匹配报价单、通过 oms_order_data 区分未下单和已下单未发货、再通过 seller 解析销售用户的整体方案。