|
|
@@ -0,0 +1,492 @@
|
|
|
+# 五维测评客观化系统 —— 开发计划(软件实现方案)
|
|
|
+
|
|
|
+> 版本: v1.0
|
|
|
+> 日期: 2026-10-25
|
|
|
+> 编写: 架构师 Bob(software-architect)
|
|
|
+> 上游依据: `docs/五维测评方法设计_客观化方案.md`、`docs/舌诊情绪识别_技术选型.md`、`docs/assessment-market-plan.md`、`AGENTS.md`
|
|
|
+> 目标: 把"五维分数从填出来的"变成"测出来的",并落地到 `EnergyService.getOverview()` 当前写死的 `healthIndex = 0`。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 一、实现方案
|
|
|
+
|
|
|
+### 1.1 核心技术难点
|
|
|
+
|
|
|
+| 难点 | 说明 | 应对策略 |
|
|
|
+|------|------|---------|
|
|
|
+| **客观计分 vs 自陈填分** | 现有五维多为人工录入/自评,信效度弱 | 引入三层数据模型(L1 行为痕迹 / L2 机器提取 / L3 自陈),单维度内 L1 0.50 / L2 0.30 / L3 0.20 归一化加权;自陈单维度权重上限 40% |
|
|
|
+| **能力与作答倾向混在一起** | 正确率 = 能力 + 倾向(保守/激进/讨好) | 凡有客观对错的游戏/判断任务统一用信号检测论 **d′** 计分,同时输出 **β** 作为作答倾向指标,\|logβ\| 超常模 2SD 降权或标记复核 |
|
|
|
+| **单一数据源不可信** | 任一指标单源即出分风险高 | 多源三角验证:同一指标 ≥2 个独立源且一致性达标(ICC≥0.60 或 \|r\|≥0.40)才计入,否则标"待补充"而非给 0 |
|
|
|
+| **缺失数据补 0 失真** | 缺数据源硬补 0 会系统性拉低 | 缺失数据源从分母剔除(权重重新归一化),同时下调置信度 |
|
|
|
+| **年龄/经验混淆** | 低龄被低估、高龄被高估,游戏经验干扰 | 年龄分段常模(`CognitiveNorm` 已存在,复用其模式扩展全维度);游戏经验、性别作协变量;结果以 T 分呈现 |
|
|
|
+| **healthIndex 写死** | `EnergyService.getOverview()` L1818 `healthIndex = 0` | 新增"维度分+五维健康指数"计算服务,读时/事件触发计算并落快照,`getOverview` 改为读取快照(见 3.4 / 4 / 7) |
|
|
|
+| **合规红线(医疗/心理诊断、未成年人敏感信息、AI 复核)** | 见第十节 | 全部文案定位"健康/成长参考";未成年人人脸/声纹需监护人单独明示同意、默认不存原始照片;AI 结果 5% 抽样 + 异常全检;绘画仅形式要素评分 |
|
|
|
+
|
|
|
+### 1.2 框架 / 库选型(严格沿用现有栈,不擅自换栈)
|
|
|
+
|
|
|
+| 层 | 现有技术栈 | 本方案沿用/新增 | 理由 |
|
|
|
+|----|-----------|----------------|------|
|
|
|
+| 后端 | Spring Boot 2.7.18 + MyBatis-Plus + Java 8,端口 9082 | **不换栈**;新增纯 Java 实现的 `ScoringAlgorithm`(d′/β/T 分/ICC/权重重归一化) | 不引入统计库依赖风险;d′/β/T 分/ICC(2,1) 公式均为可手写的小函数;如需 percentile 可轻量自实现 |
|
|
|
+| 接口规范 | 统一 `@PostMapping` + `Result<T>` + JWT Bearer + `@Resource` 注入 | **全部沿用** | 与现有 controller/service 风格一致,降低联调成本 |
|
|
|
+| 前端 | uni-app 微信小程序 Vue2 Options API | **不换栈**;新增 `components/assessment/*` 复用型组件;游戏用 Canvas 自研,不引重型库 | 小程序禁用可选链/Grid/`:key` 表达式/`new Date(string)`,组件需保守写法 |
|
|
|
+| AI 服务 | cfc-langgraph(Python FastAPI,端口 9000,LangGraph) | **不换栈**;复用已有 `tongue` 端点;新增 `emotion` 端点(DeepFace)+ 舌象质量门禁节点 | 选型文档已论证:舌诊 MVP 用 TongueDiagnosis.AI、情绪用 DeepFace 服务端,直接封装为 LangGraph 节点 |
|
|
|
+| 常模数据 | `CognitiveNorm`(cognitive_norms 表,已存在) | **复用模式并扩展**为 `assessment_metric_norms` 全维度通用常模表 | 已有 age/gender 分段 + 百分位结构,避免重复造轮子 |
|
|
|
+
|
|
|
+> 不引入任何新主框架;统计与图表均用现有或手写实现,保证 Java 8 / Vue2 兼容性。
|
|
|
+
|
|
|
+### 1.3 架构模式
|
|
|
+
|
|
|
+- **分层架构(沿用)**:controller(接口)→ service(业务/计分)→ mapper(MyBatis-Plus)→ entity,与现有 `EnergyService`/`DanAssessmentController` 一致。
|
|
|
+- **无状态计分引擎**:`ScoringAlgorithm` 为纯函数工具类(d′/β/T 分/权重重归一化/ICC/三角验证),不持有状态,便于单测。
|
|
|
+- **"采集—快照"分离(compute-on-read + 快照缓存)**:原始测量点(`DimensionMeasure`)实时落库;维度分与五维健康指数在"提交后"或"读 `getOverview` 时"按需计算,并落 `DimensionScore` / `HealthIndexSnapshot` 快照,避免每次读全量重算;快照带 `computedAt` 与置信度,报告随附展示。
|
|
|
+- **适配器模式对接 AI**:后端经 `AiGateway` 调 cfc-langgraph,返回结构化结果(仅结构化,不存原始人脸/舌象照片),由 `DimensionMeasureService` 落库。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 二、文件清单(相对路径)
|
|
|
+
|
|
|
+> 根目录约定:`cfc-backend/`、`cfc-frontend/`、`cfc-langgraph/`。Java 包根:`com/etotem/cfc/`。
|
|
|
+
|
|
|
+### 2.1 后端 cfc-backend(新增/修改)
|
|
|
+
|
|
|
+| 类型 | 路径 | 说明 |
|
|
|
+|------|------|------|
|
|
|
+| entity | `src/main/java/com/etotem/cfc/entity/AssessmentMetric.java` | 指标目录(code/dimension/layer/weight/direction/normStrategy/status) |
|
|
|
+| entity | `src/main/java/com/etotem/cfc/entity/AssessmentMetricNorm.java` | 全维度常模表(复用 CognitiveNorm 模式) |
|
|
|
+| entity | `src/main/java/com/etotem/cfc/entity/DimensionMeasure.java` | 原子测量记录(L1/L2/L3 原始数据点) |
|
|
|
+| entity | `src/main/java/com/etotem/cfc/entity/DimensionScore.java` | 维度分快照(score/confidence/sampleSize/dataSources/layerBreakdown) |
|
|
|
+| entity | `src/main/java/com/etotem/cfc/entity/HealthIndexSnapshot.java` | 五维健康指数快照(totalHealthIndex + 五维 JSON + confidence) |
|
|
|
+| entity | `src/main/java/com/etotem/cfc/entity/AssessmentReviewLog.java` | AI 结果人工复核抽样留痕(合规红线 3) |
|
|
|
+| mapper | `src/main/java/com/etotem/cfc/mapper/{AssessmentMetric,AssessmentMetricNorm,DimensionMeasure,DimensionScore,HealthIndexSnapshot,AssessmentReviewLog}Mapper.java` | MyBatis-Plus Mapper |
|
|
|
+| service | `src/main/java/com/etotem/cfc/service/ScoringAlgorithm.java` | **核心计分算法**(d′/β/T 分/权重重归一化/ICC/三角验证/置信度) |
|
|
|
+| service | `src/main/java/com/etotem/cfc/service/NormService.java` | 常模查询(按 metricCode+age+gender) |
|
|
|
+| service | `src/main/java/com/etotem/cfc/service/DimensionMeasureService.java` | 测量点提交/查询/校验(质量门禁、时间戳防补填) |
|
|
|
+| service | `src/main/java/com/etotem/cfc/service/DimensionScoreService.java` | 维度分计算与落库 |
|
|
|
+| service | `src/main/java/com/etotem/cfc/service/HealthIndexService.java` | 五维健康指数计算与快照 |
|
|
|
+| service | `src/main/java/com/etotem/cfc/service/BehaviorTraceCollector.java` | **行维度**:从现有任务/打卡/互动日志汇聚 L1 测量点 |
|
|
|
+| service | `src/main/java/com/etotem/cfc/service/CatIrtService.java` | **心维度 L3**:CAT/IRT 计分 + M 题/重复题校验 |
|
|
|
+| controller | `src/main/java/com/etotem/cfc/controller/DimensionAssessmentController.java` | 测评采集/查询/重算接口(@PostMapping + Result<T>) |
|
|
|
+| controller | `src/main/java/com/etotem/cfc/controller/AssessmentReviewController.java` | 人工复核抽样接口 |
|
|
|
+| dto | `src/main/java/com/etotem/cfc/dto/MeasureSubmitRequest.java` | 批量提交请求(childId + MeasureItem[]) |
|
|
|
+| dto | `src/main/java/com/etotem/cfc/dto/MeasureItem.java` | 单条测量(metricCode/rawValue/device/quality/modelVersion/sourceType/timestamp) |
|
|
|
+| dto | `src/main/java/com/etotem/cfc/dto/DimensionScoreVO.java` | 维度分 VO(含 confidence/dataSources/sampleSize/layerBreakdown) |
|
|
|
+| dto | `src/main/java/com/etotem/cfc/dto/HealthIndexVO.java` | 五维健康指数 VO |
|
|
|
+| dto(改) | `src/main/java/com/etotem/cfc/dto/HealthDimensionVO.java` | 扩展 `DimensionItem`:新增 `confidence`、`dataSources`、`sampleSize`、`layerBreakdown`;VO 顶层新增 `confidence` |
|
|
|
+| service(改) | `src/main/java/com/etotem/cfc/service/EnergyService.java` | `getOverview()` L1818/L1825 由写死 0 改为读取 `HealthIndexService` 快照 |
|
|
|
+| db(改) | `src/main/resources/schema.sql`(或现有迁移机制) | 上述 6 张新表 + `HealthDimensionVO` 无需改表(仅 VO) |
|
|
|
+
|
|
|
+### 2.2 前端 cfc-frontend(新增/修改)
|
|
|
+
|
|
|
+| 类型 | 路径 | 说明 |
|
|
|
+|------|------|------|
|
|
|
+| 组件 | `components/assessment/dimension-score-card.vue` | 维度分卡片(分数+置信度+数据源) |
|
|
|
+| 组件 | `components/assessment/metric-item.vue` | 单指标 T 分/来源展示 |
|
|
|
+| 组件 | `components/assessment/confidence-badge.vue` | 置信度徽标;低置信度文案"样本不足,仅供参考" |
|
|
|
+| 组件 | `components/assessment/game-wrapper.vue` | 可复用游戏外壳(记录反应时、采集 d′ 所需 hits/false-alarms、禁用可选链) |
|
|
|
+| 组件 | `components/assessment/tongue-capture.vue` | 舌象拍摄→调 langgraph→显示质量评分 |
|
|
|
+| 组件 | `components/assessment/emotion-capture.vue` | 人脸/短视频拍摄→调 langgraph→多帧中位数情绪 |
|
|
|
+| 页面(改) | `pages/body-detail/index.vue`、`health-dimensions.vue`、`health-report.vue`、`checkin.vue`、`dimension-detail.vue` | 身维度指标展示 + 体能/饮食入口 + 舌诊入口 |
|
|
|
+| 页面(改) | `pages/mind-detail/index.vue`、`emotion-checkin.vue`、`screening.vue`、`traditional-mirror.vue` | 心维度:情绪识别入口 + CAT 量表 + 置信度 |
|
|
|
+| 页面(改) | `pages/wisdom-detail/index.vue` | 智维度:聚合认知游戏入口 |
|
|
|
+| 页面(改) | `pages/cognitive-test/{memory-test,logic-test,perception-test,spatial-test,speed-test,language-test}.vue` | 改造为提交 d′/RT/ICV 测量点 |
|
|
|
+| 页面(改) | `pages/games/{schulte,sudoku,1a2b}.vue`(及新增 `corsi.vue`、`nback.vue`、`stroop.vue`、`tower.vue`、`ravens.vue`) | 改造/新增为提交测量点 |
|
|
|
+| 页面(改) | `pages/action-detail/index.vue` | 行维度:行为痕迹(完成率/打卡时间戳/streak/互动频次)展示 |
|
|
|
+| 页面(改) | `pages/wealth-detail/member-wealth-detail.vue`、`pages/wealth-cf/*` | 富维度:财商情境+资源分配+真实 CF 流水 |
|
|
|
+| 页面(改) | `pages/energy/*`(五维概览页) | 读取 `getOverview` 新 healthIndex + 置信度 |
|
|
|
+
|
|
|
+### 2.3 AI 服务 cfc-langgraph(新增/修改)
|
|
|
+
|
|
|
+| 类型 | 路径 | 说明 |
|
|
|
+|------|------|------|
|
|
|
+| agent(改) | `app/agents/tongue_agent.py` | 增加**图像质量门禁**节点(光照/白平衡校正 + 质量评分),质量不达标拒测 |
|
|
|
+| node(新) | `app/nodes/tongue_quality_node.py` | 色卡/白平衡校正 + 质量评分(0-100) |
|
|
|
+| agent(新) | `app/agents/emotion_agent.py` | DeepFace 封装;短视频按 200ms 抽帧、去首 0.5s、取情绪概率中位数 + 变异度 |
|
|
|
+| graph(新) | `app/graphs/emotion_graph.py` | EmotionGraph:preprocess → classify → aggregate(median) |
|
|
|
+| api(新) | `app/api/emotion.py` | `POST /api/v1/emotion/analyze`(返回主导情绪 + 各情绪概率 + 帧数 + 变异度) |
|
|
|
+| model(新) | `app/models/emotion.py` | 请求/响应 Pydantic 模型 |
|
|
|
+| api(改) | `app/api/tongue.py` | `/tongue/diagnose` 返回中追加 `qualityScore` 字段 |
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 三、数据结构与接口
|
|
|
+
|
|
|
+### 3.1 类图(Mermaid classDiagram)
|
|
|
+
|
|
|
+```mermaid
|
|
|
+classDiagram
|
|
|
+ %% ===== 现有(复用/改造)=====
|
|
|
+ class EnergyDimension {
|
|
|
+ +Long id
|
|
|
+ +String code
|
|
|
+ +String name
|
|
|
+ +String icon
|
|
|
+ +String element
|
|
|
+ +Integer status
|
|
|
+ }
|
|
|
+ class EnergyService {
|
|
|
+ +Map~String,Object~ getOverview(Long memberId)
|
|
|
+ }
|
|
|
+ class HealthDimensionVO {
|
|
|
+ +Long memberId
|
|
|
+ +BigDecimal healthIndex
|
|
|
+ +BigDecimal confidence
|
|
|
+ +List~DimensionItem~ dimensions
|
|
|
+ +Date updateTime
|
|
|
+ +Boolean isAverage
|
|
|
+ }
|
|
|
+ class DimensionItem {
|
|
|
+ +String dimension
|
|
|
+ +String label
|
|
|
+ +BigDecimal score
|
|
|
+ +Integer percentile
|
|
|
+ +String dataSource
|
|
|
+ +Integer tier
|
|
|
+ +String level
|
|
|
+ +BigDecimal confidence
|
|
|
+ +String dataSources
|
|
|
+ +Integer sampleSize
|
|
|
+ +String layerBreakdown
|
|
|
+ }
|
|
|
+
|
|
|
+ %% ===== 新增实体 =====
|
|
|
+ class AssessmentMetric {
|
|
|
+ +Long id
|
|
|
+ +String metricCode
|
|
|
+ +String dimension
|
|
|
+ +String layer
|
|
|
+ +BigDecimal weight
|
|
|
+ +String direction
|
|
|
+ +String normStrategy
|
|
|
+ +BigDecimal requiredSample
|
|
|
+ +String status
|
|
|
+ }
|
|
|
+ class AssessmentMetricNorm {
|
|
|
+ +Long id
|
|
|
+ +String metricCode
|
|
|
+ +String gender
|
|
|
+ +Integer ageMinMonths
|
|
|
+ +Integer ageMaxMonths
|
|
|
+ +BigDecimal mean
|
|
|
+ +BigDecimal sd
|
|
|
+ +Integer p05
|
|
|
+ +Integer p50
|
|
|
+ +Integer p95
|
|
|
+ }
|
|
|
+ class DimensionMeasure {
|
|
|
+ +Long id
|
|
|
+ +Long childId
|
|
|
+ +String metricCode
|
|
|
+ +String dimension
|
|
|
+ +String layer
|
|
|
+ +BigDecimal rawValue
|
|
|
+ +String sourceType
|
|
|
+ +String device
|
|
|
+ +BigDecimal qualityScore
|
|
|
+ +String modelVersion
|
|
|
+ +Date measureTime
|
|
|
+ +Integer validFlag
|
|
|
+ }
|
|
|
+ class DimensionScore {
|
|
|
+ +Long id
|
|
|
+ +Long childId
|
|
|
+ +String dimension
|
|
|
+ +BigDecimal score
|
|
|
+ +BigDecimal confidence
|
|
|
+ +Integer sampleSize
|
|
|
+ +String dataSources
|
|
|
+ +String layerBreakdown
|
|
|
+ +Date computedAt
|
|
|
+ }
|
|
|
+ class HealthIndexSnapshot {
|
|
|
+ +Long id
|
|
|
+ +Long childId
|
|
|
+ +BigDecimal totalHealthIndex
|
|
|
+ +String dimensionJson
|
|
|
+ +BigDecimal confidence
|
|
|
+ +Date computedAt
|
|
|
+ }
|
|
|
+ class AssessmentReviewLog {
|
|
|
+ +Long id
|
|
|
+ +Long measureId
|
|
|
+ +String reviewType
|
|
|
+ +String result
|
|
|
+ +Long reviewerId
|
|
|
+ +Date reviewedAt
|
|
|
+ }
|
|
|
+
|
|
|
+ %% ===== 服务 / DTO =====
|
|
|
+ class ScoringAlgorithm {
|
|
|
+ +double dPrime(hits, fa, n)~
|
|
|
+ +double beta(hr, far)~
|
|
|
+ +double tScore(x, mean, sd, direction)~
|
|
|
+ +double aggregateDimension(items, norms)~
|
|
|
+ +double icc(sources)~
|
|
|
+ +double confidence(completeness, consistency)~
|
|
|
+ +Map renormalizeWeights(missing)~
|
|
|
+ }
|
|
|
+ class NormService {
|
|
|
+ +AssessmentMetricNorm getNorm(metricCode, gender, ageMonths)
|
|
|
+ }
|
|
|
+ class DimensionMeasureService {
|
|
|
+ +Result submit(MeasureSubmitRequest)
|
|
|
+ +List~DimensionMeasure~ list(childId, dimension)
|
|
|
+ }
|
|
|
+ class DimensionScoreService {
|
|
|
+ +DimensionScore compute(childId, dimension)
|
|
|
+ +DimensionScoreVO getLatest(childId, dimension)
|
|
|
+ }
|
|
|
+ class HealthIndexService {
|
|
|
+ +HealthIndexSnapshot compute(childId)
|
|
|
+ +HealthIndexVO getLatest(childId)
|
|
|
+ }
|
|
|
+ class DimensionAssessmentController {
|
|
|
+ +Result submitMeasures()
|
|
|
+ +Result getDimensionScore()
|
|
|
+ +Result getHealthIndex()
|
|
|
+ +Result recompute()
|
|
|
+ }
|
|
|
+
|
|
|
+ %% ===== 关系 =====
|
|
|
+ AssessmentMetric "1" --> "0..*" AssessmentMetricNorm : 定义常模
|
|
|
+ DimensionMeasure --> AssessmentMetric : 归属指标(metricCode)
|
|
|
+ DimensionMeasureService ..> DimensionMeasure : CRUD
|
|
|
+ DimensionScoreService ..> DimensionMeasure : 聚合
|
|
|
+ DimensionScoreService ..> NormService : 取常模
|
|
|
+ DimensionScoreService ..> ScoringAlgorithm : 计分
|
|
|
+ HealthIndexService ..> DimensionScoreService : 取五维分
|
|
|
+ HealthIndexService ..> ScoringAlgorithm : 聚合
|
|
|
+ DimensionAssessmentController ..> DimensionMeasureService
|
|
|
+ DimensionAssessmentController ..> DimensionScoreService
|
|
|
+ DimensionAssessmentController ..> HealthIndexService
|
|
|
+ EnergyService ..> HealthIndexService : 读取快照(替换healthIndex=0)
|
|
|
+ HealthDimensionVO *-- DimensionItem
|
|
|
+ EnergyService ..> HealthDimensionVO : 组装
|
|
|
+```
|
|
|
+
|
|
|
+### 3.2 关键 API 定义(沿用 `@PostMapping` + `Result<T>` + JWT)
|
|
|
+
|
|
|
+> 统一前缀建议 `/api/assessment/*`;响应统一 `Result<T>`;鉴权统一 JWT Bearer;依赖注入统一 `@Resource`。
|
|
|
+
|
|
|
+| 端点 | 请求体(摘要) | 响应 `Result<T>` | 说明 |
|
|
|
+|------|--------------|-----------------|------|
|
|
|
+| `POST /api/assessment/measure/submit` | `MeasureSubmitRequest{ childId, items: MeasureItem[]{ metricCode, rawValue, sourceType, device, qualityScore, modelVersion, measureTime } }` | `Result<Void>` | 批量提交 L1/L2/L3 测量点;服务端校验时间戳(防补填)、质量门禁(舌/脸 qualityScore 不达标拒收) |
|
|
|
+| `POST /api/assessment/measure/list` | `{ childId, dimension }` | `Result<List<DimensionMeasure>>` | 查询某维度全部测量点(含来源/质量/模型版本,留痕) |
|
|
|
+| `POST /api/assessment/dimension-score/get` | `{ childId, dimension }` | `Result<DimensionScoreVO>` | 取最新维度分(score/confidence/sampleSize/dataSources/layerBreakdown);无数据返回"待补充" |
|
|
|
+| `POST /api/assessment/health-index/get` | `{ childId }` | `Result<HealthIndexVO>` | 取五维健康指数 + 各维分 + 总置信度 |
|
|
|
+| `POST /api/assessment/recompute` | `{ childId }` (规划师/系统) | `Result<HealthIndexVO>` | 触发重算并刷新快照 |
|
|
|
+| `POST /api/assessment/review/sample` | `{ childId, dimension }` | `Result<AssessmentReviewLog>` | AI 结果人工复核抽样(合规红线 3) |
|
|
|
+| `POST /api/v1/emotion/analyze` (langgraph) | `multipart: 人脸/短视频` | `{ code, data:{ dominant, probabilities, frameCount, variance } }` | DeepFace 多帧中位数情绪(去首 0.5s) |
|
|
|
+| `POST /api/v1/tongue/diagnose` (langgraph, 已存在) | `multipart: 舌象` | 增加 `qualityScore` 字段 | 舌色/苔色/苔厚/苔腻 4 维概率 + 质量评分 |
|
|
|
+
|
|
|
+> 小程序侧所有调用走统一 request 封装(JWT 注入),游戏/量表/AI 结果最终都收敛到 `measure/submit`。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 四、程序调用流程(Mermaid sequenceDiagram)
|
|
|
+
|
|
|
+> 关键链路:**一次测评从采集 → 计分 → 维度分 → 五维健康指数** 的完整闭环(以"智维度认知游戏 + 心维度情绪识别"为例)。
|
|
|
+
|
|
|
+```mermaid
|
|
|
+sequenceDiagram
|
|
|
+ participant Mini as 小程序(五维详情页)
|
|
|
+ participant Ctrl as DimensionAssessmentController
|
|
|
+ participant MS as DimensionMeasureService
|
|
|
+ participant LG as cfc-langgraph(AI)
|
|
|
+ participant DSS as DimensionScoreService
|
|
|
+ participant NS as NormService
|
|
|
+ participant SA as ScoringAlgorithm
|
|
|
+ participant HIS as HealthIndexService
|
|
|
+ participant ES as EnergyService
|
|
|
+ participant VO as HealthDimensionVO
|
|
|
+
|
|
|
+ Note over Mini,LG: ① 采集(L1 行为 / L2 机器提取)
|
|
|
+ Mini->>Mini: 玩游戏/拍舌/拍脸(game-wrapper 记录反应时、hits/false-alarms)
|
|
|
+ Mini->>LG: 上传舌象/人脸(POST /api/v1/tongue|emotion)
|
|
|
+ LG-->>Mini: 结构化结果(概率/质量评分/帧数)
|
|
|
+ Mini->>Ctrl: POST /api/assessment/measure/submit (含 rawValue/quality/modelVersion/measureTime)
|
|
|
+ Ctrl->>MS: submit(request)
|
|
|
+ MS->>MS: 校验时间戳(防补填)+质量门禁(不达标拒收)
|
|
|
+ MS-->>Ctrl: Result<Void> (落 DimensionMeasure)
|
|
|
+
|
|
|
+ Note over Ctrl,HIS: ② 计分 → 维度分
|
|
|
+ Mini->>Ctrl: POST /api/assessment/dimension-score/get {childId, dimension}
|
|
|
+ Ctrl->>DSS: compute(childId, dimension)
|
|
|
+ DSS->>MS: list(measures of dimension)
|
|
|
+ loop 每个指标 metric
|
|
|
+ DSS->>NS: getNorm(metricCode, gender, ageMonths)
|
|
|
+ NS-->>DSS: AssessmentMetricNorm(mean, sd)
|
|
|
+ DSS->>SA: tScore(raw, mean, sd, direction) %% 负向(反应时/错误)取100-T
|
|
|
+ DSS->>SA: dPrime(hits, fa) / beta(hr, far) %% 游戏类用 d′,β 异常降权
|
|
|
+ end
|
|
|
+ DSS->>SA: aggregateDimension(items) %% Σ(w·c·T)/Σ(w·c),缺失源重归一化
|
|
|
+ SA->>SA: icc(sources) → 一致性系数(1/0.8/0.6)
|
|
|
+ SA->>SA: confidence(完整度均值 × 一致性)
|
|
|
+ DSS->>DSS: 落 DimensionScore 快照(含 confidence/sampleSize/dataSources)
|
|
|
+ DSS-->>Ctrl: DimensionScoreVO
|
|
|
+ Ctrl-->>Mini: Result<DimensionScoreVO>
|
|
|
+
|
|
|
+ Note over Mini,VO: ③ 维度分 → 五维健康指数 → getOverview
|
|
|
+ Mini->>Ctrl: POST /api/assessment/health-index/get {childId}
|
|
|
+ Ctrl->>HIS: compute(childId)
|
|
|
+ HIS->>DSS: 取五维 DimensionScore
|
|
|
+ HIS->>SA: 总健康指数 = Σ(维度分×权重)/Σ(权重) %% 默认等权,配置表可调
|
|
|
+ HIS->>HIS: 落 HealthIndexSnapshot
|
|
|
+ HIS-->>Ctrl: HealthIndexVO
|
|
|
+ Ctrl-->>Mini: Result<HealthIndexVO>
|
|
|
+
|
|
|
+ Note over Mini,VO: ④ 五维概览页(对接现有 getOverview)
|
|
|
+ Mini->>ES: getOverview(memberId)
|
|
|
+ ES->>HIS: getLatest(childId) %% 替换原 healthIndex=0
|
|
|
+ HIS-->>ES: 各维 score + confidence
|
|
|
+ ES->>VO: 组装 HealthDimensionVO(DimensionItem.healthIndex/confidence/dataSources)
|
|
|
+ ES-->>Mini: 五维概览(分数+置信度随报告展示)
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 五、任务分解(按 P0 / P1 / P2 阶段 + 模块)
|
|
|
+
|
|
|
+> 说明:本项目为多阶段、多模块(后端 + 前端 + AI 服务)工程,按"阶段 + 模块"合理拆分,目标清晰可执行;优先级与工期为估算,可随人力并行调整。所有任务严守第十节合规红线。
|
|
|
+
|
|
|
+### 5.1 P0(2–4 周,用现有资产,性价比最高)
|
|
|
+
|
|
|
+| Task ID | 名称 | 涉及文件(代表) | 依赖 | 优先级 | 预估工期 |
|
|
|
+|---------|------|----------------|------|--------|---------|
|
|
|
+| **T01** | 评分算法引擎与常模目录(公共库) | `ScoringAlgorithm.java`、`AssessmentMetric.java(+Mapper)`、`AssessmentMetricNorm.java(+Mapper)`、`NormService.java`、schema 迁移 | — | P0 | 1.5 周 |
|
|
|
+| **T02** | 客观测评数据接入层(measure 提交/查询) | `DimensionMeasure.java(+Mapper)`、`DimensionMeasureService.java`、`DimensionAssessmentController.java`、`MeasureSubmitRequest.java`、`MeasureItem.java`、schema | T01 | P0 | 1 周 |
|
|
|
+| **T03** | 维度分与五维健康指数计算 + 对接 `EnergyService.getOverview` + 扩展 `HealthDimensionVO` | `DimensionScore.java(+Mapper)`、`HealthIndexSnapshot.java(+Mapper)`、`DimensionScoreService.java`、`HealthIndexService.java`、`EnergyService.java`(改 L1818/L1825)、`HealthDimensionVO.java`(改)、`DimensionScoreVO.java`、`HealthIndexVO.java` | T01, T02 | P0 | 1 周 |
|
|
|
+| **T04** | 行为痕迹层(行维度 L1) | `BehaviorTraceCollector.java`、`pages/action-detail/index.vue`(改)、`components/assessment/metric-item.vue` | T02 | P0 | 0.5 周 |
|
|
|
+| **T05** | 舌诊 AI 接入(身维度 L2) | `app/agents/tongue_agent.py`(改质量门禁)、`app/nodes/tongue_quality_node.py`、`app/api/tongue.py`(改)、`components/assessment/tongue-capture.vue`、`pages/body-detail/*`(改) | T02 | P0 | 1 周 |
|
|
|
+| **T06** | 情绪识别 AI 接入(心维度 L2) | `app/agents/emotion_agent.py`、`app/graphs/emotion_graph.py`、`app/api/emotion.py`、`app/models/emotion.py`、`components/assessment/emotion-capture.vue`、`pages/mind-detail/emotion-checkin.vue`(改) | T02 | P0 | 1 周 |
|
|
|
+| **T07** | CAT/IRT 化量表(心维度 L3) | `CatIrtService.java`、`pages/mind-detail/screening.vue`(改)、`pages/mind-detail/traditional-mirror.vue`(改)、`components/assessment/dimension-score-card.vue` | T02 | P0 | 1 周 |
|
|
|
+| **T08** | 认知游戏 d′ 计量(智维度 L1) | `components/assessment/game-wrapper.vue`、`pages/cognitive-test/*`(改)、`pages/games/schulte.vue`、`pages/games/sudoku.vue`、`pages/games/1a2b.vue`、`pages/wisdom-detail/index.vue`(改) | T01, T02 | P0 | 1.5 周 |
|
|
|
+
|
|
|
+### 5.2 P1(1–2 月)
|
|
|
+
|
|
|
+| Task ID | 名称 | 涉及文件(代表) | 依赖 | 优先级 | 预估工期 |
|
|
|
+|---------|------|----------------|------|--------|---------|
|
|
|
+| **T09** | 智维度补全(瑞文矩阵自适应 + Stroop + 伦敦塔) | `pages/games/ravens.vue`、`stroop.vue`、`tower.vue`、`corsi.vue`、`nback.vue`、`ScoringAlgorithm`(新增 Stroop 干扰量/转换代价/ICV) | T08 | P1 | 2 周 |
|
|
|
+| **T10** | 富维度(财商情境任务 + 资源分配游戏 + 真实 CF 流水) | `pages/wealth-cf/*`(改)、`pages/wealth-detail/member-wealth-detail.vue`(改)、`DimensionMeasureService`(CF 读取适配) | T02 | P1 | 2 周 |
|
|
|
+| **T11** | 身维度补全(体能小测试 + 饮食拍照识别) | `pages/body-detail/checkin.vue`(改)、`pages/body-detail/dimension-detail.vue`(改)、langgraph `meal` 端点复用、`DimensionMeasure`(体能/膳食) | T02, T05 | P1 | 2 周 |
|
|
|
+| **T12** | 年龄分段常模建立与校准 | `AssessmentMetricNorm` 数据填充脚本、`NormService`(校准)、`CognitiveNorm`(复用) | T02(累积数据) | P1 | 持续(≥200 人/年龄组) |
|
|
|
+| **T13** | AI 人工复核抽样系统(合规红线 3) | `AssessmentReviewLog.java(+Mapper)`、`AssessmentReviewController.java`、`app`(复核回调) | T02, T03 | P1 | 1 周 |
|
|
|
+
|
|
|
+### 5.3 P2(3 月+)
|
|
|
+
|
|
|
+| Task ID | 名称 | 涉及文件(代表) | 依赖 | 优先级 | 预估工期 |
|
|
|
+|---------|------|----------------|------|--------|---------|
|
|
|
+| **T14** | 心维度深度:绘画 FEATS + 笔迹过程 | `pages/mind-detail/screening.vue`(扩展)、`ScoringAlgorithm`(Rasch/IRT 校准)、绘画采集组件 | T07 | P2 | 3 周 |
|
|
|
+| **T15** | 心维度深度:听故事说选择(DIT 式) | 故事选择/排序任务页、`CatIrtService`(三择一+排序一致性+M 题) | T07 | P2 | 2 周 |
|
|
|
+| **T16** | EMA + 被动感知(可选,额外授权) | 情绪日记/被动感知采集、`DimensionMeasure`(EMA) | T02 | P2 | 2 周 |
|
|
|
+| **T17** | 全维度 CAT 自适应 + 三角验证自动化 | `DimensionScoreService`(自动三角验证/ICC)、`CatIrtService`(全维度 CAT) | T03, T12 | P2 | 3 周 |
|
|
|
+
|
|
|
+> 说明:P0 阶段**不做绘画与故事**(T14/T15)——二者需标定样本与人工复核流程,成本高于收益,留待 P2。T13(AI 复核)虽列 P1,但须在任意 AI 自动出报告上线前就位(合规红线 3 为硬约束)。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 六、共享约定(沿用项目约定)
|
|
|
+
|
|
|
+1. **接口规范**:全部 `@PostMapping`,响应统一 `Result<T>`;鉴权统一 JWT Bearer;后端依赖注入统一 `@Resource`(不用 `@Autowired`)。
|
|
|
+2. **五维详情页入口**:`body/mind/wisdom/action/wealth-detail`;各维度测评入口与指标展示清单挂在这五个页面。
|
|
|
+3. **healthIndex 对接**:`EnergyService.getOverview()` 中写死的 `healthIndex = 0` / `totalHealthIndex = 0` 必须替换为 `HealthIndexService` 快照读取;无数据时维度分返回"待补充"且 `confidence` 置低,不得硬给 0。
|
|
|
+4. **年龄分段常模**:所有 T 分必须按 `AssessmentMetricNorm`(ageMonths + gender 分段)计算;未满样本阈值时降权并下调置信度。
|
|
|
+5. **图像质量门禁**:舌象/人脸类 L2 数据,**服务端强制色卡/白平衡校正**并返回 `qualityScore`;质量不达标**拒测**(不给出低质量结论);默认**不存储原始照片**,仅存结构化结果(合规红线 2)。
|
|
|
+6. **置信度随报告展示**:所有维度分/健康指数必须展示 `confidence`;低置信度文案统一为"样本不足,仅供参考",不得给出确定性结论。
|
|
|
+7. **缺失数据源处理**:不补 0,从分母剔除并重新归一化权重,同时下调置信度(一致性系数:≥2 源且 ICC≥0.60=1.0 / ≥2 源 0.40–0.60=0.8 / 仅 1 源=0.6)。
|
|
|
+8. **表单/游戏防作弊**:行为痕迹记录**真实操作时间戳**,禁止允许补录过去日期的打卡;补录数据单独标记,不计入坚持类指标。
|
|
|
+9. **小程序编码约束**:禁用可选链(`?.`)、禁用 CSS Grid、`:key` 不得用表达式、禁用 `new Date(string)`;游戏与组件统一用 `components/assessment/game-wrapper.vue` 采集反应时/作答序列。
|
|
|
+10. **数据留痕(合规红线 5)**:每次测评记录施测时间、作答时长、设备、图像质量、模型版本,保证可复现可追溯;AI 结果 `AssessmentReviewLog` 抽样复核(5% 抽样 + 异常全检)。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 七、任务依赖图(Mermaid graph)
|
|
|
+
|
|
|
+```mermaid
|
|
|
+graph TD
|
|
|
+ T01[T01 评分算法引擎与常模目录]
|
|
|
+ T02[T02 测评数据接入层]
|
|
|
+ T03[T03 维度分&五维健康指数+EnergyService对接]
|
|
|
+ T04[T04 行为痕迹层-行]
|
|
|
+ T05[T05 舌诊AI接入-身L2]
|
|
|
+ T06[T06 情绪识别AI接入-心L2]
|
|
|
+ T07[T07 CAT/IRT量表-心L3]
|
|
|
+ T08[T08 认知游戏d′计量-智L1]
|
|
|
+ T09[T09 智维度补全-瑞文/Stroop/伦敦塔]
|
|
|
+ T10[T10 富维度-财商/资源/CF]
|
|
|
+ T11[T11 身维度补全-体能/饮食]
|
|
|
+ T12[T12 年龄分段常模建立]
|
|
|
+ T13[T13 AI人工复核抽样系统]
|
|
|
+ T14[T14 绘画FEATS+笔迹]
|
|
|
+ T15[T15 听故事说选择DIT]
|
|
|
+ T16[T16 EMA+被动感知]
|
|
|
+ T17[T17 全维度CAT+三角验证自动化]
|
|
|
+
|
|
|
+ T01 --> T02
|
|
|
+ T01 --> T03
|
|
|
+ T01 --> T08
|
|
|
+ T02 --> T03
|
|
|
+ T02 --> T04
|
|
|
+ T02 --> T05
|
|
|
+ T02 --> T06
|
|
|
+ T02 --> T07
|
|
|
+ T02 --> T08
|
|
|
+ T02 --> T10
|
|
|
+ T02 --> T11
|
|
|
+ T02 --> T13
|
|
|
+ T02 --> T16
|
|
|
+ T08 --> T09
|
|
|
+ T03 --> T12
|
|
|
+ T03 --> T13
|
|
|
+ T03 --> T17
|
|
|
+ T07 --> T14
|
|
|
+ T07 --> T15
|
|
|
+ T12 --> T17
|
|
|
+ T05 --> T11
|
|
|
+
|
|
|
+ classDef p0 fill:#e6f7ff,stroke:#1890ff;
|
|
|
+ classDef p1 fill:#f6ffed,stroke:#52c41a;
|
|
|
+ classDef p2 fill:#fff7e6,stroke:#fa8c16;
|
|
|
+ class T01,T02,T03,T04,T05,T06,T07,T08 p0;
|
|
|
+ class T09,T10,T11,T12,T13 p1;
|
|
|
+ class T14,T15,T16,T17 p2;
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 附录 A:计分核心公式速查(对接第七节)
|
|
|
+
|
|
|
+```
|
|
|
+# 信号检测论(游戏/判断类任务)
|
|
|
+d′ = Φ⁻¹(HR) − Φ⁻¹(FAR) # HR=命中率, FAR=虚报率;边界用 log-linear (+0.5/N) 修正
|
|
|
+c = −(z_HR + z_FAR) / 2 # 判定标准
|
|
|
+β = exp(−d′ · c) = exp(d′·(z_HR+z_FAR)/2) # 作答倾向;|logβ| 超常模 2SD → 降权/标记复核
|
|
|
+
|
|
|
+# 标准分(7.1)
|
|
|
+Z = (x − μ_age) / σ_age
|
|
|
+T = 50 + 10·Z (正向指标)
|
|
|
+T = 100 − (50 + 10·Z) (负向指标:反应时/持续性错误等)
|
|
|
+
|
|
|
+# 维度分(7.2)
|
|
|
+维度分 = 100 × Σ(w_i · c_i · T_i) / Σ(w_i · c_i)
|
|
|
+ w_i : L1=0.50 / L2=0.30 / L3=0.20(维度内归一化;缺失源从分母剔除后重归一化)
|
|
|
+ c_i : 数据完整度系数 = min(1, 有效样本数 / 要求样本数)
|
|
|
+
|
|
|
+# 置信度(7.3)
|
|
|
+置信度 = 数据完整度均值 × 一致性系数
|
|
|
+一致性系数 = 1.0(≥2源且ICC≥0.60) / 0.8(≥2源但0.40–0.60) / 0.6(仅1源)
|
|
|
+
|
|
|
+# 五维健康指数(7.4)
|
|
|
+健康指数 = Σ(维度分 × 维度权重) / Σ(维度权重) # 默认等权,配置表可调
|
|
|
+```
|
|
|
+
|
|
|
+## 附录 B:与现有系统对接点(确认)
|
|
|
+
|
|
|
+| 现有位置 | 本计划填补 |
|
|
|
+|---------|-----------|
|
|
|
+| `EnergyService.getOverview()` L1818 `healthIndex = 0` / L1825 `totalHealthIndex = 0` | T03 替换为 `HealthIndexService` 快照读取 |
|
|
|
+| `HealthDimensionVO.DimensionItem` | T03 扩展 `confidence`/`dataSources`/`sampleSize`/`layerBreakdown`;VO 顶层加 `confidence` |
|
|
|
+| DAN 维度 attention/focus/memory/logic/emotion | 归入**智**维度,由 T08/T09 游戏化行为计量替代现有人工录入(`DanAssessmentResult` 可作为历史数据源之一) |
|
|
|
+| `CognitiveNorm`(cognitive_norms) | T12 复用其 age/gender 分段 + 百分位模式,扩展为全维度 `AssessmentMetricNorm` |
|
|
|
+| `body/mind/wisdom/action/wealth-detail` 页面 | T04–T11 各维度测评入口与指标展示 |
|
|
|
+| `docs/舌诊情绪识别_技术选型.md` | T05/T06 直接沿用其选型(TongueDiagnosis.AI / DeepFace),不重复论证 |
|
|
|
+| `assessment-market-plan.md` 阶段三/四 | 本计划维度分可作为"方案生成引擎"的输入(consumes 维度分) |
|