Explorar o código

feat: 扩展天盘服务支持五维基础分展示和重算接口

iwt hai 1 semana
pai
achega
f097d3a0b3

+ 67 - 1
cfc-backend/src/main/java/com/etotem/cfc/controller/tianpan/TianpanController.java

@@ -2,11 +2,14 @@ package com.etotem.cfc.controller.tianpan;
 
 import com.etotem.cfc.common.Result;
 import com.etotem.cfc.dto.*;
-import com.etotem.cfc.service.TianpanService;
+import com.etotem.cfc.entity.FamilyMemberAttributes;
+import com.etotem.cfc.service.*;
 import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
+import java.util.Calendar;
+import java.util.LinkedHashMap;
 import java.util.Map;
 
 /**
@@ -21,6 +24,15 @@ public class TianpanController {
     @Resource
     private TianpanService tianpanService;
 
+    @Resource
+    private FamilyMemberAttributeService familyMemberAttributeService;
+
+    @Resource
+    private ZodiacAnnualEnergyService zodiacAnnualEnergyService;
+
+    @Resource
+    private FamilyMemberDimensionBaseScoreService familyMemberDimensionBaseScoreService;
+
     /**
      * 获取家庭天盘仪表盘
      * 
@@ -207,6 +219,60 @@ public class TianpanController {
         return Result.success(data);
     }
 
+    /**
+     * 重算单个成员的五维基础分
+     */
+    @PostMapping("/recalibrate")
+    public Result<Map<String, Integer>> recalibrate(
+            HttpServletRequest request,
+            @RequestBody Map<String, Object> params) {
+        Long memberId = Long.valueOf(params.get("memberId").toString());
+        String memberType = params.get("memberType") != null ? params.get("memberType").toString() : "child";
+        String operator = params.get("operator") != null ? params.get("operator").toString() : "system";
+
+        FamilyMemberAttributes attrs = familyMemberAttributeService.getByMember(memberId, memberType);
+        if (attrs == null) {
+            return Result.error("成员属性不存在");
+        }
+
+        Map<String, Integer> wuxingElements = parseWuxingElements(attrs.getWuxingElements());
+        String westernSign = null;
+        if (attrs.getBirthDatetime() != null) {
+            Calendar cal = Calendar.getInstance();
+            cal.setTime(attrs.getBirthDatetime());
+            westernSign = zodiacAnnualEnergyService.getWesternSign(cal.get(Calendar.MONTH) + 1, cal.get(Calendar.DAY_OF_MONTH));
+        }
+        Integer lifeNumber = extractLifeNumber(attrs.getBehaviorModifier());
+
+        familyMemberDimensionBaseScoreService.calcAndSave(memberId, memberType, wuxingElements, westernSign, lifeNumber, operator);
+        Map<String, Integer> scores = familyMemberDimensionBaseScoreService.getScores(memberId);
+        return Result.success(scores);
+    }
+
+    private Map<String, Integer> parseWuxingElements(String json) {
+        Map<String, Integer> result = new LinkedHashMap<>();
+        if (json == null || json.isEmpty()) return result;
+        try {
+            Map<String, Object> raw = familyMemberAttributeService.fromJson(json);
+            for (Map.Entry<String, Object> e : raw.entrySet()) {
+                if (e.getValue() instanceof Number) {
+                    result.put(e.getKey(), ((Number) e.getValue()).intValue());
+                }
+            }
+        } catch (Exception ignored) {}
+        return result;
+    }
+
+    private Integer extractLifeNumber(String behaviorModifier) {
+        if (behaviorModifier == null || behaviorModifier.isEmpty()) return null;
+        try {
+            Map<String, Object> map = familyMemberAttributeService.fromJson(behaviorModifier);
+            Object ln = map.get("lifeNumber");
+            if (ln instanceof Number) return ((Number) ln).intValue();
+        } catch (Exception ignored) {}
+        return null;
+    }
+
     // ========== 权限检查 ==========
 
     private boolean checkAccess(String role, Long familyId, Long currentUserId, HttpServletRequest request) {

+ 1 - 0
cfc-backend/src/main/java/com/etotem/cfc/dto/TianpanMemberVO.java

@@ -30,4 +30,5 @@ public class TianpanMemberVO {
     private Map<String, Integer> wuxingElements;  // 五行元素分布
     private String wuxingReading;                 // 五行解读文本
     private Map<String, Object> energySnapshot;  // 能量快照:body/mind/wisdom/action/wealth
+    private Map<String, Integer> dimensionBaseScores;  // 五维基础分(先天)
 }

+ 30 - 0
cfc-backend/src/main/java/com/etotem/cfc/service/TianpanService.java

@@ -54,6 +54,9 @@ public class TianpanService {
     @Resource
     private FamilyMemberService familyMemberService;
 
+    @Resource
+    private FamilyMemberDimensionBaseScoreService familyMemberDimensionBaseScoreService;
+
     @Resource
     private FamilyMemberMapper familyMemberMapper;
 
@@ -223,6 +226,23 @@ public class TianpanService {
             }
             vo.setEightCharacters(eightCharacters);
 
+            // 生肖中文名
+            vo.setZodiacName(findZodiacName(m.getZodiac()));
+
+            // 五维基础分:优先读库,无则计算并落库
+            Map<String, Integer> cachedScores = familyMemberDimensionBaseScoreService.getScores(m.getMemberId());
+            boolean hasScores = cachedScores.values().stream().anyMatch(s -> s != 50);
+            if (!hasScores) {
+                familyMemberDimensionBaseScoreService.calcAndSave(
+                        m.getMemberId(), m.getMemberType(),
+                        m.getWuxingElements(),
+                        vo.getWesternSign(),
+                        m.getLifeNumber(),
+                        "system");
+                cachedScores = familyMemberDimensionBaseScoreService.getScores(m.getMemberId());
+            }
+            vo.setDimensionBaseScores(cachedScores);
+
             result.add(vo);
         }
 
@@ -786,4 +806,14 @@ public class TianpanService {
     private String getDayElementDetail(Date date) {
         return "甲木参天";
     }
+
+    private String findZodiacName(String zodiacCode) {
+        if (zodiacCode == null) return null;
+        Map<String, String> nameMap = new LinkedHashMap<>();
+        nameMap.put("rat", "鼠"); nameMap.put("ox", "牛"); nameMap.put("tiger", "虎");
+        nameMap.put("rabbit", "兔"); nameMap.put("dragon", "龙"); nameMap.put("snake", "蛇");
+        nameMap.put("horse", "马"); nameMap.put("sheep", "羊"); nameMap.put("monkey", "猴");
+        nameMap.put("rooster", "鸡"); nameMap.put("dog", "狗"); nameMap.put("pig", "猪");
+        return nameMap.get(zodiacCode);
+    }
 }