|
|
@@ -127,18 +127,44 @@
|
|
|
public class FiveDimensionScoreService {
|
|
|
|
|
|
/**
|
|
|
- * 计算五维基础能量分(确定性规则,无状态)
|
|
|
+ * 计算并落库(INSERT ON DUPLICATE KEY UPDATE)
|
|
|
*
|
|
|
+ * @param memberId 成员 ID
|
|
|
+ * @param memberType 成员类型
|
|
|
* @param wuxingElements 五行元素 {"wood":..,"fire":..,"earth":..,"metal":..,"water":..},可为 null
|
|
|
* @param westernSign 西方星座中文名(如 "狮子座"),可为 null
|
|
|
* @param lifeNumber 生命灵数(主数 11/22/33 已化简为 1-9),可为 null
|
|
|
- * @return Map<String,Integer> { body, mind, wisdom, action, wealth }
|
|
|
+ * @param operator 计算来源(system/manual)
|
|
|
*/
|
|
|
- public Map<String, Integer> calcBaseScores(Map<String, Integer> wuxingElements,
|
|
|
- String westernSign,
|
|
|
- Integer lifeNumber) {
|
|
|
- // 实现要点见 3.1.1 - 3.1.3
|
|
|
+ public void calcAndSave(Long memberId, String memberType,
|
|
|
+ Map<String, Integer> wuxingElements,
|
|
|
+ String westernSign, Integer lifeNumber,
|
|
|
+ String operator) {
|
|
|
+ Map<String, Integer> scores = calcBaseScores(wuxingElements, westernSign, lifeNumber);
|
|
|
+ saveScores(memberId, memberType, scores, operator);
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 重算指定成员(覆盖现有记录)
|
|
|
+ */
|
|
|
+ public void recalibrate(Long memberId, String memberType, String operator) {
|
|
|
+ FamilyMemberAttributes attrs = familyMemberAttributeService.getByMember(memberId, memberType);
|
|
|
+ if (attrs == null) return;
|
|
|
+ String westernSign = calcWesternSignFromAttrs(attrs); // 复用 zodiacAnnualEnergyService 逻辑
|
|
|
+ Integer lifeNumber = attrs.getLifeNumber(); // 若未存则从 birthDatetime 重新算
|
|
|
+ calcAndSave(memberId, memberType, parseWuxingMap(attrs.getWuxingElements()),
|
|
|
+ westernSign, lifeNumber, operator);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 批量重算全家(用于数据修复/策略调整)
|
|
|
+ */
|
|
|
+ public int recalibrateFamily(Long familyId, String operator) { ... }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 查询五维基础分(供 dashboard/member 接口读取)
|
|
|
+ */
|
|
|
+ public Map<String, Integer> getScores(Long memberId) { ... }
|
|
|
}
|
|
|
```
|
|
|
|
|
|
@@ -185,18 +211,46 @@ private Map<String, Integer> dimensionBaseScores; // 五维基础分 {body,mind
|
|
|
### 3.3 改动点
|
|
|
|
|
|
**`TianpanService.enrichMembers()`**(第 174 行附近):
|
|
|
-- 成员已有 `m.getWuxingElements()`、`vo.getWesternSign()`、`m.getLifeNumber()`
|
|
|
-- 在填充 `vo` 时调用 `fiveDimensionScoreService.calcBaseScores(...)` 并 `vo.setDimensionBaseScores(...)`
|
|
|
+- 原有 `m.getWuxingElements()`、`vo.getWesternSign()`、`m.getLifeNumber()` 保持不变
|
|
|
+- 改为从新表读取已落库的五维基础分:`fiveDimensionScoreService.getScores(m.getMemberId())`
|
|
|
+- 若表无数据(首次部署或重算未完成)则 fallback 到内存计算(`calcBaseScores(...)`)并立即落库
|
|
|
+- 新增 `zodiacName` 填充(见 3.6)
|
|
|
|
|
|
**`TianpanService.buildMemberDetail()`**:经 `enrichMembers` 自动填充,无需额外改动。
|
|
|
|
|
|
-**依赖注入**:`TianpanService` 增加 `@Resource private FiveDimensionScoreService fiveDimensionScoreService;`(注意 Bean 名与字段名一致)。
|
|
|
+**依赖注入**:`TianpanService` 增加 `@Resource private FiveDimensionScoreService fiveDimensionScoreService;`
|
|
|
+
|
|
|
+**新增 Controller 接口**:
|
|
|
+- `POST /api/tianpan/recalibrate` — 手动触发单个成员重算
|
|
|
+ - 请求体:`{memberId, memberType, operator: "admin"}`
|
|
|
+ - 返回:更新后的 `dimensionBaseScores`
|
|
|
+- `POST /api/tianpan/recalibrate-family` — 批量重算全家(管理员用)
|
|
|
+ - 请求体:`{familyId, operator: "admin"}`
|
|
|
+ - 返回:成功重算的成员数
|
|
|
+
|
|
|
+**管理端集成**:在 Web 管理端家庭成员详情页新增「重新计算五维基础分」按钮,调用上述接口。
|
|
|
+
|
|
|
+### 3.4 数据库迁移
|
|
|
+
|
|
|
+**新增表 `family_member_dimension_base_scores`**:
|
|
|
+```sql
|
|
|
+CREATE TABLE IF NOT EXISTS family_member_dimension_base_scores (
|
|
|
+ id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
|
|
+ member_id BIGINT NOT NULL COMMENT '家庭成员ID',
|
|
|
+ member_type VARCHAR(20) NOT NULL COMMENT '成员类型: child/parent',
|
|
|
+ dimension_code VARCHAR(20) NOT NULL COMMENT '维度: body/mind/wisdom/action/wealth',
|
|
|
+ base_score INT NOT NULL COMMENT '基础能量分(0-100)',
|
|
|
+ last_calculated_at DATETIME NOT NULL COMMENT '最后计算时间',
|
|
|
+ calculated_by VARCHAR(50) DEFAULT 'system' COMMENT '计算来源(system/manual)',
|
|
|
+ UNIQUE KEY uk_member_dimension (member_id, dimension_code),
|
|
|
+ INDEX idx_member (member_id)
|
|
|
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='五维基础能量分(落库,支持重算)';
|
|
|
+```
|
|
|
+
|
|
|
+**迁移逻辑**:`DatabaseInitializer.runMigrations()` 追加迁移,对已有成员批量回填(若 `family_member_attributes` 有数据则触发一次性重算写入)。
|
|
|
|
|
|
-### 3.4 明确不做的事
|
|
|
+### 3.5 显式不做的事
|
|
|
|
|
|
-- ❌ 不新增数据库表 —— 八字/星座/灵数数据均已存在 `family_member_attributes`,五维基础分为实时计算(确定性、无状态)
|
|
|
-- ❌ 不落库缓存 —— 计算成本极低(纯内存映射),无性能压力
|
|
|
-- ❌ 不新增 Controller 接口 —— 通过现有 `/api/tianpan/dashboard` 和 `/api/tianpan/member/{id}` 返回
|
|
|
- ❌ 不引入 AI/LangGraph —— 用户已确认走确定性加权计算
|
|
|
|
|
|
## 4. 前端设计(三处增强)
|
|
|
@@ -281,9 +335,12 @@ cd cfc-backend && mvn clean compile
|
|
|
|
|
|
**In scope**:
|
|
|
- 五维基础分算法服务 + 单测
|
|
|
+- `family_member_dimension_base_scores` 表 + 迁移 + 批量回填
|
|
|
- `TianpanMemberVO` 扩展(dimensionBaseScores)+ `enrichMembers` 填充(含 zodiacName 补齐)
|
|
|
+- 重算接口 `POST /api/tianpan/recalibrate` / `recalibrate-family`
|
|
|
- 天盘首页 canvas 节点标注 + 成员弹窗增强
|
|
|
- 新增 `pages/tianpan/traditional.vue` + 入口卡片 + pages.json 注册
|
|
|
+- Web 管理端家庭成员详情「重新计算五维基础分」按钮(可选)
|
|
|
|
|
|
**Out of scope**:
|
|
|
- 姓名数理(五格剖象法)—— 需汉字笔画库,单独需求
|