# 异常数据分析 > **文档目的**:根据业务表结构,预先梳理各模块可能产生脏数据的数据库表及对应的脏数据类型,供后续脏数据检测开发使用。 --- ## 目录 - [一、脏数据类型汇总](#一脏数据类型汇总) - [二、健康评估](#二健康评估) - [2.1 涉及数据库表](#21-涉及数据库表) - [2.2 系统脏数据检测规则](#22-系统脏数据检测规则) - [2.3 检测频率建议](#23-检测频率建议) - [三、健康咨询](#三健康咨询) - [3.1 涉及数据库表](#31-涉及数据库表) - [3.2 系统脏数据检测规则](#32-系统脏数据检测规则) - [3.3 现有后端实现评估](#33-现有后端实现评估) - [3.4 检测频率建议](#34-检测频率建议) - [四、应急就医](#四应急就医) - [4.1 涉及数据库表](#41-涉及数据库表) - [4.2 系统脏数据检测规则](#42-系统脏数据检测规则) - [4.3 检测频率建议](#43-检测频率建议) - [五、营养管理](#五营养管理) - [5.1 涉及数据库表](#51-涉及数据库表) - [5.2 系统脏数据检测规则](#52-系统脏数据检测规则) - [5.3 现有后端实现评估](#53-现有后端实现评估) - [5.4 检测频率建议](#54-检测频率建议) - [六、健康监测](#六健康监测) - [6.1 涉及数据库表](#61-涉及数据库表) - [6.2 系统脏数据检测规则](#62-系统脏数据检测规则) - [6.3 检测频率建议](#63-检测频率建议) --- ## 一、脏数据类型汇总 | 脏数据类型 | 健康评估 | 健康咨询 | 应急就医 | 营养管理 | 健康监测 | |------------|:--:|:--:|:--:|:--:|:--:| | 数据缺失 | ✅ | ✅ | — | ✅ | ✅ | | 格式错误 | ✅ | ✅ | — | ✅ | ✅ | | 逻辑矛盾 | ✅ | ✅ | ✅ | ✅ | ✅ | | 重复数据 | ✅ | — | — | ✅ | ✅ | | 范围越界 | ✅ | ✅ | — | ✅ | ✅ | | 关联缺失 | ✅ | ✅ | ✅ | ✅ | ✅ | | 状态异常 | ✅ | ✅ | ✅ | — | — | | 非法数据 | — | — | ✅ | — | — | | 异常坐标 | — | — | ✅ | — | — | --- ## 二、健康评估 > **后端服务**:`platform-assessment`(端口 24803)| **原型参考**:评估模块原型使用摹刀独立设计 > > **开发状态**:⚠️ 后端已有 `AssDataAbnormalController` 占位(返回硬编码 mock 数据)。 健康评估模块对员工进行多维度健康评估,包括风险评估、心理评估、规律起居评估、人群分类等。 ### 2.1 涉及数据库表 评估模块共 21 张业务表,按子域分类如下。 #### 风险评估(7+2 张表) | 表名 | 说明 | 脏数据风险 | |------|------|:--:| | `ass_risk_evaluation` | 风险评估主表(问卷+自动双模式) | 高 — `eval_source`(评估来源:1=问卷/2=自动)、`status`(任务状态:1=成功/2=处理中/3=失败)、`is_exception`(是否异常:0=否/1=是)、`user_id`(用户ID) | | `ass_risk_result` | 风险评估结果(疾病等级、BMI、生活习惯标记) | 高 — `bmi`(BMI值)、`sbp`(收缩压)/`dbp`(舒张压)、`fasting_bg`(空腹血糖)、`diabetes_level`(糖尿病等级)、`bmi_mark`(BMI标记格式) | | `ass_risk_evaluation_statistics` | 风险评估统计(按用户/年份汇总) | 中 — `statics_num`(统计评估次数)、`exception_num`(异常评估次数) | | `ass_risk_factor` | 风险因素明细 | 中 — `current_value`(当前检测值)、`reference_range`(参考范围)、`is_abnormal`(是否异常) | | `ass_risk_questionnaire_info` | 问卷基础信息(病史、生活方式) | 高 — `height`(身高cm)/`weight`(体重kg)/`waist_line`(腰围cm)、`smoking_status`(吸烟状态:1-3) | | `ass_risk_diet_sports_prescription` | 饮食运动处方 | 中 — `f_elements`(食物元素格式)、`aerobic_*`(有氧运动)、`strength_*`(力量训练)、`flexibility_*`(柔韧训练) | | `ass_risk_hms_log` | 第三方HMS接口调用日志 | 低 — XML 格式完整性 | | `ass_risk_request_cache` | MD5请求去重缓存 | 低 — 缓存过期/碰撞 | | `ass_risk_food_element` | 食物营养元素字典 | 低 — 字典数据完整性 | #### 心理评估(3 张表) | 表名 | 说明 | 脏数据风险 | |------|------|:--:| | `ass_psychology` | 心理评估主表(综合/压力/焦虑/抑郁) | 高 — `type`(评估类型:1=综合/2=压力/3=焦虑/4=抑郁)、`grade`(评估得分)、`phy_grade_level`(健康等级)、`is_exception`(是否异常)、`status`(任务状态) | | `ass_psychology_statistics` | 心理评估统计 | 中 — 统计值与实际记录数一致性 | | `ass_influence_factor` | 心理影响因素评估 | 中 — 因子数据完整性 | #### 规律起居(2 张表) | 表名 | 说明 | 脏数据风险 | |------|------|:--:| | `ass_daily_routine_online` | 在线穿戴数据评估(睡眠/运动/心率/血氧/压力) | 高 — `sleep_hour`(睡眠时长分钟)、`sport_minute`(运动时长分钟)、`resting_heart_rate`(静息心率bpm)、`oxygen_saturation`(血氧饱和度%)、`week_start_date`(周开始日期)/`week_end_date`(周结束日期) | | `ass_daily_routine_paper` | 问卷规律起居(体力活动/睡眠/上网) | 中 — `sport_value`(运动值)、`sleep_value`(睡眠值)、`time_of_net_value`(上网时长)、`questions_id`(关联问卷ID) | #### 人群分类(4 张表) | 表名 | 说明 | 脏数据风险 | |------|------|:--:| | `ass_group_user` | 人群分类主表(A/B/C/D/E五类) | 高 — `user_group`(人群分类枚举:A/B/C/D/E)、`audit_status`(审核状态:0-2)、`is_archived`(是否归档)、`latest_assessment_date`(最近评估日期) | | `ass_group_user_detail` | 人群分类明细(疾病/体检项) | 中 — `detail_type`(明细类型:A/B/C/D)、`item_code`(项目编码)、`risk_level_flag`(风险等级标记) | | `ass_group_user_change_his` | 分类变更历史 | 低 — 变更记录完整性 | | `ass_group_user_audit_his` | 分类审核历史 | 低 — 审核记录完整性 | #### 共享/基础(3 张表) | 表名 | 说明 | 脏数据风险 | |------|------|:--:| | `ass_questions` | 问卷答案(JSON) | 中 — `questions_json`(问卷JSON)、`status`(状态:卡处理中) | | `ass_algorithm_model` | 算法模型文档 | 低 | | `ass_trigger_config` | 评估触发器配置 | 低 | ### 2.2 系统脏数据检测规则 > 参照营养模块 `nut_ano_dirty` 模式。mock 数据中定义了四种异常类型:缺失值、超范围值、重复数据、格式错误。 #### 风险评估 **评估主表(`ass_risk_evaluation`)** | 异常类型 | 检测规则 | 涉及字段 | 说明 | |----------|----------|----------|------| | 数据缺失 | `user_id` 为 NULL | `user_id`(用户ID) | 评估记录无归属人 | | 范围越界 | `eval_source` 不在 1-2 范围内 | `eval_source`(评估来源) | 评估来源异常(1=问卷/2=自动) | | 状态异常 | `status` = 2(处理中)或 3(失败)超过 24 小时 | `status`(任务状态) | 评估任务卡住未完成 | | 逻辑矛盾 | `is_exception` = 1 但 `ass_risk_result` 中所有疾病等级均为正常 | `is_exception`(是否异常) ↔ `ass_risk_result.*_level`(疾病等级) | 异常标记与结果数据不一致 | **评估结果(`ass_risk_result`)** | 异常类型 | 检测规则 | 涉及字段 | 说明 | |----------|----------|----------|------| | 范围越界 | BMI 值 < 10 或 > 80 | `bmi`(BMI值) | 超出人体可能范围 | | 范围越界 | 收缩压 < 50 或 > 300 mmHg | `sbp`(收缩压) | 血压值异常 | | 范围越界 | 舒张压 < 30 或 > 200 mmHg | `dbp`(舒张压) | 血压值异常 | | 逻辑矛盾 | `sbp` < `dbp` | `sbp`(收缩压)、`dbp`(舒张压) | 收缩压低于舒张压 | | 范围越界 | `fasting_bg`(空腹血糖)< 0 或 > 50 mmol/L | `fasting_bg`(空腹血糖) | 血糖值异常 | | 范围越界 | `health_age` / `potential_health_age` 计算为负数或 > 150 | `health_age`(健康年龄)、`potential_health_age`(潜在健康年龄) | 健康年龄异常 | | 格式错误 | `bmi_mark` / `smoke_mark` / `sleep_mark` 等不符合 `state,score,fullmark` 格式 | `*_mark` 字段(生活习惯标记) | 生活习惯标记格式异常 | | 范围越界 | 疾病等级(`diabetes_level`、`hypertension_level` 等)不在预期枚举范围内 | `*_level` 字段(疾病等级) | 等级编码越界 | | 逻辑矛盾 | `cholesterol`、`triglycerin`、`hdlc`、`ldlc` 均为 0 或 NULL 但疾病等级非空 | 血脂四项 + `*_level`(疾病等级) | 血脂数据缺失但给出了疾病评级 | **问卷信息(`ass_risk_questionnaire_info`)** | 异常类型 | 检测规则 | 涉及字段 | 说明 | |----------|----------|----------|------| | 范围越界 | 身高 < 50cm 或 > 250cm | `height`(身高cm) | 录入异常 | | 范围越界 | 体重 < 20kg 或 > 300kg | `weight`(体重kg) | 录入异常 | | 范围越界 | 腰围 < 30cm 或 > 200cm | `waist_line`(腰围cm) | 录入异常 | | 范围越界 | `smoking_status` 不在 1-3 | `smoking_status`(吸烟状态) | 吸烟状态枚举越界 | | 范围越界 | 个人病史字段(`personal_diabetes` 等)不为 0 或 1 | `personal_*` 字段(个人病史) | 病史枚举越界 | | 数据缺失 | `height`、`weight`、`waist_line` 均为 NULL | `height`(身高)、`weight`(体重)、`waist_line`(腰围) | 基础体测数据完全缺失 | | 格式错误 | 问卷 JSON 原始数据格式异常 | `questions_json`(问卷JSON,通过 `ass_questions`) | JSON 解析失败 | **评估统计(`ass_risk_evaluation_statistics`)** | 异常类型 | 检测规则 | 涉及字段 | 说明 | |----------|----------|----------|------| | 逻辑矛盾 | `statics_num` 与 `ass_risk_evaluation` 中实际评估次数不一致 | `statics_num`(统计评估次数) | 统计数据过期 | | 逻辑矛盾 | `is_bmi_abnormal` 等疾病异常标记与 `last_evaluation_id` 对应结果数据不一致 | `is_*_abnormal` 字段(疾病异常标记) | 统计标记与源数据脱节 | | 逻辑矛盾 | `exception_num` 与实际 `is_exception=1` 的记录数不一致 | `exception_num`(异常计数) | 异常计数错误 | #### 心理评估 | 异常类型 | 检测规则 | 涉及表 | 涉及字段 | |----------|----------|--------|----------| | 范围越界 | `type` 不在 1-4(综合/压力/焦虑/抑郁) | `ass_psychology` | `type`(评估类型) | | 范围越界 | `grade` 超出该量表合理分值范围 | `ass_psychology` | `grade`(评估得分) | | 数据缺失 | `grade` 或 `phy_grade_level` 为 NULL | `ass_psychology` | `grade`(评估得分)、`phy_grade_level`(健康等级) | | 格式错误 | `phy_grade_level` 编码不在数据字典范围内 | `ass_psychology` | `phy_grade_level`(健康等级编码) | | 状态异常 | `status` = 2(分析中)超过 24 小时 | `ass_psychology` | `status`(任务状态) | | 逻辑矛盾 | `is_exception` = 1 但 `grade` 在正常范围内 | `ass_psychology` | `is_exception`(是否异常) ↔ `grade`(评估得分) | | 关联缺失 | `questions_id` 在 `ass_questions` 中不存在 | `ass_psychology` | `questions_id`(关联问卷ID) | | 逻辑矛盾 | `ass_psychology_statistics` 统计值与实际评估记录数不一致 | `ass_psychology_statistics` | — | #### 规律起居 **在线穿戴评估(`ass_daily_routine_online`)** | 异常类型 | 检测规则 | 涉及字段 | 说明 | |----------|----------|----------|------| | 范围越界 | `sleep_hour` < 0 或 > 1440 分钟 | `sleep_hour`(睡眠时长分钟) | 睡眠时长不合理 | | 范围越界 | `sport_minute` < 0 或 > 1440 分钟 | `sport_minute`(运动时长分钟) | 运动时长不合理 | | 范围越界 | `resting_heart_rate` < 30 或 > 220 bpm | `resting_heart_rate`(静息心率bpm) | 静息心率异常 | | 范围越界 | `oxygen_saturation` < 60% 或 > 100% | `oxygen_saturation`(血氧饱和度%) | 血氧值异常 | | 范围越界 | `pressure_value` 超出传感器量程 | `pressure_value`(压力值) | 压力值异常 | | 逻辑矛盾 | `week_end_date` < `week_start_date` | `week_end_date`(周结束日期)、`week_start_date`(周开始日期) | 周起止日期倒置 | | 逻辑矛盾 | `sleep_hour` + `sport_minute` > 1440 | `sleep_hour`(睡眠时长)、`sport_minute`(运动时长) | 睡眠+运动超过24小时 | | 状态异常 | `status` = 2(分析中)超过 24 小时 | `status`(任务状态) | 任务卡住 | | 数据缺失 | `is_exception` 为 NULL | `is_exception`(是否异常) | 异常标记缺失 | **问卷评估(`ass_daily_routine_paper`)** | 异常类型 | 检测规则 | 涉及字段 | 说明 | |----------|----------|----------|------| | 范围越界 | `sport_value` / `sleep_value` / `time_of_net_value` 为负值 | `sport_value`(运动值)、`sleep_value`(睡眠值)、`time_of_net_value`(上网时长) | 负数无意义 | | 范围越界 | `time_of_net_value` > 24 小时 | `time_of_net_value`(上网时长) | 上网时长不合理 | | 范围越界 | `sport_level` / `sleep_type` / `time_of_net_level` 不在枚举范围 | `sport_level`(运动等级)、`sleep_type`(睡眠类型)、`time_of_net_level`(上网等级) | 等级编码越界 | | 关联缺失 | `questions_id` 在 `ass_questions` 中不存在 | `questions_id`(关联问卷ID) | 孤立问卷关联 | | 数据缺失 | `is_exception` 为 NULL | `is_exception`(是否异常) | 异常标记缺失 | #### 人群分类 | 异常类型 | 检测规则 | 涉及表 | 涉及字段 | |----------|----------|--------|----------| | 范围越界 | `user_group` 不在 A/B/C/D/E 范围内 | `ass_group_user` | `user_group`(人群分类) | | 范围越界 | `group_change_type` 不在 1-3 | `ass_group_user` | `group_change_type`(变更类型) | | 范围越界 | `audit_status` 不在 0-2 | `ass_group_user` | `audit_status`(审核状态) | | 逻辑矛盾 | `is_archived` = 1 且 `archived_time` 为 NULL | `ass_group_user` | `is_archived`(是否归档)、`archived_time`(归档时间) | | 范围越界 | `date_year` 为未来年份或早于 2020 | `ass_group_user` | `date_year`(归属年份) | | 范围越界 | `latest_assessment_date` 为未来日期 | `ass_group_user` | `latest_assessment_date`(最近评估日期) | | 关联缺失 | `group_user_id` 在 `ass_group_user` 中不存在 | `ass_group_user_detail` | `group_user_id`(人群分类ID) | | 范围越界 | `detail_type` 不在 A/B/C/D | `ass_group_user_detail` | `detail_type`(明细类型) | | 范围越界 | `data_type` 不在 1-2 | `ass_group_user_detail` | `data_type`(数据类型) | | 重复数据 | 同一用户同一年度存在多条活跃分类记录 | `ass_group_user` | `user_id`(用户ID) + `date_year`(归属年份) | #### 问卷与处方 | 异常类型 | 检测规则 | 涉及表 | 涉及字段 | |----------|----------|--------|----------| | 格式错误 | `questions_json` 格式非法(JSON 解析失败) | `ass_questions` | `questions_json`(问卷JSON) | | 状态异常 | `status` = 2(分析中)超过 24 小时 | `ass_questions` | `status`(任务状态) | | 格式错误 | `f_elements` 不符合 `meal_foodCode_amount;...` 格式 | `ass_risk_diet_sports_prescription` | `f_elements`(食物元素格式) | | 范围越界 | `energy_level` 为负值或 > 10000 kcal | `ass_risk_diet_sports_prescription` | `energy_level`(能量等级) | | 数据缺失 | 评估正常但处方中所有运动字段为 NULL | `ass_risk_diet_sports_prescription` | `aerobic_*`(有氧运动)、`strength_*`(力量训练)、`flexibility_*`(柔韧训练) | ### 2.3 检测频率建议 | 检测类型 | 建议频率 | 说明 | |----------|----------|------| | 评估任务卡住检测 | 每小时 | `status=2` 超过 24 小时的记录 | | 数值范围越界检测 | 每日凌晨(评估任务完成后) | 全量扫描 BMI/血压/心率等 | | 统计一致性校验 | 每日凌晨 | `statics_num` vs 实际记录数 | | 格式校验(JSON/mark) | 数据入库时实时 | 问卷JSON、`f_elements`、`*_mark` | --- ## 三、健康咨询 > **后端服务**:`platform-consult`(端口 24806)| **原型参考**:无独立原型页面 > > **开发状态**:✅ 已实现 `con_exception_dirty` 表 + 3 种异常类型定时检测,管理端分页查询/忽略/导出功能完整。 健康咨询模块管理员工在线图文/视频咨询全流程,涵盖咨询会话、专家管理、病历档案、IM 消息、评价结算等。 ### 3.1 涉及数据库表 #### 咨询核心(4 张表) | 表名 | 说明 | 脏数据风险 | |------|------|:--:| | `con_consult` | 咨询会话主表(图文/视频统一) | 高 — `consult_no`(咨询单号)、`content_status`(预约/咨询状态:1-8)、`session_status`(会话状态:1=进行中/2=已结束)、`start_time`(开始时间)/`end_time`(结束时间)、`duration_minutes`(咨询时长秒)、`score`(用户评分1-5)、`cost`(咨询费用) | | `con_evaluate` | 咨询评价表 | 高 — `score`(评分1-5)、`consult_id`(关联咨询ID)、`expert_id`(被评价专家ID) | | `con_medical_record` | 病历档案表 | 中 — `medical_describe`(病情描述)、`duration_type`(持续时间:1-4)、`images`(检查资料图片URL) | | `con_family_member` | 家庭成员/咨询人表 | 中 — `member_name`(成员姓名)、`birthday`(出生日期)、`height`(身高cm)、`weight`(体重kg)、`relation`(家庭关系) | #### 专家与排班(2 张表) | 表名 | 说明 | 脏数据风险 | |------|------|:--:| | `con_expert` | 专家信息表 | 高 — `expert_no`(专家编号)、`expert_type`(专家类型:1=收费/2=免费/3=其他)、`overall_merit`(综合评分)、`response_rate`(24h回复率)、`hospital_id`(所属医院ID)、`dept_id`(所属科室ID)、`reg_date`(入职日期)/`off_date`(离职日期) | | `con_expert_schedule_rule` | 专家排班规则表(按周设置) | 中 — `week_day`(周几:1-7)、`period`(时段:1-4)、`start_time`(出诊开始时间)/`end_time`(出诊结束时间)、`capacity`(接诊人数上限) | #### IM 消息(2 张表) | 表名 | 说明 | 脏数据风险 | |------|------|:--:| | `con_im_message` | IM消息记录表 | 中 — `msg_key`(腾讯IM消息唯一标识)、`msg_type`(消息类型:1=单聊/2=群聊/3=应急群聊/4=音视频)、`msg_content`(消息内容)、`send_time`(发送时间)、`consult_id`(关联咨询ID) | | `con_im_chat` | IM聊天会话表(通讯录单聊) | 中 — `session_id`(会话ID)、`pair_id`(会话对唯一标识)、`from_user_id`(发起者)、`to_user_id`(接受者) | #### 结算(4 张表) | 表名 | 说明 | 脏数据风险 | |------|------|:--:| | `con_settle_main` | 结算主表 | 中 — `settle_status`(结算状态:0=待结算/1=结算中/2=已结算/3=异常)、`com_fee_per_month`(每月通讯费)、`error_msg`(异常信息) | | `con_settle_result` | 结算结果 | 中 — 金额一致性 | | `con_settle_result_item` | 结算结果明细 | 中 — 明细与汇总一致性 | | `con_settle_cost_config` | 费用配置 | 低 — 配置值合理性 | #### 基础数据(4 张表) | 表名 | 说明 | 脏数据风险 | |------|------|:--:| | `con_hospital` | 医院关联配置 | 中 — `ref_id`(关联外部医院ID) | | `con_hospital_dept` | 医院-科室关联表 | 低 — `hospital_id`(医院ID)、`dept_id`(科室ID) | | `con_department` | 科室表 | 中 — `dept_name`(科室名称)、`parent_id`(上级科室ID) | | `con_disease` | 疾病信息表 | 低 — `disease_name`(疾病名称)、`dept_id`(所属科室ID) | #### 其他(4 张表) | 表名 | 说明 | 脏数据风险 | |------|------|:--:| | `con_notice` | 咨询须知表 | 低 | | `con_phrase` | 常用语表 | 低 | | `con_settle_period_config` | 结算周期配置 | 低 | ### 3.2 系统脏数据检测规则 > 后端已实现 `con_exception_dirty` 表,目前定义了 3 种异常类型:咨询时长异常(`exception_type=1`)、长时间未回复(`exception_type=2`)、评价分数极低(`exception_type=3`)。 > > ⚠️ **已知问题**:`ConConsultTimeoutJob` 每小时自动关闭超时 7 天的会话,因此"咨询时长异常"检测的阈值必须设置在 7 天以内,否则异常记录永远无法生成。 > > ⚠️ **已知缺陷**:`ConExceptionDirtyMapper.xml` 第 29 行 `work_no` 被硬编码为 `NULL`,前端展示员工工号列为空。 > > ⚠️ **已知缺陷**:`ConExceptionDirtyMapper.xml` 中 `h."name" AS hospital_name` 引用了 `con_hospital` 表中可能不存在的 `name` 列(`con_hospital` 实体仅有 `ref_id` 无 `name`),需确认运行时是否会报错或从外部服务取数。 #### 咨询会话(已有) | 异常类型 | 检测规则 | 涉及表 | 涉及字段 | 说明 | |----------|----------|--------|----------|------| | 状态异常 | 咨询时长异常:会话进行中但 `duration_minutes` 超过合理阈值(如 > 60 分钟) | `con_consult` | `duration_minutes`(咨询时长)、`content_status`(预约/咨询状态) | `exception_type=1`,需在超时 Job(7天)前触发 | | 状态异常 | 长时间未回复:专家超过 N 小时未回复用户消息 | `con_consult` | `last_reply_time`(最后回复时间)、`content_status`(预约/咨询状态) | `exception_type=2` | | 范围越界 | 评价分数极低:`score` < 2 分 | `con_evaluate` / `con_consult` | `score`(评分) | `exception_type=3` | #### 咨询会话(建议新增) | 异常类型 | 检测规则 | 涉及表 | 涉及字段 | 说明 | |----------|----------|--------|----------|------| | 逻辑矛盾 | `start_time` > `end_time` | `con_consult` | `start_time`(开始时间)、`end_time`(结束时间) | 咨询结束时间早于开始时间 | | 逻辑矛盾 | `session_status` = 进行中(1) 但 `end_time` 不为空 | `con_consult` | `session_status`(会话状态)、`end_time`(结束时间) | 状态与时间矛盾 | | 逻辑矛盾 | `content_status` = 已完成(3) 但 `end_time` 为空 | `con_consult` | `content_status`(预约/咨询状态)、`end_time`(结束时间) | 已完成但无结束时间 | | 逻辑矛盾 | `content_status` = 已拒绝(8) 但 `reject_reason` 为空 | `con_consult` | `content_status`(预约/咨询状态)、`reject_reason`(拒绝原因) | 拒绝但无理由 | | 范围越界 | `duration_minutes` < 0 | `con_consult` | `duration_minutes`(咨询时长) | 咨询时长为负数 | | 范围越界 | `consult_type` 不在 1-2 | `con_consult` | `consult_type`(咨询类型:1=图文/2=视频) | 咨询类型枚举越界 | | 范围越界 | `content_status` 不在 1-8 | `con_consult` | `content_status`(预约/咨询状态) | 内容状态枚举越界 | | 范围越界 | `cost` < 0 | `con_consult` | `cost`(咨询费用) | 咨询费用为负数 | | 关联缺失 | `expert_id` 在 `con_expert` 中不存在 | `con_consult` | `expert_id`(专家ID) | 关联专家已删除 | | 关联缺失 | `member_id` 不为空但在 `con_family_member` 中不存在 | `con_consult` | `member_id`(咨询人ID) | 关联咨询人已删除 | | 数据缺失 | `consult_no` 为空 | `con_consult` | `consult_no`(咨询单号) | 咨询单号缺失 | #### 专家信息 | 异常类型 | 检测规则 | 涉及表 | 涉及字段 | 说明 | |----------|----------|--------|----------|------| | 范围越界 | `overall_merit` < 0 或 > 5 | `con_expert` | `overall_merit`(综合评分) | 综合评分越界 | | 范围越界 | `response_rate` < 0 或 > 100 | `con_expert` | `response_rate`(24h回复率%) | 回复率越界 | | 范围越界 | `expert_type` 不在 1-3 | `con_expert` | `expert_type`(专家类型) | 专家类型枚举越界 | | 数据缺失 | `expert_no` 为空 | `con_expert` | `expert_no`(专家编号) | 专家编号缺失 | | 逻辑矛盾 | `off_date` < `reg_date`(均已填写时) | `con_expert` | `off_date`(离职日期)、`reg_date`(入职日期) | 离职日期早于入职日期 | | 关联缺失 | `hospital_id` 在 `con_hospital` 中不存在 | `con_expert` | `hospital_id`(所属医院ID) | 关联医院不存在 | | 关联缺失 | `dept_id` 在 `con_department` 中不存在 | `con_expert` | `dept_id`(所属科室ID) | 关联科室不存在 | #### 咨询评价 | 异常类型 | 检测规则 | 涉及表 | 涉及字段 | 说明 | |----------|----------|--------|----------|------| | 范围越界 | `score` < 0 或 > 5 | `con_evaluate` | `score`(评分) | 评分越界 | | 关联缺失 | `consult_id` 在 `con_consult` 中不存在 | `con_evaluate` | `consult_id`(关联咨询ID) | 评价关联的咨询不存在 | | 关联缺失 | `expert_id` 在 `con_expert` 中不存在 | `con_evaluate` | `expert_id`(被评价专家ID) | 评价关联的专家不存在 | #### 家庭成员 | 异常类型 | 检测规则 | 涉及表 | 涉及字段 | 说明 | |----------|----------|--------|----------|------| | 范围越界 | `height` < 50 或 > 250 (cm) | `con_family_member` | `height`(身高cm) | 身高越界 | | 范围越界 | `weight` < 20 或 > 300 (kg) | `con_family_member` | `weight`(体重kg) | 体重越界 | | 范围越界 | `sex` 不在 1-2 | `con_family_member` | `sex`(性别:1=男/2=女) | 性别枚举越界 | | 范围越界 | `birthday` 为未来日期 | `con_family_member` | `birthday`(出生日期) | 生日为未来日期 | #### 病历档案 | 异常类型 | 检测规则 | 涉及表 | 涉及字段 | 说明 | |----------|----------|--------|----------|------| | 数据缺失 | `medical_describe` 为空 | `con_medical_record` | `medical_describe`(病情描述) | 病情描述缺失 | | 范围越界 | `duration_type` 不在 1-4 | `con_medical_record` | `duration_type`(持续时间:1=几天内/2=1-2周/3=1-3月/4=3月以上) | 持续时间枚举越界 | #### IM 消息 | 异常类型 | 检测规则 | 涉及表 | 涉及字段 | 说明 | |----------|----------|--------|----------|------| | 数据缺失 | `msg_content` 为空且非撤回消息 | `con_im_message` | `msg_content`(消息内容) | 消息内容缺失 | | 范围越界 | `msg_type` 不在 1-4 | `con_im_message` | `msg_type`(消息类型) | 消息类型枚举越界 | | 关联缺失 | `consult_id` 不为空但在 `con_consult` 中不存在 | `con_im_message` | `consult_id`(关联咨询ID) | 消息关联的咨询不存在 | #### 排班规则 | 异常类型 | 检测规则 | 涉及表 | 涉及字段 | 说明 | |----------|----------|--------|----------|------| | 范围越界 | `week_day` 不在 1-7 | `con_expert_schedule_rule` | `week_day`(星期:1=周一~7=周日) | 星期枚举越界 | | 范围越界 | `period` 不在 1-4 | `con_expert_schedule_rule` | `period`(时段:1-4) | 时段枚举越界 | | 范围越界 | `capacity` < 0 | `con_expert_schedule_rule` | `capacity`(接诊人数上限) | 接诊人数为负 | | 逻辑矛盾 | `end_time` < `start_time` | `con_expert_schedule_rule` | `start_time`(出诊开始时间)、`end_time`(出诊结束时间) | 排班结束时间早于开始时间 | ### 3.3 现有后端实现评估 #### 已实现 | 组件 | 状态 | 说明 | |------|:--:|------| | `con_exception_dirty` 表 | ✅ 已上线 | 5个字段:consult_id、consult_no、exception_type、exception_value、alarm_time | | `ConExceptionDirtyController` | ✅ 已上线 | `/page` 分页查询 + `/ignore` 批量忽略 + `/export` 导出 | | `ConExceptionDirtyService` | ✅ 已上线 | 分页 JOIN 咨询/专家/医院 + Feign 批量查用户名 | | `ExceptionTypeEnum` | ✅ 已上线 | 3 种异常类型:时长异常/长时间未回复/低分评价 | | `ConConsultTimeoutJob` | ✅ 已上线 | 每小时扫描,7 天超时自动关闭会话 | #### 待完善 | 项目 | 优先级 | 说明 | |------|:--:|------| | 异常数据自动检测定时任务 | 高 | 需实现定时扫描生成 `con_exception_dirty` 记录 | | `work_no` 字段补充 | 高 | 当前 Mapper XML 硬编码为 NULL,需 JOIN `con_user_snapshot` 获取 | | 咨询时长异常阈值与超时 Job 的协调 | 高 | 时长异常应在超时 Job 触发前检测(如 > 60 分钟即告警,而非等 7 天) | | 专家/家庭成员/病历/排班等数据校验 | 中 | 当前仅覆盖咨询会话维度的 3 种异常 | | IM 消息数据完整性校验 | 低 | 消息内容、关联关系 | ### 3.4 检测频率建议 | 检测类型 | 建议频率 | 说明 | |----------|----------|------| | 咨询时长异常检测 | 每 30 分钟 | 需在超时 Job(7天)前触发,建议 > 60 分钟即告警 | | 长时间未回复检测 | 每小时 | 检查 `last_reply_time` 超过阈值 | | 低分评价检测 | 评价生成时实时 | 评价提交后即时判断 | | 枚举/范围/逻辑矛盾校验 | 每日凌晨 | 全量扫描各表枚举字段和数值范围 | --- ## 四、应急就医 > **后端服务**:`platform-emergency`(端口 24808)| **原型参考**:`web-admin/emergency-dispatch/admin/exception-dirty.html` > > **开发状态**:⚠️ 后端已有 `EmDirtyDataController` 占位(返回空数据),`EmExceptionDictConstant` 定义常量;尚未实现具体检测和存储。 应急就医管理员工应急工单、云坐席通话、AED 设备部署与管理、救护车调度等。脏数据类型与其他模块差异较大,主要关注 **AED 设备**数据质量和**通话记录**完整性。 ### 4.1 涉及数据库表 #### 核心应急表 | 表名 | 说明 | 脏数据风险 | |------|------|:--:| | `em_emergency_center` | 应急中心 | 中 — `longitude`(经度)/`latitude`(纬度)、`center_phone`(中心电话)、`status`(状态) | | `em_user_profile` | 应急人员档案 | 中 — `cert_number`(证书编号)、`license_number`(执照编号)、`station_status`(驻场状态) | | `em_call_record` | 通话记录(七陌云客服) | 高 — `incoming_phone`(来电号码)、`match_status`(匹配状态:1=唯一匹配/2=多重匹配)、`employee_id`(匹配员工ID)、`duration`(通话时长) | | `em_emergency_order` | 应急工单 | 高 — `order_no`(工单编号)、`status`(工单状态)、`location_desc`(位置描述)、`location_lat`(纬度)/`location_lng`(经度)、`closed_at`(关闭时间) | | `em_work_order_dispatch` | 工单调度日志 | 中 — 调度链路完整性 | #### AED 设备管理 | 表名 | 说明 | 脏数据风险 | |------|------|:--:| | `em_aed_device` | AED 设备主表 | 高 — `battery_level`(电池电量百分比)、`battery_status`(电池状态枚举) | | `em_aed_deploy_point` | AED 部署点位 | 高 — `longitude`(经度)、`latitude`(纬度) | | `em_aed_maintenance` | AED 维护记录 | 中 — 维护日期、到期提醒 | | `em_aed_latest` | AED 最新状态 | 高 — `battery_power`(厂商原始电池数据String)、实时状态聚合 | | `em_aed_warn_info` | AED 告警信息 | 中 — 告警记录 | | `em_aed_usage` | AED 使用记录 | 中 — 使用时间、使用人 | #### 其他应急表 | 表名 | 说明 | 脏数据风险 | |------|------|:--:| | `em_ambulance` | 救护车 | 中 — `plate_no`(车牌号)、`driver`(驾驶员)、`status`(状态) | | `em_schedule_record` | 值班排班记录 | 中 — 排班时间冲突 | | `em_emergency_contact` | 紧急联系人 | 中 — 联系方式有效性 | | `em_emergency_center_call_record` | 应急中心通话记录 | 中 — `call_id`(通话ID)、`employee_id`(员工ID)、`begin_time`(开始时间)、`end_time`(结束时间)、`record_file`(录音文件) | | `em_emergency_center_call_join` | 应急中心通话参与人 | 中 — 参与人关联完整性、`employee_id`(员工ID) | | `em_hospital` | 应急合作医院 | 低 | | `em_first_aid_kit` | 急救箱 | 中 — 过期检查 | | `em_drill_record` | 演练记录 | 低 | ### 4.2 系统脏数据检测规则 > 应急模块使用独特的异常类型分类:非法数据 / 异常坐标 / 状态异常。 > > **注意**:后端 `EmExceptionDictConstant` 当前定义了 `MISSING_FIELD` / `INVALID_FORMAT` / `ORPHAN_RECORD`,与原型中的 `非法数据` / `异常坐标` / `状态异常` 分类不一致,需后续对齐。 #### 通话记录 | 异常类型 | 检测规则 | 涉及表 | 涉及字段 | 说明 | |----------|----------|--------|----------|------| | 非法数据 | 电话号码格式不合法(非国内手机号/非座机号) | `em_call_record` | `incoming_phone`(来电号码) | 云客服传入的号码非法 | | 状态异常 | `match_status` 为"多重匹配"(=2),存在多个员工对应同一号码 | `em_call_record` | `match_status`(匹配状态)、`employee_id`(匹配员工ID) | 一个号码匹配到多名员工,需人工确认 | | 关联缺失 | 通话记录关联的 `order_id` 在 `em_emergency_order` 中不存在 | `em_call_record` | `order_id`(关联工单ID) | 孤立的工单关联 | | 逻辑矛盾 | 通话结束时间早于开始时间 | `em_call_record` | `begin_time`(开始时间)、`end_time`(结束时间) | 时间戳异常 | | 逻辑矛盾 | 通话状态为"已接听"但时长为 0 | `em_call_record` | `answer_status`(接听状态) + `duration`(通话时长) | 状态与数据矛盾 | #### AED 设备管理 | 异常类型 | 检测规则 | 涉及表 | 涉及字段 | 说明 | |----------|----------|--------|----------|------| | 非法数据 | 电池电量百分比超出 0-100% 范围(如 = 260%) | `em_aed_device` | `battery_level`(电池电量百分比) | 硬件上传了不可能的电量值 | | 非法数据 | 设备上报的原始电池电压/电量(String 类型,厂商原始值) | `em_aed_latest` | `battery_power`(厂商原始电池数据) | 厂商原始电池数据,非 0-100% 百分比 | | 非法数据 | 电池状态值不在预定义枚举范围内 | `em_aed_device` | `battery_status`(电池状态) | 状态码异常,如"未知" | | 异常坐标 | GPS 坐标不在国内范围(经度 73-135°E,纬度 18-54°N) | `em_aed_deploy_point` | `longitude`(经度)、`latitude`(纬度) | 如坐标指向海外(悉尼) | | 异常坐标 | GPS 坐标为 (0,0) 或 NULL(未获取到定位) | `em_aed_deploy_point` | `longitude`(经度)、`latitude`(纬度) | AED 部署点位无有效坐标 | | 关联缺失 | AED 部署点位关联的应急中心不存在 | `em_aed_deploy_point` ↔ `em_emergency_center` | 中心关联字段 | | | 逻辑矛盾 | AED 最近一次维护日期晚于当前日期 | `em_aed_maintenance` | 维护日期 | 未来日期,数据录入错误 | | 数据缺失 | AED 设备缺少维护记录 | `em_aed_device` ↔ `em_aed_maintenance` | | 设备部署后从未维护 | > **注意**:AED 设备离线检测(基于心跳时间差)当前暂不可用,因为 `em_aed_latest` 表缺少 `update_time` 字段。需后续新增该字段。 ### 4.3 检测频率建议 | 检测类型 | 建议频率 | 说明 | |----------|----------|------| | 系统脏数据 — AED 电池/坐标 | 每日凌晨 | AED 设备数据量小 | | 系统脏数据 — 通话记录非法数据 | 每日凌晨 | 通话记录增量扫描 | | AED 设备离线检测 | 每小时 | `em_aed_latest` 心跳超时判断 | --- ## 五、营养管理 > **后端服务**:`platform-nutrition`(端口 24810)| **原型参考**:`web-admin/nutrition/ano-dirty.html` > > **开发状态**:✅ 已实现脏数据存储表 `nut_ano_dirty`,服务已上线。 营养管理是系统最大的模块(约 130 张表),涵盖菜品/食谱管理、订餐/取餐、农场种植养殖、原材料采购库存、中央厨房生产、营养算法与 AI 推荐等全链路。 ### 5.1 涉及数据库表 #### 用户与档案 | 表名 | 说明 | 脏数据风险 | |------|------|:--:| | `nut_user` | 营养用户(用餐者) | 高 — `phone`(手机号)、`bmi`(BMI值)、`health_tags`(健康标签) | | `nut_user_profile` | 用户健康档案 | 高 — `height`(身高)、`weight`(体重)、`target_weight`(目标体重)、`allergies`(过敏原)、`dietary_restrictions`(饮食限制) | | `nut_user_account` | 用户账户/充值 | 中 — 账户余额字段 | | `nut_user_face` | 面部识别数据 | 中 — 面部嵌入向量有效性 | | `nut_member` | 会员记录 | 中 — 会员有效期 | #### 食品与食谱 | 表名 | 说明 | 脏数据风险 | |------|------|:--:| | `nut_food` | 菜品主表 | 高 — `price`(价格)、`nutrition_info`(营养信息)、`status`(状态) | | `nut_food_class` | 菜品分类 | 中 — `parent_id`(上级分类ID) 自引用完整性 | | `nut_food_composition` | 食物成分 | 高 — `value_per_100g`(每100g营养值) | | `nut_food_nutri` | 食物营养数据 | 高 — 详细营养分解 | | `nut_food_spec` | 食物规格/份量 | 中 — `weight`(份量重量) | | `nut_food_check` | 食品检测记录 | 中 — `result`(检测结果)、`passed`(是否通过) | | `nut_recipe` | 食谱 | 中 — `total_calories`(总热量)、`nutrition_summary`(营养汇总JSON) | | `nut_recipe_food` | 食谱-菜品关联 | 中 — `portion`(份数) | | `nut_cookbook` | 菜谱 | 低 — `steps`(步骤) | #### 膳食与订餐 | 表名 | 说明 | 脏数据风险 | |------|------|:--:| | `nut_order` | 订单主表 | 高 — `total_amount`(订单总金额)、`status`(订单状态)、`order_type`(订单类型) | | `nut_order_item` | 订单明细 | 高 — `quantity`(数量)、`price`(单价)、`subtotal`(小计) | | `nut_canteen` | 餐厅/食堂 | 中 — `capacity`(容量)、`status`(状态) | | `nut_canteen_pickup_record` | 取餐记录 | 中 — `portion`(份量)、`calories`(热量) | | `nut_pickup_order` | 取餐订单 | 中 — `nutrition_info`(营养汇总) | | `nut_consume_record` | 消费记录 | 中 — 金额一致性 | | `nut_pay_error` | 支付错误日志 | 低 — 支付异常记录 | #### 原材料与供应 | 表名 | 说明 | 脏数据风险 | |------|------|:--:| | `nut_mater_base` | 原材料主表 | 高 — `price`(价格)、`unit`(单位) | | `nut_raw_inbound` | 原材料入库 | 高 — `quantity`(数量)、`weight`(重量) | | `nut_sup_inventory` | 供应库存 | 高 — `quantity`(库存数量) | | `nut_sup_inventory_flow` | 库存流水 | 中 — `qty`(操作量)、`current_qty_after`(操作后在库量) | | `nut_sup_hygiene_test` | 卫生检测 | 中 — 检测结果 | | `nut_sup_warehouse` | 仓库 | 低 — `location`(位置)、`manager`(管理员) | > **注**:`nut_sup_inventory_flow` 的 SQL DDL 文件缺失(`db/nutrition/` 目录下未找到对应建表脚本),需补充。 #### 生产与中央厨房 | 表名 | 说明 | 脏数据风险 | |------|------|:--:| | `nut_prod_combo_task` | 组合生产任务 | 中 — `plan_date`(计划日期)、`status`(任务状态) | | `nut_prod_qc_sample` | 质检样品 | 高 — `status`(状态:0=留样中/1=已处置/2=已检验) | | `nut_prod_qc_violation` | 质检违规 | 中 — 违规记录完整性 | | `nut_prod_serve_record` | 供餐记录 | 中 — 实际供餐与实际订单一致性 | | `nut_prod_stat_cost` | 生产成本统计 | 中 — 金额合理性 | #### 农场 | 表名 | 说明 | 脏数据风险 | |------|------|:--:| | `nut_farm_plot` | 地块 | 中 — `area`(面积)、`soil_type`(土壤类型) | | `nut_farm_crop_batch` | 作物批次 | 中 — `plant_date`(种植日期)、`expected_harvest`(预计采收日期) | | `nut_farm_harvest` | 采收记录 | 中 — `quantity`(采收数量) | | `nut_farm_livestock_batch` | 牲畜批次 | 中 — `count`(数量) | | `nut_farm_supplier_rating` | 供应商评级 | 低 — 评分范围 | #### 算法与 AI | 表名 | 说明 | 脏数据风险 | |------|------|:--:| | `nut_algo_personal` | 个性化算法结果 | 高 — 营养计算结果 | | `nut_algo_mass` | 批量算法结果 | 高 — 批量计算结果 | | `nut_algo_standard` | 算法标准 | 中 — 标准值合理性 | | `nut_model_llm` | LLM 模型配置 | 中 — 配置有效性 | | `nut_model_small_version` | 模型版本 | 低 — 版本管理 | #### 设备与终端 | 表名 | 说明 | 脏数据风险 | |------|------|:--:| | `nut_terminal` | 终端设备 | 中 — 设备状态 | | `nut_terminal_fault` | 终端故障记录 | 低 | | `nut_meter_device` | 计量设备(秤) | 中 — 计量精度 | | `nut_meter_reading` | 计量读数 | 高 — 读数合理性 | ### 5.2 系统脏数据检测规则 > 后端已实现 `nut_ano_dirty` 表,以下按原型业务模块分类列出需要检测的规则。 #### 用户档案 | 异常类型 | 检测规则 | 涉及表 | 涉及字段 | |----------|----------|--------|----------| | 逻辑矛盾 | 年龄为负数 | `nut_user_profile` | `birthday`(生日) → 计算年龄 | | 范围越界 | BMI 值超出合理范围 | `nut_user` / `nut_user_profile` | `bmi`(BMI值) | | 数据缺失 | 手机号为空 | `nut_user` | `phone`(手机号) | | 重复数据 | 同一 `user_id` 存在多条档案记录 | `nut_user_profile` | `user_id`(用户ID) | | 逻辑矛盾 | 健康目标与饮食限制冲突(如目标为增重但设置了减脂限制) | `nut_user_profile` | `health_goal`(健康目标) ↔ `dietary_restrictions`(饮食限制) | #### 食谱管理 | 异常类型 | 检测规则 | 涉及表 | 涉及字段 | |----------|----------|--------|----------| | 数据缺失 | 热量值字段为空 | `nut_recipe` / `nut_food_nutri` | `total_calories`(总热量) | | 关联缺失 | 食谱引用的食材ID在食材库中不存在 | `nut_recipe_food` | `food_id`(食材ID) → `nut_food.id` | | 格式错误 | 食谱营养汇总JSON格式非法 | `nut_recipe` | `nutrition_summary`(营养汇总JSON) | #### 订餐管理 | 异常类型 | 检测规则 | 涉及表 | 涉及字段 | |----------|----------|--------|----------| | 格式错误 | 订餐日期格式非法 | `nut_order` | 订单日期字段 | | 范围越界 | 单次订餐份数超出系统上限 | `nut_order_item` | `quantity`(数量) | | 逻辑矛盾 | 订单金额与明细小计之和不一致 | `nut_order.total_amount` vs `SUM(nut_order_item.subtotal)` | | #### 营养分析 | 异常类型 | 检测规则 | 涉及表 | 涉及字段 | |----------|----------|--------|----------| | 重复数据 | 同一用户同日存在多条重复营养分析记录 | `nut_algo_personal` | `user_id`(用户ID) + 日期 | | 范围越界 | 营养素计算结果超出合理范围 | `nut_algo_personal` / `nut_algo_mass` | 营养结果字段 | #### 食材库存 | 异常类型 | 检测规则 | 涉及表 | 涉及字段 | |----------|----------|--------|----------| | 范围越界 | 库存数量为负值 | `nut_sup_inventory` | `quantity`(库存数量) | | 逻辑矛盾 | 库存流水余额与当前库存不一致 | `nut_sup_inventory_flow` ↔ `nut_sup_inventory` | `current_qty_after`(操作后在库量) vs `quantity`(库存数量) | | 关联缺失 | 库存记录的原材料在 `nut_mater_base` 中不存在 | `nut_sup_inventory` | `mater_id`(原材料ID) | #### 健康生产 | 异常类型 | 检测规则 | 涉及表 | 涉及字段 | |----------|----------|--------|----------| | 格式错误 | 生产批次号含非法字符 | `nut_prod_combo_task` | `task_no`(任务编号) | | 逻辑矛盾 | 生产任务完成但无供餐记录 | `nut_prod_combo_task` ↔ `nut_prod_serve_record` | | | 数据缺失 | 质检样品无检测结果 | `nut_prod_qc_sample` | `status`(状态:0=留样中/1=已处置/2=已检验) | #### 卫生供应 | 异常类型 | 检测规则 | 涉及表 | 涉及字段 | |----------|----------|--------|----------| | 数据缺失 | 供应商资质证书编号为空 | `nut_farm_supplier_external` | 证书字段 | | 格式错误 | 卫生检测报告编号格式非法 | `nut_sup_hygiene_test` | 检测编号字段 | | 关联缺失 | 供应记录关联的供应商已删除 | `nut_raw_inbound` | `supplier_id`(供应商ID) | ### 5.3 现有后端实现评估 #### 已实现 | 组件 | 状态 | 说明 | |------|:--:|------| | `nut_ano_dirty` 表 | ✅ 已上线 | 5个索引,支持分页/筛选/导出 | | `NutAnoDirtyService` | ✅ 已上线 | 完整 CRUD + 异步导出 | | `NutAnoDirtyController` | ✅ 已上线 | 与原型一致的查询接口 | #### 待完善 | 项目 | 优先级 | 说明 | |------|:--:|------| | 系统脏数据自动检测定时任务 | 高 | 需实现每日全量扫描 Job | | 订餐管理、食材库存、健康生产、卫生供应的脏数据规则 | 高 | 原型有定义但后端可能未覆盖全 | | 农场子域的脏数据检测 | 中 | 原型未明确涉及,但表结构已存在 | | 设备/终端数据脏数据检测 | 低 | 秤读数、终端故障等 | ### 5.4 检测频率建议 | 检测类型 | 建议频率 | 说明 | |----------|----------|------| | 系统脏数据全面扫描 | 每日凌晨 2:00 | 全量扫描所有7个业务模块 | | 库存数量负值检查 | 每日凌晨 + 每次出入库后 | 实时性要求较高 | | 订单金额一致性 | 每日凌晨 | 财务敏感性数据 | --- ## 六、健康监测 > **后端服务**:`platform-monitor`(端口 24805)| **原型参考**:`web-admin/health-monitor/exception-dirty.html` > > **开发状态**:❌ 未实现独立的脏数据检测表,已有 `mon_alert_record`(穿戴告警)和 `mon_env_warn_info`(环境告警)。 健康监测是系统第二大模块,涵盖可穿戴设备数据采集、环境监测、健康调查问卷等。 ### 6.1 涉及数据库表 #### 设备与告警 | 表名 | 说明 | 脏数据风险 | |------|------|:--:| | `mon_device` | 可穿戴设备主表 | 高 — `device_code`(设备编码)、`bind_status`(绑定状态)、`bind_user_id`(绑定用户ID)、`online_status`(在线状态)、`last_data_time`(最后数据上报时间) | | `mon_device_config` | 设备监测配置 | 高 — `threshold_min`(阈值下限)、`threshold_max`(阈值上限)、`upload_frequency`(上报频率) | | `mon_bind_record` | 设备绑定/解绑记录 | 中 — `bind_date`(绑定日期)、`unbind_date`(解绑日期) | | `mon_alert_record` | 告警记录 | 中 — `alert_value`(告警值)、`threshold_range`(阈值范围)、GPS 坐标 | | `mon_notification` | 通知消息 | 低 — `send_time`(发送时间)、`notice_status`(通知状态) | #### 每日聚合统计(9张表) | 表名 | 关键字段 | 脏数据风险 | |------|----------|:--:| | `mon_daily_stats_summary` | `wear_flag`(佩戴标记)、`last_upload_time`(最后上报时间) | 中 | | `mon_daily_stats_heart_rate` | `hr_max`(最大心率)/`hr_min`(最小心率)/`hr_avg`(平均心率)/`hr_latest`(最新心率)、`silence_hr_*`(静息心率) | 高 | | `mon_daily_stats_spo2` | `spo2_max`(最大血氧)/`spo2_min`(最小血氧)/`spo2_avg`(平均血氧)/`spo2_latest`(最新血氧) | 高 | | `mon_daily_stats_stress` | `stress_max`(最大压力)/`stress_min`(最小压力)/`stress_avg`(平均压力)/`stress_latest`(最新压力) | 中 | | `mon_daily_stats_temperature` | `temp_max`(最高体温)/`temp_min`(最低体温)/`temp_avg`(平均体温)/`temp_latest`(最新体温)、`skin_temp_*`(皮肤温度) | 高 | | `mon_daily_stats_blood_pressure` | `systolic_max`(最高收缩压)/`systolic_min`(最低收缩压)、`diastolic_max`(最高舒张压)/`diastolic_min`(最低舒张压) | 高 | | `mon_daily_stats_sleep` | `total_min`(总睡眠时长分钟)、`deep_min`(深睡时长)、`score`(睡眠评分) | 中 | | `mon_daily_stats_exercise` | `steps`(步数)、`exercise_calorie`(运动消耗卡路里)、`steps_distance`(步行距离)、`exercise_distance`(运动距离) | 中 | | `mon_daily_stats_ecg` | `ecg_count`(心电测量次数)、`latest_value`(最新值) | 低 | #### 原始监测数据(12张表) | 表名 | 关键字段 | 脏数据风险 | |------|----------|:--:| | `mon_data_heart_rate` | `data_value`(心率值bpm)、`silence_value`(静息心率值) | 高 | | `mon_data_spo2` | `data_value`(血氧值%) | 高 | | `mon_data_stress` | `data_value`(压力值)、`start_time`(测量开始时间)、`end_time`(测量结束时间) | 中 | | `mon_data_temperature` | `data_value`(体温值℃)、`skin_value`(皮肤温度) | 高 | | `mon_data_sleep` | `fall_asleep_time`(入睡时间)、`wake_up_time`(醒来时间)、`sleep_score`(睡眠评分) | 中 | | `mon_data_sleep_stage` | `stage_type`(睡眠阶段类型)、`start_time`(开始时间)、`end_time`(结束时间)、`duration`(持续时间) | 中 | | `mon_data_ecg` | `avg_heart_rate`(平均心率)、`arrhy_type`(心律失常类型)、`data_points_url`(数据点文件URL) | 中 | | `mon_data_exercise` | `calorie`(消耗卡路里)、`distance`(运动距离)、`duration`(运动时长) | 中 | | `mon_data_exercise_trace` | `longitude`(经度)、`latitude`(纬度)、`altitude`(海拔) | 中 | | `mon_data_steps` | `step_count`(步数)、`calorie`(消耗卡路里)、`distance`(距离) | 中 | | `mon_data_blood_pressure` | `systolic_value`(收缩压)、`diastolic_value`(舒张压) | 高 | | `mon_data_gps` | `longitude`(经度)、`latitude`(纬度)、`address`(地址) | 中 | #### 环境监测(16张表) | 类别 | 数据表 | 日数据表 | 月数据表 | 使用记录表 | |------|--------|----------|----------|-----------| | 室内 | `mon_env_data_indoor` | `mon_env_day_data_indoor` | `mon_env_month_data_indoor` | `mon_env_use_record_indoor` | | 室外 | `mon_env_data_outdoor` | `mon_env_day_data_outdoor` | `mon_env_month_data_outdoor` | `mon_env_use_record_outdoor` | | 花粉 | `mon_env_data_pollen` | `mon_env_day_data_pollen` | `mon_env_month_data_pollen` | `mon_env_use_record_pollen` | | 水质 | `mon_env_data_water` | `mon_env_day_data_water` | `mon_env_month_data_water` | `mon_env_use_record_water` | 附加表:`mon_env_category_indoor/outdoor/pollen/water`(指标类别定义)、`mon_env_meter_info`(环境仪表元数据)、`mon_env_warn_info`(环境告警记录)、`mon_env_warn_sync_record`(告警同步记录) #### 调查问卷 | 表名 | 说明 | 脏数据风险 | |------|------|:--:| | `mon_survey` | 调查主表 | 低 | | `mon_survey_activity` | 调查活动 | 低 | | `mon_survey_answer_record` | 回答记录 | 中 | | `mon_survey_answer_detail` | 回答详情 | 中 | ### 6.2 系统脏数据检测规则 > 按原型业务模块分类:健康排查、穿戴监测、体重监测、环境监测 #### 健康排查(问卷) | 异常类型 | 检测规则 | 涉及表 | 涉及字段 | |----------|----------|--------|----------| | 数据缺失 | 积分字段异常(`mon_survey_answer_record` 无 score 字段,积分在别处计算) | `mon_survey_answer_record` + 积分相关表 | — | | 逻辑矛盾 | 问卷回答时间早于活动发布时间 | `mon_survey_answer_record` ↔ `mon_survey_activity` | 时间字段 | | 重复数据 | 同一用户同一问卷出现多条回答记录 | `mon_survey_answer_record` | `user_id`(用户ID) + `survey_id`(问卷ID) | #### 穿戴监测 | 异常类型 | 检测规则 | 涉及表 | 涉及字段 | |----------|----------|--------|----------| | 格式错误 | 设备绑定日期格式非法 | `mon_bind_record` | `bind_date`(绑定日期) | | 重复数据 | 同一设备同一时间段出现重复数据记录 | `mon_data_heart_rate` / `mon_data_spo2` / ... | `device_id`(设备ID) + `data_time`(数据时间) | | 范围越界 | 心率值超出人体可能范围(如 <20 或 >300 bpm) | `mon_data_heart_rate` | `data_value`(心率值bpm) | | 范围越界 | 血氧值超出合理范围(如 <50% 或 >100%) | `mon_data_spo2` | `data_value`(血氧值%) | | 范围越界 | 体温值超出人体可能范围(如 <30℃ 或 >45℃) | `mon_data_temperature` | `data_value`(体温值℃) | | 逻辑矛盾 | 静息心率高于活动心率 | `mon_daily_stats_heart_rate` | `silence_hr_avg`(静息心率均值) > `hr_avg`(心率均值) | | 逻辑矛盾 | 设备在线但超过 N 天无数据上报 | `mon_device` | `online_status`(在线状态) + `last_data_time`(最后上报时间) | | 范围越界 | GPS 坐标超出国内范围 | `mon_data_gps` | `longitude`(经度)、`latitude`(纬度) | | 格式错误 | 穿戴设备原始数据 `data_points_url` 指向的 URL 不可访问 | `mon_data_ecg` | `data_points_url`(数据点文件URL) | #### 体重监测 | 异常类型 | 检测规则 | 涉及表 | 涉及字段 | |----------|----------|--------|----------| | 逻辑矛盾 | 日统计中的最大心率 < 最小心率 | `mon_daily_stats_heart_rate` | `hr_max`(最大心率) < `hr_min`(最小心率) | | 逻辑矛盾 | 日统计中的收缩压 < 舒张压 | `mon_daily_stats_blood_pressure` | `systolic_*`(收缩压) < `diastolic_*`(舒张压) | | 逻辑矛盾 | 睡眠时长 > 24小时 | `mon_daily_stats_sleep` | `total_min`(总睡眠时长) > 1440 | #### 环境监测 | 异常类型 | 检测规则 | 涉及表 | 涉及字段 | |----------|----------|--------|----------| | 逻辑矛盾 | 室内温度高于室外温度超过10℃(且空调未在制热) | `mon_env_data_indoor` + `mon_env_data_outdoor` | 温度字段 | | 范围越界 | 环境温度超出设备量程 | 各环境数据表 | 温度字段 | | 范围越界 | PM2.5 值为负数 | `mon_env_data_indoor` / `mon_env_data_outdoor` | PM2.5 字段 | | 范围越界 | ph 值超出 0-14 范围 | `mon_env_data_water` | `ph`(酸碱度) | | 数据缺失 | 环境监测设备超过 N 天未上报数据 | 各环境数据表 | `read_time`(读取时间) | | 关联缺失 | 环境数据关联的仪表在 `mon_env_meter_info` 中不存在 | 各环境数据表 | `meter_code`(仪表编码) | ### 6.3 检测频率建议 | 检测类型 | 建议频率 | 说明 | |----------|----------|------| | 系统脏数据全面扫描 | 每日凌晨 3:00 | 穿戴/环境数据量大,错峰执行 | | 原始数据范围越界检查 | 数据入库时实时 | 在数据接收层做第一道校验 | | 聚合统计一致性检查 | 每日凌晨(聚合任务完成后) | 校验日统计 = 原始数据汇总 | | 设备在线但无数据告警 | 每小时 | `mon_device.online_status` + `last_data_time` | | GPS 坐标越界检查 | 每日凌晨 | 全量扫描 `mon_data_gps` |