Blacklist:策略、范围与规则
黑名单策略、审批与生效版本
app_blacklisted 的一行表达一项应用处置策略:目标应用包名、操作类型、版本条件、启停状态及其审批过程。它不是被封禁设备清单,也不是每次设备执行日志。适用设备由规则或兼容范围决定,执行记录由反馈表保存。
例如修改已有配置的包名或处置方式时,业务需要让 旧配置继续工作,等待修改获批后再替换。因此表里既有正式字段,也有 draft、valid 和 bpm_status。这些字段共同描述“正在生效的版本”和“待审变更”,不能看到草稿就认为正式策略已经被替换。
如何读懂状态
| 字段 | 当前代码语义 | 使用时应区分 |
|---|---|---|
status | 1 启用,0 停用 | 决定配置是否可下发;不表示审批结果 |
type | 0 卸载,1 杀死进程/闪退 | 以 BlacklistedTypeEnum 为准;旧字段注释将两者写反 |
valid | 0 未生效;1 已生效;2 已生效待修改;3 已生效待移除 | 以 BpmBusinessValid 为准;旧 DO 与库注释将 2/3 写反 |
bpm_status | -1 未开始,1 审批中,2 通过,3 不通过,4 取消 | 审批生命周期,不替代启停和生效状态 |
deleted | BaseDO.@TableLogic 逻辑删除标志 | 与 type 的卸载动作完全不同 |
本文不依据注释差异调整数据库或重解释既有记录。当前代码使用枚举常量,存量历史数据是否都按同一语义写入,需另行结合历史版本和业务记录确认。
谁写入,什么时候生效
普通管理人员通过审批路径创建配置:先插入 valid=0,保存关联范围并设置待审状态。修改已生效配置时,BpmDraft 对 @IncludeInBpmDraft 字段建立变更,正式字段保留旧值,待审新值存入 JSON。当前主表参与该草稿机制的字段为 packageName/status/type/version;applicationName 的草稿注解已被注释,不能把全部字段都说成审批后才修改。
发起审批时,服务通过 system 字典取得流程定义,再通过 BPM API 创建流程:businessKey=app_blacklisted.id 的字符串形式,返回实例 ID 保存到 process_instance_id。流程变量可带 BLACK_LIST 的规则业务信息,让配置审批与规则变更共同参与流程。规则绑定本身由 rule 服务保存。
审批回调非通过时仅更新审批状态,不合并草稿。通过时按原 valid 合并待修改字段或删除配置,处理渠道/MAC/地区变更并刷新缓存。删除策略还会清理本库卸载反馈,但不会同步删除 TDengine 杀进程记录。主表是逻辑删除,未继承 BaseDO 的关联表按 Mapper 删除。
后台依据 PermissionUtils.hasSkipBpmRole 为免审批角色选择 AppBlacklistedNoBpmServiceImpl,创建和修改直接设为生效;删除复用通过态处理并解除规则绑定。因此不能单凭“无流程实例 ID”判断配置无效,也不能把所有配置修改都描述为必须走审批。
源码完整字段清单
源码的 13 个本体字段加 5 个 BaseDO 字段合计 18 个;均在实测主表中存在。物理类型和空值规则以实测字典为准。
| Java 字段 | 映射列 | Java 类型 | 业务用途 |
|---|---|---|---|
| id | id | Long | 策略 ID,规则绑定、回调和流程业务键的共同标识 |
| applicationName | application_name | String | 后台及设备返回的应用展示名 |
| packageName | package_name | String | 设备实际处置的应用包名 |
| status | status | Integer | 策略启停 |
| updateBy | update_by | String | 历史更新者字段,当前查询仍支持此条件 |
| createBy | create_by | String | 历史创建者字段,当前查询仍支持此条件 |
| remark | remark | String | 维护备注 |
| type | type | Integer | 卸载或终止进程 |
| version | version | String | 版本条件;后台校验后随策略返回设备 |
| draft | draft | BpmDraft<AppBlacklistedDO> | BpmDraftTypeHandler 保存的 JSON 待审变更 |
| bpmStatus | bpm_status | Integer | 流程状态 |
| processInstanceId | process_instance_id | String | BPM API 返回的实例 ID |
| valid | valid | Integer | 正式版本与待审变更关系 |
| createTime | create_time | LocalDateTime | BaseDO 创建填充 |
| updateTime | update_time | LocalDateTime | BaseDO 创建/更新填充 |
| creator | creator | String | BaseDO 当前审计创建者标识 |
| updater | updater | String | BaseDO 当前审计更新者标识 |
| deleted | deleted | Boolean | BaseDO 逻辑删除 |
实库另外存在 tenant_id、release_info、flow_status,分类见差异页。create_by/update_by 与 creator/updater 同时存在,不应按名字相近就合并。主表实测只有 PRIMARY(id),没有包名唯一约束;同包名能否出现多个配置不能靠数据库唯一键保障。
核验证据
以下前缀为 ik_project/yudao-cloud/yudao-module-blacklist/yudao-module-blacklist-biz/src/main/java/cn/iocoder/yudao/module/blacklist/。
dal/dataobject/blacklisted/AppBlacklistedDO.java:26:继承、草稿注解和类型处理。service/blacklisted/AppBlacklistedServiceImpl.java:123、:149、:186:创建、草稿修改、删除标记。service/blacklisted/AppBlackListedBpmServiceImpl.java:95、:422:发起审批与回调合并。service/blacklisted/AppBlacklistedNoBpmServiceImpl.java:77、:123、:138:免审批维护。controller/admin/blacklisted/AppBlacklistedController.java:537:按角色选择业务实现。- 枚举:
ik_project/yudao-cloud/yudao-module-blacklist/yudao-module-blacklist-api/src/main/java/cn/iocoder/yudao/module/blacklist/enums/BlacklistedTypeEnum.java:15;ik_project/yudao-cloud/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/business/BpmBusinessValid.java:18、enums/task/BpmProcessInstanceStatusEnum.java:19。 - 继承字段:
ik_project/yudao-cloud/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/dataobject/BaseDO.java:30。
核验日期:2026-09-18,源码静态检查与 MySQL 元数据对照;未执行审批或策略下发。
黑名单规则匹配与历史范围关系
黑名单从早期的“配置绑渠道/MAC/地区”逐步转为由 rule 统一表达设备范围。数据库保留早期关系并不说明新规则配置无效,也不意味着这些表可以删除:当前后台、审批处理和兼容入口仍有读写代码。设计说明必须同时保留当前规则方向与兼容行为。
当前规则链路
设备调用 /app/blacklisted,入口检查 blacklist.rule.enable。启用时走 V2:先从设备令牌或 device 缓存取得设备属性,再调用 RuleRunUtil.matchBusinessIds(BLACK_LIST, device),得到策略 ID 集合,读取策略缓存,过滤停用、无包名及保护包名,最后向设备返回策略 ID、应用名、包名、类型和版本条件。业务类型 BLACK_LIST 当前编码为 2。
配置字段决定“执行什么”,规则决定“谁执行”。规则的业务绑定以 businessType=2 + businessId=app_blacklisted.id 表达,规则表由 rule 服务管理;本库三张旧关系表不承担 V2 规则条件存储。查询 页面的设备覆盖数也由 RuleBusinessApi 返回,不能用渠道绑定数或 MAC 表行数替代。
开关先查询 infra 系统参数 blacklist.rule.enable,非空时优先采用;查询失败或为空再用配置注入值,代码默认 false。本次仅采集结构,没有读取参数业务记录,故没有证据断言当前测试进程一定采用哪个分支。
兼容关系如何工作
关闭规则开关时,旧链路从 MAC、渠道、地区缓存取候选策略 ID。若某策略设有地区限制,它必须同时命中地区,且渠道/MAC 至少命中一个;未设地区限制时由渠道或 MAC 命中。不是三项一律求交,也不是只命中地区就下发。
| 表 | 一行的含义 | 读写方与关系 |
|---|---|---|
| flow_blacklisted_channel | 一项策略绑定一个渠道 | 后台和审批服务写入,兼容匹配读取;channel_id 逻辑指向设备渠道体系 |
| flow_blacklisted_mac | 一项策略绑定一个 MAC | 后台导入、免审批和审批处理写入,兼容匹配读取;这里未存 CPU,粒度不同于设备反馈 |
| flow_blacklisted_region | 一项策略绑定一个国家/地区 ID | 后台和审批服务写入,兼容匹配读取;region_id 按设备侧返回的地区属性匹配 |
三表的 blacklisted_id 均逻辑关联 app_blacklisted.id,并无实测外键。draft/valid 用于范围变更审批:新增绑定未生效,删除已有绑定先标记,获批再合并/删除。兼容范围查询会保留已生效但待修改/移除的旧绑定,避免尚未获 批的动作立刻改变覆盖范围。
源码完整字段清单
三类 DO 均不继承 BaseDO,每表 5 个持久化字段,实库全部存在。
| 表 | Java 字段 → 列 | Java 类型 | 业务意义 |
|---|---|---|---|
| flow_blacklisted_channel | id → id | Long | 关系主键;实库为 int |
| flow_blacklisted_channel | blacklistedId → blacklisted_id | Long | 黑名单策略 ID |
| flow_blacklisted_channel | channelId → channel_id | Long | 渠道 ID |
| flow_blacklisted_channel | draft → draft | BpmDraft | 关系待审信息,JSON 类型处理 |
| flow_blacklisted_channel | valid → valid | Integer | 0 未生效、1 生效、2 待修改、3 待移除 |
| flow_blacklisted_mac | id → id | Long | 关系主键 |
| flow_blacklisted_mac | blacklistedId → blacklisted_id | Long | 黑名单策略 ID |
| flow_blacklisted_mac | mac → mac | String | 设备 MAC 范围项 |
| flow_blacklisted_mac | draft → draft | BpmDraft | 关系待审信息,JSON 类型处理 |
| flow_blacklisted_mac | valid → valid | Integer | 同上,按当前枚举解释 |
| flow_blacklisted_region | id → id | Long | 关系主键 |
| flow_blacklisted_region | blacklistedId → blacklisted_id | Long | 黑名单策略 ID |
| flow_blacklisted_region | regionId → region_id | Long | 国家/地区 ID |
| flow_blacklisted_region | draft → draft | BpmDraft | DO 声明 JSON 类型处理 |
| flow_blacklisted_region | valid → valid | Integer | 同上,按当前枚举解释 |
地区 DO 的 @TableName 没有像渠道/MAC DO 一样显式开启 autoResultMap。这属于源码映射差异,本文没有通过运行读取证明其反序列化行为;不把它当成缺失列或修库理由。
实测渠道、地区表只有主键;MAC 表另有唯一索引 blacklistId_mac(blacklisted_id, mac),普通索引 blacklistId_vaild(blacklisted_id, valid)、mac_vaild(mac, valid)。保留索引实际拼写 vaild,不擅自纠正。MAC 导入 Mapper 使用 ON DUPLICATE KEY UPDATE,与该组合唯一键共同支持重复导入已有绑定;审批与免审批路径对 valid 的更新规则不同。渠道、地区业务去重不能写成数据库组合唯一约束。
缓存属于派生数据
| 键模式 | 内容与用途 |
|---|---|
id:app:blacklisted:{id} | 策略缓存,包括 hasRegion、emptyId 等派生信息 |
blacklisted:mac:{mac} | MAC 对应策略 ID 集合 |
blacklisted:channel:{channelId} | 渠道对应策略 ID 集合 |
blacklisted:region:{regionId} | 地区对应策略 ID 集合 |
详情缓存未命中时回源 MySQL,使用空值标记和分布式锁处理穿透/并发;配置变更通过删除 Redis 及本地缓存触发重建,部分路径使用延迟双删。AppBlacklistedRedisDO.hasRegion/emptyId 是缓存字段,不是主表列;Redis 实际键、TTL 和当前一致性没有在本次元数据采集中核验。
核验证据
源码基准目录:ik_project/yudao-cloud/yudao-module-blacklist/yudao-module-blacklist-biz/src/main/java/cn/iocoder/yudao/module/blacklist/。
controller/app/blacklisted/ForeignBlacklistedController.java:61:入口分支与设备身份来源。framework/config/BlacklistConfig.java:25:infra 参数优先与配置回退。service/blacklisted/AppBlacklistedServiceImpl.java:1242、:1299、:1367、:1408、:1450:V2、兼容匹配与范围回源。dal/dataobject/blacklisted/FlowBlacklistedChannelDO.java:24、FlowBlacklistedMacDO.java:28、FlowBlacklistedRegionDO.java:21:全部字段。dal/redis/blacklisted/AppBlacklistedRedisDAO.java:48、:291;dal/redis/blacklisted/AppBlacklistedRedisDO.java:18:缓存维护与派生字段。ik_project/yudao-cloud/yudao-module-blacklist/yudao-module-blacklist-biz/src/main/resources/mapper/blacklisted/FlowBlacklistedMacMapper.xml:13:MAC 导入 SQL。ik_project/yudao-cloud/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/enums/BusinessTypeEnum.java:22:BLACK_LIST 编码。
核验日期:2026-09-18。规则匹配结果、当前开关及缓存状态未做运行验证。