# 家庭天盘 · 传统文化 + 五维基础能量分 设计文档 - **日期**: 2026-09-09 - **状态**: 设计待审 - **需求来源**: 用户「完善家庭天盘的展示设计,用姓名、生日通过生辰八字、星座和数字能量进行天盘内容定义。同时也可以对五维有一个基础能量分的计算」 ## 1. 背景与现状 ### 1.1 现有实现(已具备) | 能力 | 位置 | 说明 | |------|------|------| | 八字四柱 | `family_member_attributes.eight_characters` | JSON `{"year":"甲子","month":"丙寅","day":"戊辰","hour":"壬申"}` | | 五行元素 | `family_member_attributes.wuxing_elements` | JSON `{"wood":30,"fire":45,"earth":60,"metal":25,"water":40}` | | 生肖 | `family_member_attributes.zodiac` | rat/ox/... | | 出生时间 | `family_member_attributes.birth_datetime` | 精确到分钟,用于排盘 | | 生命灵数 | `NumSoulCalculator` + `InnatePortraitService.calculateNumSoul()` | lifePath/天赋数/生日数/命运数,主数 11/22/33 保留 | | 灵数配置 | `numsoul_detail_config` 表 | 1-9 号人 title/keywords/advice/colorHex | | 先天分 | `family_member_attributes.mind_base_score` / `wisdom_base_score` | 仅心/智两维已有 | | 天盘聚合 | `TianpanService.buildDashboard()` / `buildMemberDetail()` | 已返回八字/星座/灵数/五行/能量快照 | ### 1.2 缺口 1. 五维基础分仅覆盖 mind/wisdom 两维,缺 body/action/wealth 2. 天盘主页面 canvas 成员节点未展示传统文化信息 3. 成员弹窗仅展示生肖/星座/代际/动态能量,无八字/灵数/五维基础分 4. 无「全家成员传统文化对比」专属页面 ### 1.3 设计决策(用户已确认) 1. **展示范围**:以上都要 —— canvas 节点标注 + 成员弹窗增强 + 新增专属页面 2. **五维基础分算法**:八字五行 + 星座 + 灵数 加权(确定性规则,不走 AI) 3. **数字能量**:9 型人格数字能量学(即生命灵数体系,复用现有 `NumSoulCalculator`) ## 2. 五维基础能量分算法 ### 2.1 核心映射(权威,来自 README 五维五行矩阵) | 维度 | code | 五行 | 颜色 | |:---:|:---:|:---:|:---:| | 身 | body | 土 earth | `#FF8C42` | | 智 | wisdom | 金 metal | `#6366F1` | | 富 | wealth | 水 water | `#F59E0B` | | 行 | action | 木 wood | `#10B981` | | 心 | mind | 火 fire | `#FF6B9D` | ### 2.2 加权公式 ``` 五维基础分[dim] = round( 八字五行[dim] × 0.6 + 星座命中[dim] × 20 + 灵数命中[dim] × 20 ) ``` - 分数范围:每维度 0-100 - 八字贡献 0-60 分(主因子,占 60%) - 星座贡献 0-20 分(占 20%) - 灵数贡献 0-20 分(占 20%) ### 2.3 八字五行层(权重 60%) 直接取 `wuxingElements` 中对应五行值(0-100 量纲)乘以 0.6: | 五行 | 映射维度 | |:---:|:---:| | wood 木 | action 行 | | fire 火 | mind 心 | | earth 土 | body 身 | | metal 金 | wisdom 智 | | water 水 | wealth 富 | **缺数据兜底**:某成员无 `wuxingElements`(或某五行缺失)时,该维度取中性值 50。 ### 2.4 星座层(权重 20%) 西方 12 星座四元素 → 五行 → 五维映射,命中维度 +20 分: | 四元素 | 星座 | 五行 | 维度 | |:---:|------|:---:|:---:| | 火象 | 白羊/狮子/射手 | 火 | 心 | | 土象 | 金牛/处女/摩羯 | 土 | 身 | | 风象 | 双子/天秤/水瓶 | 木 | 行 | | 水象 | 巨蟹/天蝎/双鱼 | 水 | 富 | **边界说明**:西方占星无「金」元素,金(智)在星座层恒 0 贡献。智维度由八字金 + 灵数(3/7)覆盖,不影响整体平衡。星座数据来源:`TianpanService.enrichMembers()` 已通过 `zodiacAnnualEnergyService.getWesternSign(month, day)` 计算 `westernSign`。 **无星座数据兜底**:westernSign 为空时星座层全部 0 贡献。 ### 2.5 生命灵数层(权重 20%) 灵数(生命数 lifePath,1-9)映射主维度,命中维度 +20 分: | 灵数 | 人格特质 | 主维度 | |:---:|:---:|:---:| | 1 | 开创/独立/领导 | 行 | | 2 | 合群/同理/协调 | 心 | | 3 | 创意/表达 | 智 | | 4 | 务实/规律/稳定 | 身 | | 5 | 自由/冒险 | 行 | | 6 | 关怀/责任/家庭 | 心 | | 7 | 分析/策略/求知 | 智 | | 8 | 商业/权力/物质 | 富 | | 9 | 博爱/理想 | 心 | 灵数来源:现有 `NumSoulCalculator.calcLifePath(year, month, day)`(主数 11/22/33 保留)。`TianpanMemberVO.lifeNumber` 来自 `behaviorModifier` 中存储值,**服务内做防御性化简**:11→2、22→4、33→6(主数化简),其余 >9 值按 digit sum 递归化简至 1-9,null 则不命中。 **无灵数数据兜底**:无 birthDatetime 时灵数层全部 0 贡献。 ### 2.6 计算示例 输入:八字五行 `{wood:40, fire:60, earth:50, metal:30, water:20}`、星座狮子座(火象→心)、灵数 7(→智) | 维度 | 八字×0.6 | 星座 | 灵数 | 基础分 | |:---:|:---:|:---:|:---:|:---:| | 身 body(土) | 50×0.6=30 | 0 | 0 | 30 | | 智 wisdom(金) | 30×0.6=18 | 0 | 20 | 38 | | 富 wealth(水) | 20×0.6=12 | 0 | 0 | 12 | | 行 action(木) | 40×0.6=24 | 0 | 0 | 24 | | 心 mind(火) | 60×0.6=36 | 20 | 0 | 56 | ## 3. 后端设计 ### 3.1 新增服务 `FiveDimensionScoreService` 文件:`cfc-backend/src/main/java/com/etotem/cfc/service/FiveDimensionScoreService.java` ```java @Service 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 * @param operator 计算来源(system/manual) */ public void calcAndSave(Long memberId, String memberType, Map wuxingElements, String westernSign, Integer lifeNumber, String operator) { Map 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 getScores(Long memberId) { ... } } ``` #### 3.1.1 星座 → 四元素映射(内部常量) ```java private static final Map ZODIAC_ELEMENT = ...; // 白羊座/狮子座/射手座 -> FIRE // 金牛座/处女座/摩羯座 -> EARTH // 双子座/天秤座/水瓶座 -> AIR // 巨蟹座/天蝎座/双鱼座 -> WATER // 元素 -> 维度: FIRE->mind, EARTH->body, AIR->action, WATER->wealth ``` #### 3.1.2 灵数 → 主维度映射(内部常量) ```java private static final Map LIFE_NUMBER_DIM = ...; // 1->action, 2->mind, 3->wisdom, 4->body, 5->action, 6->mind, 7->wisdom, 8->wealth, 9->mind ``` #### 3.1.3 计算逻辑 ```java // 1. 初始化五维 map,八字层: 各维度 = (wuxing 对应五行值 ?? 50) × 0.6 // 2. 星座命中: elementToDim[westernSign元素] += 20 // 3. 灵数命中: numberToDim[reduceMaster(lifeNumber)] += 20 // 11->2, 22->4, 33->6, >9 digit sum // 4. round 取整返回 ``` **单测**:`cfc-backend/src/test/java/com/etotem/cfc/unit/FiveDimensionScoreServiceTest.java` - 全数据用例(对照 2.6 示例断言精确值) - 各层缺数据兜底用例(wuxing=null / westernSign=null / lifeNumber=null) - 主数化简用例(11→映射2、22→映射4、33→映射6) ### 3.2 扩展 DTO `TianpanMemberVO` 新增字段: ```java private Map dimensionBaseScores; // 五维基础分 {body,mind,wisdom,action,wealth} ``` ### 3.3 改动点 **`TianpanService.enrichMembers()`**(第 174 行附近): - 原有 `m.getWuxingElements()`、`vo.getWesternSign()`、`m.getLifeNumber()` 保持不变 - 改为从新表读取已落库的五维基础分:`fiveDimensionScoreService.getScores(m.getMemberId())` - 若表无数据(首次部署或重算未完成)则 fallback 到内存计算(`calcBaseScores(...)`)并立即落库 - 新增 `zodiacName` 填充(见 3.6) **`TianpanService.buildMemberDetail()`**:经 `enrichMembers` 自动填充,无需额外改动。 **依赖注入**:`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.5 显式不做的事 - ❌ 不引入 AI/LangGraph —— 用户已确认走确定性加权计算 ## 4. 前端设计(三处增强) ### 4.1 Canvas 成员节点标注(`pages/tianpan/index.vue`) `drawMemberNodes()`(第 375 行附近): - 成员节点圆形下方增加一行小字:`生肖·灵数`(如 `兔·7`) - 数据来源:`member.zodiacName`(生肖名)+ `member.lifeNumber` - 无生肖/灵数时不显示该行(避免空标注) - 颜色:跟随 `getMemberColor(member.effectiveRole)` - 字体:9px,与节点名字体一致 **注意**:`enrichMembers` 目前只设置了 `vo.setZodiac(m.getZodiac())`(生肖代码,如 rat),**未设置 `zodiacName`(生肖中文名)**。前端弹窗/节点展示生肖名必须补齐:在 `enrichMembers` 中通过生肖代码映射中文名(映射表参考 `ZodiacConfig`/`findZodiacName` 逻辑,rat→鼠/ox→牛/...)并 `vo.setZodiacName(...)`。 ### 4.2 成员弹窗增强(`pages/tianpan/index.vue` `member-popup`) 弹窗内容重构为两区块: **① 基本信息区**(现有 + 扩展): - 现有:生肖、星座、代际 - 新增:生命灵数(`member.lifeNumber`,显示 `灵数 N`)、八字四柱(`member.eightCharacters`:年/月/日/时柱横向四格排布,复用 `FamilyTianpanCard` 的 `pillarLabels` 样式) - 脱敏:孩子视角查看家长成员时,后端已脱敏为仅年柱(`redactEightCharacters`),前端直接渲染 **② 能量区**(双条对比): - 现有:动态能量条(`selectedMember.energy`) - 新增:**五维基础分**条(`selectedMember.dimensionBaseScores`,用五维标准色,复用现有 `.energy-bar` 样式) ### 4.3 新增「命理」专属页面 `pages/tianpan/traditional.vue` **入口**:`pages/tianpan/index.vue` canvas 下方、tab 栏之前新增「家庭成员命理解读」入口卡片(样式参考现有 `fortune-card`) **页面结构**(全家成员传统文化对比): 1. **家庭成员列表**:`mapGetters('tianpan', ['members'])` 数据(复用 dashboard 已加载数据,不重复请求) 2. **每个成员展开卡片**: - 头部:头像 + 昵称 + 角色 - 八字四柱:年/月/日/时柱四格 - 五行条形图:复用 `FamilyTianpanCard` wuxingData 样式 - 星座 + 生肖 tag - 灵数:**定稿为简化版** —— 仅展示生命数(`member.lifeNumber`)+ 灵数称号(`member.lifeNumberTitle`)。完整的天赋数/生日数/命运数(`NumSoulDetailVO`)不随 dashboard 返回,如需完整版走 `/api/tianpan/member/{id}` 详情扩展(本迭代不做,列入 out of scope) - **五维基础分**:条形图(五维标准色)+ 总分 **页面注册**:`pages.json` 的 `pages/tianpan` 分包新增 `traditional` **API 去重规范**:本页复用 store `tianpan/members`(dashboard 已加载),禁止重复请求 `/api/tianpan/dashboard`;成员展开明细如需更多数据走 `/api/tianpan/member/{id}`(按需点击加载,遵守规则 4 不 N+1) ### 4.4 数据依赖核对 | 前端展示项 | 后端字段 | 现状 | 动作 | |------|------|------|------| | 生肖名 | `zodiacName` | ❌ `enrichMembers` 未设置(仅 zodiac 代码) | **补齐**:代码→中文名映射 + setZodiacName | | 星座 | `westernSign` | ✅ 已设置 | 无 | | 灵数 | `lifeNumber` | ✅ 已设置 | 无 | | 八字四柱 | `eightCharacters` | ✅ 已设置(含脱敏) | 无 | | 五行 | `wuxingElements` | ✅ 已设置 | 无 | | 五维基础分 | `dimensionBaseScores` | ❌ 新增 | 3.3 实现 | | 灵数详情(天赋/生日/命运数) | numSoul | `TianpanMemberVO` 未含 | 传统页简化版仅展示 lifeNumber | ## 5. 测试策略 ### 5.1 后端单测(必须) `FiveDimensionScoreServiceTest`: - 全数据用例(对照 2.6 示例断言) - 兜底用例:wuxing=null、westernSign=null、lifeNumber=null、全部为 null(五维全 50×0.6=30) - 主数化简用例 - 星座边界:12 星座全部覆盖 + 未知星座字符串 ### 5.2 前端校验 - `node --check` 提取的 script 块语法校验(按 cfc-frontend/AGENTS.md 规范,Agent 不打包) - CI 门禁:`node scripts/audit-duplicate-api-calls.js` 通过 - 小程序限制自查:无可选链 `?.`、无 CSS Grid、无 `:key` 表达式、无 `new Date(string)` ### 5.3 编译验证 ```bash cd cfc-backend && mvn clean compile ``` ## 6. 范围边界 **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**: - 姓名数理(五格剖象法)—— 需汉字笔画库,单独需求 - 灵数九宫格连线(147/258/369 连线分析)—— 后续迭代 - 灵数完整详情(天赋数/生日数/命运数)随 member 详情接口返回 —— 后续迭代 - AI 天盘解读(LangGraph)—— 未确认前不做 - 天盘周报 PDF 内容变更 - 数据库迁移(无新表无新列)