Przeglądaj źródła

feat(energy): 富维度重构为利他创富四子维度模型(能力/利他/CF值/素养)

- 后端:EnergyService calcParentWealth/calcChildWealth 重构为 4 子维度加权
  - 家长:能力25% + 利他30% + CF值35% + 素养10%
  - 孩子:学业25% + 利他30% + 积分35% + 素养10%
- 新增 mapper 注入:FamilyPlatformBalanceMapper(CF值)、ReferralTreeMapper(邀请人数)、GuideMapper(服务商资质)
- DTO:新增 wealthSkill/wealthAltruism/wealthFx 共用字段,旧字段兼容保留
- 前端:WealthSubScores.vue、wealth/index.vue、health-main/index.vue 全部适配 4 子维度
- pages.json:移除不存在的 intent-quiz 页面引用
liaoxg 1 miesiąc temu
rodzic
commit
f355d4948b

+ 8 - 3
cfc-backend/src/main/java/com/etotem/cfc/dto/MemberEnergyDTO.java

@@ -32,12 +32,17 @@ public class MemberEnergyDTO {
     /** 个人综合能量值 */
     private Integer overallScore;
 
-    // 富的子维度(parent)
-    private Integer wealthIncome;       // 金钱/收入
+    // ========== 富·利他创富模型(4子维度,家长/孩子共用字段) ==========
+    private Integer wealthSkill;        // 个人能力(家长:能力认证/服务商资质;孩子:学业能力)
+    private Integer wealthAltruism;     // 利他贡献(家长:帮助过多少人;孩子:帮助他人)
+    private Integer wealthIncome;       // 财务积累(家长:CF值;孩子:积分)
+    private Integer wealthFx;           // 财务素养(记账/理财任务)
+
+    // 富的子维度(旧版 parent,兼容保留)
     private Integer wealthAchievement;  // 社会成就
     private Integer wealthNetwork;      // 资源网络
 
-    // 富的子维度(child)
+    // 富的子维度(旧版 child,兼容保留
     private Integer wealthEducation;    // 学业成绩
     private Integer wealthSocial;       // 社交筹码
     private Integer wealthPoints;       // 规则博弈(积分效率)

+ 72 - 42
cfc-backend/src/main/java/com/etotem/cfc/service/EnergyService.java

@@ -67,6 +67,15 @@ public class EnergyService {
     @Resource
     private HealthDimensionScoreService healthDimensionScoreService;
 
+    @Resource
+    private FamilyPlatformBalanceMapper familyPlatformBalanceMapper;
+
+    @Resource
+    private ReferralTreeMapper referralTreeMapper;
+
+    @Resource
+    private GuideMapper guideMapper;
+
     /**
      * 计算整个家庭的能量沙盘数据
      *
@@ -316,50 +325,58 @@ public class EnergyService {
                 Arrays.asList("习惯", "好习惯", "自律", "家务", "自理", "作息"), 365);
     }
 
-    /** 家长 富 — 三子维度加权 */
+    /** 家长 富 — 利他创富四子维度加权:个人能力25% + 利他贡献30% + 财务积累(CF值)35% + 财务素养10% */
     private int calcParentWealth(User parent, MemberEnergyDTO dto) {
+        int skill = calcParentWealthSkill(parent);
+        int altruism = calcParentWealthAltruism(parent);
         int income = calcParentWealthIncome(parent);
-        int achievement = calcParentWealthAchievement(parent);
-        int network = calcParentWealthNetwork(parent);
+        int fx = calcParentWealthFx(parent);
+        dto.setWealthSkill(skill);
+        dto.setWealthAltruism(altruism);
         dto.setWealthIncome(income);
-        dto.setWealthAchievement(achievement);
-        dto.setWealthNetwork(network);
-        return (int) Math.round(income * 0.5 + achievement * 0.3 + network * 0.2);
+        dto.setWealthFx(fx);
+        // 旧字段兼容(新前端改为读 wealthSkill/wealthAltruism/wealthIncome/wealthFx)
+        dto.setWealthAchievement(skill);
+        dto.setWealthNetwork(altruism);
+        return (int) Math.round(skill * 0.25 + altruism * 0.3 + income * 0.35 + fx * 0.1);
+    }
+
+    /** 家长富-个人能力:服务商/规划师资质(active) 满分100,否则按成长类任务完成率 */
+    private int calcParentWealthSkill(User parent) {
+        Long guideCount = guideMapper.selectCount(
+                new LambdaQueryWrapper<Guide>()
+                        .eq(Guide::getUserId, parent.getId())
+                        .eq(Guide::getStatus, "active"));
+        if (guideCount != null && guideCount > 0) {
+            return 100;
+        }
+        return calcTaskCompletionRate(parent.getId(), "parent",
+                Arrays.asList("学习", "培训", "技能", "阅读", "知识"), 365);
     }
 
-    /** 家长富-金钱收入:积分总量/500 */
-    private int calcParentWealthIncome(User parent) {
-        Integer totalPoints = parent.getTotalPoints();
-        if (totalPoints == null) totalPoints = 0;
-        int refMax = 500;
-        int score = Math.min(totalPoints * 100 / Math.max(refMax, 1), 100);
-        return Math.max(score, 0);
+    /** 家长富-利他贡献:ReferralTree 直接邀请人数折算(1人=20分,每多1人+15分,最高100) */
+    private int calcParentWealthAltruism(User parent) {
+        Long count = referralTreeMapper.selectCount(
+                new LambdaQueryWrapper<ReferralTree>().eq(ReferralTree::getParentId, parent.getId()));
+        if (count == null || count == 0) return 0;
+        return clamp(20 + (int) ((count - 1) * 15), 0, 100);
     }
 
-    /** 家长富-社会成就:家庭任务完成率(近30天completed/total,0=无数据) */
-    private int calcParentWealthAchievement(User parent) {
+    /** 家长富-财务积累:家庭CF值累计获得(totalEarned)折算,5000CF=100分 */
+    private int calcParentWealthIncome(User parent) {
         if (parent.getFamilyId() == null) return 0;
-        Calendar cal = Calendar.getInstance();
-        cal.add(Calendar.DAY_OF_YEAR, -30);
-        LambdaQueryWrapper<Task> wrapper = new LambdaQueryWrapper<Task>()
-                .eq(Task::getFamilyId, parent.getFamilyId())
-                .eq(Task::getExecutorType, "parent")
-                .gt(Task::getCreatedAt, cal.getTime())
-                .ne(Task::getIsTemplate, 1);
-        SortUtil.applySort(wrapper);
-        List<Task> tasks = taskMapper.selectList(wrapper);
-        if (tasks.isEmpty()) return 0;
-        long completed = tasks.stream().filter(t -> "completed".equals(t.getStatus())).count();
-        return clamp((int) Math.round(completed * 100.0 / tasks.size()), 0, 100);
+        FamilyPlatformBalance balance = familyPlatformBalanceMapper.selectOne(
+                new LambdaQueryWrapper<FamilyPlatformBalance>()
+                        .eq(FamilyPlatformBalance::getFamilyId, parent.getFamilyId())
+                        .last("LIMIT 1"));
+        if (balance == null || balance.getTotalEarned() == null) return 0;
+        return clamp(balance.getTotalEarned() / 50, 0, 100);
     }
 
-    /** 家长富-资源网络:家庭成员数折算(1人=20分,每多1人+15分,最高100) */
-    private int calcParentWealthNetwork(User parent) {
-        if (parent.getFamilyId() == null) return 0;
-        Long count = familyMemberMapper.selectCount(
-                new LambdaQueryWrapper<FamilyMember>().eq(FamilyMember::getFamilyId, parent.getFamilyId()));
-        if (count == null || count == 0) return 0;
-        return clamp(20 + (int) ((count - 1) * 15), 0, 100);
+    /** 家长富-财务素养:记账/理财/储蓄类任务完成率 */
+    private int calcParentWealthFx(User parent) {
+        return calcTaskCompletionRate(parent.getId(), "parent",
+                Arrays.asList("记账", "理财", "财务", "储蓄", "投资"), 365);
     }
 
     // ==================== 孩子能量计算 ====================
@@ -698,18 +715,24 @@ public class EnergyService {
         return Math.min((int) Math.round(streakScore * 0.4 + habitScore * 0.6), 100);
     }
 
-    /** 孩子 富 — 三子维度加权 */
+    /** 孩子 富 — 利他创富四子维度加权:学业能力25% + 利他贡献30% + 积分积累35% + 财务素养10% */
     private int calcChildWealth(FamilyMember child, MemberEnergyDTO dto) {
         int edu = calcChildWealthEducation(child);
-        int social = calcChildWealthSocial(child);
+        int altruism = calcChildWealthAltruism(child);
         int points = calcChildWealthPoints(child);
+        int fx = calcChildWealthFx(child);
+        dto.setWealthSkill(edu);
+        dto.setWealthAltruism(altruism);
+        dto.setWealthIncome(points);
+        dto.setWealthFx(fx);
+        // 旧字段兼容(新前端改为读 wealthSkill/wealthAltruism/wealthIncome/wealthFx)
         dto.setWealthEducation(edu);
-        dto.setWealthSocial(social);
+        dto.setWealthSocial(altruism);
         dto.setWealthPoints(points);
-        return (int) Math.round(edu * 0.3 + social * 0.2 + points * 0.5);
+        return (int) Math.round(edu * 0.25 + altruism * 0.3 + points * 0.35 + fx * 0.1);
     }
 
-    /** 孩子富-学业成绩:DAN测评最近3次综合分+进步趋势 */
+    /** 孩子富-学业能力:DAN测评最近3次综合分+进步趋势 */
     private int calcChildWealthEducation(FamilyMember child) {
         Long memberId = child.getId();
         LambdaQueryWrapper<DanAssessmentResult> qw = new LambdaQueryWrapper<DanAssessmentResult>()
@@ -741,9 +764,16 @@ public class EnergyService {
         return clamp((int) Math.round(avg), 0, 100);
     }
 
-    /** 孩子富-社交筹码:活动参与次数(第一阶段返回0) */
-    private int calcChildWealthSocial(FamilyMember child) {
-        return 0;
+    /** 孩子富-利他贡献:帮助他人/分享/公益/家务类任务完成率 */
+    private int calcChildWealthAltruism(FamilyMember child) {
+        return calcTaskCompletionRate(child.getId(), "child",
+                Arrays.asList("帮助", "分享", "公益", "家务", "合作"), 365);
+    }
+
+    /** 孩子富-财务素养:财商/记账/理财/储蓄类任务完成率 */
+    private int calcChildWealthFx(FamilyMember child) {
+        return calcTaskCompletionRate(child.getId(), "child",
+                Arrays.asList("财商", "记账", "理财", "储蓄", "投资"), 365);
     }
 
     /** 孩子富-规则博弈:积分获取效率 */

+ 12 - 18
cfc-frontend/components/WealthSubScores.vue

@@ -29,27 +29,19 @@ export default {
       type: String,
       default: 'parent'
     },
-    income: {
-      type: Number,
-      default: 0
-    },
-    achievement: {
+    skill: {
       type: Number,
       default: 0
     },
-    network: {
+    altruism: {
       type: Number,
       default: 0
     },
-    education: {
-      type: Number,
-      default: 0
-    },
-    social: {
+    income: {
       type: Number,
       default: 0
     },
-    points: {
+    fx: {
       type: Number,
       default: 0
     }
@@ -61,15 +53,17 @@ export default {
     subItems() {
       if (this.isParent) {
         return [
-          { key: 'income', label: '金钱收入', score: this.income, weight: 50 },
-          { key: 'achievement', label: '社会成就', score: this.achievement, weight: 30 },
-          { key: 'network', label: '资源网络', score: this.network, weight: 20 }
+          { key: 'skill', label: '个人能力', score: this.skill, weight: 25 },
+          { key: 'altruism', label: '利他贡献', score: this.altruism, weight: 30 },
+          { key: 'income', label: 'CF值积累', score: this.income, weight: 35 },
+          { key: 'fx', label: '财务素养', score: this.fx, weight: 10 }
         ]
       }
       return [
-        { key: 'education', label: '学业成绩', score: this.education, weight: 30 },
-        { key: 'social', label: '社交筹码', score: this.social, weight: 20 },
-        { key: 'points', label: '规则博弈', score: this.points, weight: 50 }
+        { key: 'skill', label: '学业能力', score: this.skill, weight: 25 },
+        { key: 'altruism', label: '利他贡献', score: this.altruism, weight: 30 },
+        { key: 'income', label: '积分积累', score: this.income, weight: 35 },
+        { key: 'fx', label: '财务素养', score: this.fx, weight: 10 }
       ]
     },
     tipText() {

+ 0 - 6
cfc-frontend/pages.json

@@ -925,12 +925,6 @@
           "style": {
             "navigationBarTitleText": "AI 健康问卷"
           }
-        },
-        {
-          "path": "intent-quiz",
-          "style": {
-            "navigationBarTitleText": "选择开始方式"
-          }
         }
       ]
     },

+ 6 - 14
cfc-frontend/pages/health-main/index.vue

@@ -341,9 +341,9 @@ export default {
       if (this.currentTab === 'wealth') {
         var isChild = !!uni.getStorageSync('currentChildId')
         if (isChild) {
-          return [{ label:'学业成绩',key:'education'},{ label:'社交筹码',key:'social'},{ label:'规则博弈',key:'points' }]
+          return [{ label:'学业能力',key:'skill'},{ label:'利他贡献',key:'altruism'},{ label:'积分积累',key:'income'},{ label:'财务素养',key:'fx' }]
         }
-        return [{ label:'金钱/收入',key:'income'},{ label:'社会成就',key:'achievement'},{ label:'资源网络',key:'network' }]
+        return [{ label:'个人能力',key:'skill'},{ label:'利他贡献',key:'altruism'},{ label:'CF值积累',key:'income'},{ label:'财务素养',key:'fx' }]
       }
       return [{ label:'生长发育',key:'growth'},{ label:'睡眠质量',key:'sleep'},{ label:'视力健康',key:'vision'},{ label:'免疫力',key:'immunity'},{ label:'营养均衡',key:'nutrition'},{ label:'肠胃健康',key:'gut'},{ label:'运动活力',key:'exercise' }]
     },
@@ -389,12 +389,8 @@ export default {
       }
       if (this.currentTab === 'wealth') {
         var d = this.wealthDetail
-        if (!d) return [0, 0, 0]
-        var isChild = !!uni.getStorageSync('currentChildId')
-        if (isChild) {
-          return [d.wealthEducation || 0, d.wealthSocial || 0, d.wealthPoints || 0]
-        }
-        return [d.wealthIncome || 0, d.wealthAchievement || 0, d.wealthNetwork || 0]
+        if (!d) return [0, 0, 0, 0]
+        return [d.wealthSkill || 0, d.wealthAltruism || 0, d.wealthIncome || 0, d.wealthFx || 0]
       }
       // body: fallback to demo
       if (this.reports.length > 0) {
@@ -436,11 +432,7 @@ export default {
       }
       if (this.currentTab === 'wealth' && this.wealthDetail) {
         var d = this.wealthDetail
-        var isChild = !!uni.getStorageSync('currentChildId')
-        if (isChild) {
-          return [d.wealthEducation || 0, d.wealthSocial || 0, d.wealthPoints || 0]
-        }
-        return [d.wealthIncome || 0, d.wealthAchievement || 0, d.wealthNetwork || 0]
+        return [d.wealthSkill || 0, d.wealthAltruism || 0, d.wealthIncome || 0, d.wealthFx || 0]
       }
       return []
     },
@@ -571,7 +563,7 @@ export default {
             self.relationshipEmpty = true
           }
         }).catch(function() { self.relationshipEmpty = true })
-        // 财富子维度(富维度三子维度
+        // 财富子维度(富维度四子维度:能力/利他/财务/素养
         if (memberId) {
           var memberType = uni.getStorageSync('currentChildId') ? 'child' : 'parent'
           api.getWealthDetail(memberId, memberType).then(function(res) {

+ 21 - 30
cfc-frontend/pages/wealth/index.vue

@@ -102,12 +102,10 @@
       <!-- 子维度水滴 -->
       <wealth-sub-scores
         :role="role"
+        :skill="wealthSkill"
+        :altruism="wealthAltruism"
         :income="wealthIncome"
-        :achievement="wealthAchievement"
-        :network="wealthNetwork"
-        :education="wealthEducation"
-        :social="wealthSocial"
-        :points="wealthPoints" />
+        :fx="wealthFx" />
 
       <!-- 子维度评分表 -->
       <dimension-sub-dims
@@ -148,7 +146,7 @@
         <view class="child-wealth-card">
           <view class="child-wealth-item">
             <text class="child-wealth-icon">⭐</text>
-            <text class="child-wealth-value">{{ wealthPoints || 0 }}</text>
+            <text class="child-wealth-value">{{ wealthIncome || 0 }}</text>
             <text class="child-wealth-label">累计积分</text>
           </view>
           <view class="child-wealth-item">
@@ -224,15 +222,11 @@ export default {
       role: 'parent',
       // 五维评分
       wealthScore: 0,
-      // 子维度 - parent
+      // 子维度 - 利他创富四维(家长/孩子共用字段)
+      wealthSkill: null,
+      wealthAltruism: null,
       wealthIncome: null,
-      wealthAchievement: null,
-      wealthNetwork: null,
-      wealthLegacy: null,
-      // 子维度 - child
-      wealthEducation: null,
-      wealthSocial: null,
-      wealthPoints: null,
+      wealthFx: null,
       // 子维度汇总(DimensionSubDims 用)
       wealthSubDims: [],
       // 身克富杠杆
@@ -387,31 +381,28 @@ export default {
         if (res && res.data) {
           var d = res.data
           this.wealthScore = d.wealthScore || 0
-          if (memberType === 'parent') {
-            this.wealthIncome = d.wealthIncome
-            this.wealthAchievement = d.wealthAchievement
-            this.wealthNetwork = d.wealthNetwork
-          } else {
-            this.wealthEducation = d.wealthEducation
-            this.wealthSocial = d.wealthSocial
-            this.wealthPoints = d.wealthPoints
-          }
+          // 利他创富四子维度(家长/孩子共用字段)
+          this.wealthSkill = d.wealthSkill
+          this.wealthAltruism = d.wealthAltruism
+          this.wealthIncome = d.wealthIncome
+          this.wealthFx = d.wealthFx
           // 身克富杠杆状态
           this.bodyWealthStatus = d.bodyWealthStatus || 'normal'
           this.bodyWealthMessage = d.bodyWealthMessage || ''
           // 子维度汇总(供 DimensionSubDims 使用)
           if (memberType === 'parent') {
             this.wealthSubDims = [
-              { label: '金钱收入', score: this.wealthIncome || 0, desc: '家庭总收入水平' },
-              { label: '社会成就', score: this.wealthAchievement || 0, desc: '家庭任务完成情况' },
-              { label: '资源网络', score: this.wealthNetwork || 0, desc: '家庭成员人脉资源' },
-              { label: '家族传承', score: (this.wealthLegacy || 0), desc: '价值观与精神传承' }
+              { label: '个人能力', score: this.wealthSkill || 0, desc: '服务商资质与成长学习' },
+              { label: '利他贡献', score: this.wealthAltruism || 0, desc: '邀请分享帮助他人' },
+              { label: 'CF值积累', score: this.wealthIncome || 0, desc: '家庭第二收入曲线' },
+              { label: '财务素养', score: this.wealthFx || 0, desc: '记账理财储蓄习惯' }
             ]
           } else {
             this.wealthSubDims = [
-              { label: '学习积分', score: this.wealthEducation || 0, desc: '通过学习教育获得的积分' },
-              { label: '社交积分', score: this.wealthSocial || 0, desc: '通过社交活动获得的积分' },
-              { label: '任务积分', score: this.wealthPoints || 0, desc: '完成任务获得的积分' }
+              { label: '学业能力', score: this.wealthSkill || 0, desc: '测评成绩与进步趋势' },
+              { label: '利他贡献', score: this.wealthAltruism || 0, desc: '帮助他人与分享' },
+              { label: '积分积累', score: this.wealthIncome || 0, desc: '完成任务获取积分' },
+              { label: '财务素养', score: this.wealthFx || 0, desc: '财商学习与储蓄习惯' }
             ]
           }
         }