文章目录

公司要实时关注广东气象局发布的灾害预警(台风、暴雨、高温……),第一时间推送到钉钉群。SmartOA 实现:定时任务扫描广东气象局预警数据 → 解析预警级别 → 钉钉互动卡片投递到群聊,卡片带详情链接和级别图标。这篇记录模块从联调到上线的完整过程,包括两个典型的「数据语义」坑。

一、整体链路

1
定时任务(SmartJob 调度):按扫描频率轮询广东气象局预警接口
cron
↓
2
解析预警数据:级别编码 → 颜色图标映射,按市级过滤本公司所在城市
parse
↓
3
钉钉互动卡片:群聊投递,标题 + 级别图标 + 详情链接
card
↓
4
预警解除:图标变蓝,提示「已解除」
resolve
气象灾害预警信息图
▲ 气象灾害预警效果图

二、数据源与接口切换

广东气象局的预警接口有两个版本,联调中发现老接口(ActiveYJ)数据不全,切换到新接口:

// 图标处理:media_id 需先上传素材换取
public String getLevelIcon(String levelCode) {
    if (mediaIdCache.containsKey(levelCode)) {
        return mediaIdCache.get(levelCode);       // 缓存,避免重复上传
    }
    String mediaId = dingTalkService.uploadMedia(iconFile(levelCode));
    mediaIdCache.put(levelCode, mediaId);
    return mediaId;
}

图标全量补全:4 色通用图标(蓝=预警、黄=较重、橙=严重、红=特别严重),titleimg 统一换通用图标。

三、坑 1:预警级别编码映射错误——橙色显示蓝色

上线后第一条台风预警,橙色预警却显示蓝色图标。排查:

🚨 坑:外部接口的枚举语义必须以官方文档/真实数据为准,不能凭直觉猜。正确做法:先拉一批真实数据,统计每个编码出现的级别文本,反推映射表。
// 修复:按真实数据反推的映射表
private static final Map<Integer, Level> LEVEL_MAP = Map.of(
    2, Level.BLUE,     // 实测 2 → 蓝色
    3, Level.YELLOW,   // 实测 3 → 黄色
    4, Level.ORANGE,   // 实测 4 → 橙色
    5, Level.RED       // 实测 5 → 红色
);

四、坑 2:市级过滤——子串匹配误伤

需求:只推送本公司所在城市(如惠州)的预警。初版用子串匹配:预警标题包含「惠州」就推送。结果:

修复:从子串匹配改为精确匹配市级行政区划代码/名称:

// ❌ 子串匹配:'惠州市大亚湾区'.contains('惠州') → 误推送
if (title.contains(cityName)) { push(); }

// ✅ 精确匹配:预警区域字段按行政区划解析,只认市级本身
if (region.equals(cityName) || region.startsWith(cityName + "市")) {
    if (isSubRegion(region)) return;   // 区/县级别不推
    push();
}
💡 教训:区域/名称类过滤永远用「结构化精确匹配」,不要用 contains 子串。数据里隐含层级关系时,先建模再过滤。

五、坑 3:预警解除要「降级」而不是「静默」

预警解除后,气象局会发一条解除记录(级别 0 或特殊编码)。初版逻辑是「无新预警就不推」,结果群里台风过境后没有任何「解除」通知,员工不知道警报已撤。修复:

六、定时任务配置:SmartJob 复用

定时任务复用项目现有的 SmartJob 调度体系(不单独开发),前端在 /#/job/list 管理:

配置项值说明
任务名气象灾害预警扫描SmartJob 注册
扫描频率每 30 分钟param 字段填充扫描频率描述
执行记录导出 Excel每次执行留痕可查

执行记录导出 Excel 功能一并补齐(定时任务执行记录增加导出),便于事后核对「为什么没推」。

七、踩坑清单(可直接复用)

  1. 枚举语义别猜:外部接口编码映射先拉真实数据反推,再写代码
  2. 区域过滤用精确匹配:contains 子串匹配会误伤子区域
  3. 解除也是事件:状态变化要推送「解除」,不能静默
  4. media_id 缓存:钉钉素材上传接口有频率限制,必须缓存
  5. 定时任务复用 SmartJob:别重复造调度轮子,执行记录可导出
✅ 最终成果:气象预警 30 分钟级自动扫描,级别图标准确、市级精确过滤、解除状态同步推送,群聊卡片带详情链接,全程零人工值守。

评 论