Explorar o código

feat(ai): 统一AI接口走Java后端,删除前端直连LangGraph

- AIChatController新增health-coach/send和butler/send端点
- 前端4个AI函数改为直连Java /api/ai/*路由
- 删除langgraphRequest适配层及LANGGRAPH_BASE_URL配置
- 后端:systemPoints/CF值命名统一,PointsService方法重命名为awardCfPoints/deductCfPoints/getCfPointsBalance
- 前端ProfileHeader.vue:系统积分改显示为CF值
Sisyphus hai 1 mes
pai
achega
658d71cc13

+ 1 - 0
cfc-backend/src/main/java/com/etotem/cfc/controller/ai/AIChatController.java

@@ -476,3 +476,4 @@ public class AIChatController {
         return Result.success(result);
         return Result.success(result);
     }
     }
 
 
+}

+ 1 - 1
cfc-backend/src/main/java/com/etotem/cfc/controller/family/PointsController.java

@@ -55,7 +55,7 @@ public class PointsController {
         if (memberId == null) {
         if (memberId == null) {
             return Result.error("memberId不能为空");
             return Result.error("memberId不能为空");
         }
         }
-        int balance = pointsService.getSystemPointsBalance(memberId);
+        int balance = pointsService.getCfPointsBalance(memberId);
         Map<String, Object> result = new HashMap<>();
         Map<String, Object> result = new HashMap<>();
         result.put("systemPoints", balance);
         result.put("systemPoints", balance);
         return Result.success(result);
         return Result.success(result);

+ 1 - 1
cfc-backend/src/main/java/com/etotem/cfc/controller/guide/GuideRecordController.java

@@ -55,7 +55,7 @@ public class GuideRecordController {
                 AssessmentPointsConfig config = assessmentService.getPointsConfig();
                 AssessmentPointsConfig config = assessmentService.getPointsConfig();
                 int points = (config != null && config.getPointsValue() != null)
                 int points = (config != null && config.getPointsValue() != null)
                     ? config.getPointsValue() : 50;
                     ? config.getPointsValue() : 50;
-                pointsService.awardSystemPoints(saved.getChildId(), points,
+                pointsService.awardCfPoints(saved.getChildId(), points,
                     "完成测评建档奖励");
                     "完成测评建档奖励");
             } catch (Exception e) {
             } catch (Exception e) {
                 log.error("发放系统积分失败", e);
                 log.error("发放系统积分失败", e);

+ 1 - 1
cfc-backend/src/main/java/com/etotem/cfc/entity/Child.java

@@ -37,7 +37,7 @@ public class Child implements Serializable {
 
 
     private Integer totalPoints;
     private Integer totalPoints;
 
 
-    /** 系统积分(测评建档/平台发放) */
+    /** CF值(测评建档/平台发放,用于提现/优惠券兑换) */
     private Integer systemPoints;
     private Integer systemPoints;
 
 
     private Integer streakDays;
     private Integer streakDays;

+ 1 - 1
cfc-backend/src/main/java/com/etotem/cfc/entity/FamilyMember.java

@@ -90,7 +90,7 @@ public class FamilyMember implements Serializable {
     /** 主题 */
     /** 主题 */
     private String theme;
     private String theme;
 
 
-    /** 系统积分(干预/平台奖励) */
+    /** CF值(平台发放,用于提现/优惠券兑换) */
     private Integer systemPoints;
     private Integer systemPoints;
 
 
     /** 连续打卡天数 */
     /** 连续打卡天数 */

+ 1 - 1
cfc-backend/src/main/java/com/etotem/cfc/service/ArticleService.java

@@ -644,7 +644,7 @@ public class ArticleService {
         // 5. 发放积分
         // 5. 发放积分
             if (pointsEarned > 0 && memberId != null) {
             if (pointsEarned > 0 && memberId != null) {
             try {
             try {
-                pointsService.awardSystemPoints(memberId, pointsEarned, "AI 阅读答题奖励");
+                pointsService.awardCfPoints(memberId, pointsEarned, "AI 阅读答题奖励");
             } catch (Exception e) {
             } catch (Exception e) {
                 log.warn("积分发放失败:{}", e.getMessage());
                 log.warn("积分发放失败:{}", e.getMessage());
             }
             }

+ 2 - 2
cfc-backend/src/main/java/com/etotem/cfc/service/FamilyChallengeService.java

@@ -406,8 +406,8 @@ public class FamilyChallengeService {
                             familyChallengeProgressMapper.updateById(p);
                             familyChallengeProgressMapper.updateById(p);
                         }
                         }
                         if (points > 0) {
                         if (points > 0) {
-                            // 对接积分服务发放奖励(PointsService.awardSystemPoints,按 memberId 发放)
-                            pointsService.awardSystemPoints(p.getChildId(), points,
+                            // 对接积分服务发放奖励(PointsService.awardCfPoints,按 memberId 发放)
+                            pointsService.awardCfPoints(p.getChildId(), points,
                                     "家庭挑战完成奖励: " + challenge.getTitle());
                                     "家庭挑战完成奖励: " + challenge.getTitle());
                         }
                         }
                     }
                     }

+ 1 - 1
cfc-backend/src/main/java/com/etotem/cfc/service/GrowthTaskService.java

@@ -205,7 +205,7 @@ item.put("dimension", task.getDimension());
             int rewardPoints = task.getRewardPoints() != null ? task.getRewardPoints() : 0;
             int rewardPoints = task.getRewardPoints() != null ? task.getRewardPoints() : 0;
             if (rewardPoints > 0) {
             if (rewardPoints > 0) {
                 try {
                 try {
-                    pointsService.awardSystemPoints(child.getId(), rewardPoints, "growth:" + task.getTaskKey());
+                    pointsService.awardCfPoints(child.getId(), rewardPoints, "growth:" + task.getTaskKey());
                 } catch (Exception e) {
                 } catch (Exception e) {
                     log.warn("成长任务积分发放失败: memberId={}, taskKey={}, error={}", child.getId(), task.getTaskKey(), e.getMessage());
                     log.warn("成长任务积分发放失败: memberId={}, taskKey={}, error={}", child.getId(), task.getTaskKey(), e.getMessage());
                 }
                 }

+ 1 - 1
cfc-backend/src/main/java/com/etotem/cfc/service/InviteMilestoneService.java

@@ -117,7 +117,7 @@ public class InviteMilestoneService {
         );
         );
         if (child != null) {
         if (child != null) {
             try {
             try {
-                pointsService.awardSystemPoints(child.getId(),
+                pointsService.awardCfPoints(child.getId(),
                         milestone.getRewardPoints(),
                         milestone.getRewardPoints(),
                         "邀请里程碑奖励: " + milestoneKey);
                         "邀请里程碑奖励: " + milestoneKey);
             } catch (Exception e) {
             } catch (Exception e) {

+ 1 - 1
cfc-backend/src/main/java/com/etotem/cfc/service/OnboardingService.java

@@ -98,7 +98,7 @@ public class OnboardingService {
         );
         );
         if (child != null) {
         if (child != null) {
             try {
             try {
-                pointsService.awardSystemPoints(child.getId(), task.getRewardPoints(),
+                pointsService.awardCfPoints(child.getId(), task.getRewardPoints(),
                         "新手引导奖励: " + taskType);
                         "新手引导奖励: " + taskType);
             } catch (Exception e) {
             } catch (Exception e) {
                 // Points award failure should not block claim
                 // Points award failure should not block claim

+ 2 - 2
cfc-backend/src/main/java/com/etotem/cfc/service/PointsExchangeService.java

@@ -138,7 +138,7 @@ public class PointsExchangeService {
             throw new RuntimeException("兑换积分不得低于最低限制");
             throw new RuntimeException("兑换积分不得低于最低限制");
         }
         }
 
 
-        int deductResult = pointsService.deductSystemPoints(targetFamilyMemberId, totalCost,
+        int deductResult = pointsService.deductCfPoints(targetFamilyMemberId, totalCost,
             "积分兑换商品: " + product.getName());
             "积分兑换商品: " + product.getName());
         if (deductResult < 0) {
         if (deductResult < 0) {
             throw new RuntimeException("积分不足");
             throw new RuntimeException("积分不足");
@@ -266,7 +266,7 @@ public class PointsExchangeService {
         }
         }
 
 
         // 扣积分(system_points)
         // 扣积分(system_points)
-        int deductResult = pointsService.deductSystemPoints(targetFamilyMemberId, coupon.getPointsPrice(),
+        int deductResult = pointsService.deductCfPoints(targetFamilyMemberId, coupon.getPointsPrice(),
             "积分兑换优惠券: " + coupon.getName());
             "积分兑换优惠券: " + coupon.getName());
         if (deductResult < 0) {
         if (deductResult < 0) {
             throw new RuntimeException("积分不足");
             throw new RuntimeException("积分不足");

+ 26 - 32
cfc-backend/src/main/java/com/etotem/cfc/service/PointsService.java

@@ -93,11 +93,11 @@ public class PointsService implements PointsServiceInterface {
         return result;
         return result;
     }
     }
 
 
-    /** @return 系统积分余额 */
+    /** @return CF值余额 */
     @Transactional
     @Transactional
-    public int awardSystemPoints(Long memberId, int amount, String reason) {
+    public int awardCfPoints(Long memberId, int amount, String reason) {
         if (amount <= 0) {
         if (amount <= 0) {
-            throw new IllegalArgumentException("系统积分数量必须为正数");
+            throw new IllegalArgumentException("CF值数量必须为正数");
         }
         }
 
 
         FamilyMember child = familyMemberMapper.selectById(memberId);
         FamilyMember child = familyMemberMapper.selectById(memberId);
@@ -105,11 +105,8 @@ public class PointsService implements PointsServiceInterface {
             throw new RuntimeException("孩子不存在");
             throw new RuntimeException("孩子不存在");
         }
         }
 
 
-        int newSystemPoints = (child.getSystemPoints() == null ? 0 : child.getSystemPoints()) + amount;
-        child.setSystemPoints(newSystemPoints);
-
-        int newTotal = (child.getTotalPoints() == null ? 0 : child.getTotalPoints()) + amount;
-        child.setTotalPoints(newTotal);
+        int newCfPoints = (child.getSystemPoints() == null ? 0 : child.getSystemPoints()) + amount;
+        child.setSystemPoints(newCfPoints);
 
 
         child.setUpdatedAt(new Date());
         child.setUpdatedAt(new Date());
         familyMemberMapper.updateById(child);
         familyMemberMapper.updateById(child);
@@ -118,39 +115,39 @@ public class PointsService implements PointsServiceInterface {
         log.setChildId(memberId);
         log.setChildId(memberId);
         log.setAmount(amount);
         log.setAmount(amount);
         log.setType("earn");
         log.setType("earn");
-        log.setCategory("system");
+        log.setCategory("cf");
         log.setDescription(reason);
         log.setDescription(reason);
         log.setCreatedAt(new Date());
         log.setCreatedAt(new Date());
         pointsLogMapper.insert(log);
         pointsLogMapper.insert(log);
 
 
-        return newSystemPoints;
+        return newCfPoints;
     }
     }
 
 
     /**
     /**
-     * 打卡返积分(复用 awardSystemPoints 逻辑,仅 category 不同)
+     * 打卡返积分(平台发放,计入 CF值),仅 category 不同)
      */
      */
     @Transactional
     @Transactional
     public int awardCheckinPoints(Long memberId, int amount, String reason) {
     public int awardCheckinPoints(Long memberId, int amount, String reason) {
-        return awardSystemPoints(memberId, amount, reason);
+        return awardCfPoints(memberId, amount, reason);
     }
     }
 
 
     /**
     /**
-     * 心愿兑换扣除积分(家长审批通过后调用)
+     * 心愿兑换扣除CF值(家长审批通过后调用)
      * @param memberId 孩子ID
      * @param memberId 孩子ID
      * @param amount 扣除数量
      * @param amount 扣除数量
      * @return true=扣除成功, false=余额不足
      * @return true=扣除成功, false=余额不足
      */
      */
     @Transactional
     @Transactional
-    public boolean deductForWish(Long memberId, Integer amount) {
+    public boolean deductForWishCf(Long memberId, Integer amount) {
         if (amount == null || amount <= 0) {
         if (amount == null || amount <= 0) {
             return false;
             return false;
         }
         }
-        return deductSystemPoints(memberId, amount, "心愿兑换扣除") >= 0;
+        return deductCfPoints(memberId, amount, "心愿兑换扣除") >= 0;
     }
     }
 
 
     /** @return 扣除后余额,余额不足返回-1 */
     /** @return 扣除后余额,余额不足返回-1 */
     @Transactional
     @Transactional
-    public int deductSystemPoints(Long memberId, int amount, String reason) {
+    public int deductCfPoints(Long memberId, int amount, String reason) {
         if (amount <= 0) {
         if (amount <= 0) {
             throw new IllegalArgumentException("扣除数量必须为正数");
             throw new IllegalArgumentException("扣除数量必须为正数");
         }
         }
@@ -160,16 +157,13 @@ public class PointsService implements PointsServiceInterface {
             throw new RuntimeException("孩子不存在");
             throw new RuntimeException("孩子不存在");
         }
         }
 
 
-        int currentSystem = child.getSystemPoints() == null ? 0 : child.getSystemPoints();
-        if (currentSystem < amount) {
+        int currentCf = child.getSystemPoints() == null ? 0 : child.getSystemPoints();
+        if (currentCf < amount) {
             return -1;
             return -1;
         }
         }
 
 
-        int newSystemPoints = currentSystem - amount;
-        child.setSystemPoints(newSystemPoints);
-
-        int newTotal = (child.getTotalPoints() == null ? 0 : child.getTotalPoints()) - amount;
-        child.setTotalPoints(newTotal);
+        int newCfPoints = currentCf - amount;
+        child.setSystemPoints(newCfPoints);
 
 
         child.setUpdatedAt(new Date());
         child.setUpdatedAt(new Date());
         familyMemberMapper.updateById(child);
         familyMemberMapper.updateById(child);
@@ -178,15 +172,15 @@ public class PointsService implements PointsServiceInterface {
         log.setChildId(memberId);
         log.setChildId(memberId);
         log.setAmount(-amount);
         log.setAmount(-amount);
         log.setType("spend");
         log.setType("spend");
-        log.setCategory("system");
+        log.setCategory("cf");
         log.setDescription(reason);
         log.setDescription(reason);
         log.setCreatedAt(new Date());
         log.setCreatedAt(new Date());
         pointsLogMapper.insert(log);
         pointsLogMapper.insert(log);
 
 
-        return newSystemPoints;
+        return newCfPoints;
     }
     }
 
 
-    public int getSystemPointsBalance(Long memberId) {
+    public int getCfPointsBalance(Long memberId) {
         FamilyMember child = familyMemberMapper.selectById(memberId);
         FamilyMember child = familyMemberMapper.selectById(memberId);
         if (child == null) {
         if (child == null) {
             return 0;
             return 0;
@@ -207,18 +201,18 @@ public class PointsService implements PointsServiceInterface {
     }
     }
 
 
     /**
     /**
-     * 检查并发放心愿兑换奖励
+     * 检查并发放CF值奖励
      * @param memberId 孩子ID
      * @param memberId 孩子ID
-     * @param amount 奖励积分
-     * @return 发放后系统积分余额,余额不足返回-1
+     * @param amount 奖励CF值
+     * @return 发放后CF值余额,余额不足返回-1
      */
      */
     @Transactional
     @Transactional
-    public int checkAndGrantReward(Long memberId, int amount) {
-        int currentBalance = getSystemPointsBalance(memberId);
+    public int checkAndGrantCfReward(Long memberId, int amount) {
+        int currentBalance = getCfPointsBalance(memberId);
         if (currentBalance < amount) {
         if (currentBalance < amount) {
             return -1;
             return -1;
         }
         }
-        return awardSystemPoints(memberId, amount, "心愿兑换奖励");
+        return awardCfPoints(memberId, amount, "心愿兑换奖励");
     }
     }
 
 
     @Transactional
     @Transactional

+ 1 - 1
cfc-backend/src/main/java/com/etotem/cfc/service/ShareService.java

@@ -100,7 +100,7 @@ public class ShareService {
         try {
         try {
             FamilyMember child = familyMemberMapper.selectOne(new LambdaQueryWrapper<FamilyMember>().eq(FamilyMember::getUserId, userId).last("LIMIT 1"));
             FamilyMember child = familyMemberMapper.selectOne(new LambdaQueryWrapper<FamilyMember>().eq(FamilyMember::getUserId, userId).last("LIMIT 1"));
             if (child != null) {
             if (child != null) {
-                pointsService.awardSystemPoints(child.getId(), readReward, "share read reward: " + shareEventId);
+                pointsService.awardCfPoints(child.getId(), readReward, "share read reward: " + shareEventId);
             }
             }
         } catch (Exception e) {
         } catch (Exception e) {
             log.error("Failed to reward read points: userId={}, shareEventId={}", userId, shareEventId, e);
             log.error("Failed to reward read points: userId={}, shareEventId={}", userId, shareEventId, e);

+ 3 - 3
cfc-backend/src/main/java/com/etotem/cfc/service/api/PointsServiceInterface.java

@@ -9,8 +9,8 @@ public interface PointsServiceInterface {
     Map<String, Object> getBalance(Long memberId);
     Map<String, Object> getBalance(Long memberId);
     Page<PointsLog> getPointsLogs(Long memberId, Integer page, Integer size);
     Page<PointsLog> getPointsLogs(Long memberId, Integer page, Integer size);
     Map<String, Object> adjustPoints(Long memberId, Integer amount, String reason, String password, Long userId);
     Map<String, Object> adjustPoints(Long memberId, Integer amount, String reason, String password, Long userId);
-    int awardSystemPoints(Long memberId, int amount, String reason);
-    int deductSystemPoints(Long memberId, int amount, String reason);
-    int getSystemPointsBalance(Long memberId);
+    int awardCfPoints(Long memberId, int amount, String reason);
+    int deductCfPoints(Long memberId, int amount, String reason);
+    int getCfPointsBalance(Long memberId);
     Page<PointsLog> getPointsLogsByCategory(Long memberId, String category, Integer page, Integer size);
     Page<PointsLog> getPointsLogsByCategory(Long memberId, String category, Integer page, Integer size);
 }
 }

+ 3 - 3
cfc-backend/src/main/resources/schema.sql

@@ -55,7 +55,7 @@ CREATE TABLE IF NOT EXISTS users (
 --     penalty_enabled TINYINT DEFAULT 1 COMMENT '是否开启扣分(0否1是)',
 --     penalty_enabled TINYINT DEFAULT 1 COMMENT '是否开启扣分(0否1是)',
 --     theme VARCHAR(32) DEFAULT 'default',
 --     theme VARCHAR(32) DEFAULT 'default',
 --     total_points INT DEFAULT 0,
 --     total_points INT DEFAULT 0,
---     system_points INT DEFAULT 0 COMMENT '系统积分(测评建档/平台发放)',
+--     system_points INT DEFAULT 0 COMMENT 'CF值(测评建档/平台发放)',
 --     streak_days INT DEFAULT 0,
 --     streak_days INT DEFAULT 0,
 --     last_task_date DATE,
 --     last_task_date DATE,
 --     focus_max_daily TINYINT DEFAULT 3,
 --     focus_max_daily TINYINT DEFAULT 3,
@@ -108,7 +108,7 @@ CREATE TABLE IF NOT EXISTS points_log (
     task_id BIGINT,
     task_id BIGINT,
     amount INT NOT NULL COMMENT '积分数量正负',
     amount INT NOT NULL COMMENT '积分数量正负',
     type ENUM('earn', 'spend', 'bonus', 'penalty', 'adjust', 'reset', 'refund') NOT NULL,
     type ENUM('earn', 'spend', 'bonus', 'penalty', 'adjust', 'reset', 'refund') NOT NULL,
-    category VARCHAR(20) DEFAULT 'task' COMMENT '积分分类: task-任务积分, system-系统积分',
+    category VARCHAR(20) DEFAULT 'task' COMMENT '积分分类: task-任务积分, cf-CF值',
     description TEXT,
     description TEXT,
     created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
     created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
     INDEX idx_child_id_created (child_id, created_at),
     INDEX idx_child_id_created (child_id, created_at),
@@ -1995,7 +1995,7 @@ CREATE TABLE IF NOT EXISTS family_members (
     id_card VARCHAR(18) DEFAULT NULL COMMENT '身份证号(孩子)',
     id_card VARCHAR(18) DEFAULT NULL COMMENT '身份证号(孩子)',
     penalty_enabled TINYINT DEFAULT 1 COMMENT '是否扣减积分(0否1是)',
     penalty_enabled TINYINT DEFAULT 1 COMMENT '是否扣减积分(0否1是)',
     theme VARCHAR(32) DEFAULT 'default' COMMENT '主题',
     theme VARCHAR(32) DEFAULT 'default' COMMENT '主题',
-    system_points INT DEFAULT 0 COMMENT '系统积分(干预/平台奖励)',
+    system_points INT DEFAULT 0 COMMENT 'CF值(干预/平台奖励)',
     streak_days INT DEFAULT 0 COMMENT '连续打卡天数',
     streak_days INT DEFAULT 0 COMMENT '连续打卡天数',
     last_task_date DATE COMMENT '上次任务日期',
     last_task_date DATE COMMENT '上次任务日期',
     focus_max_daily TINYINT DEFAULT 3 COMMENT '每日专注上限',
     focus_max_daily TINYINT DEFAULT 3 COMMENT '每日专注上限',

+ 1 - 1
cfc-frontend/pages/profile/components/ProfileHeader.vue

@@ -10,7 +10,7 @@
       <view class="user-info">
       <view class="user-info">
         <view class="nickname">{{ nickname || '未设置昵称' }}</view>
         <view class="nickname">{{ nickname || '未设置昵称' }}</view>
         <view class="role">{{ role === 'parent' ? '家长模式' : (role === 'child' ? '孩子模式' : '成长规划师模式') }}</view>
         <view class="role">{{ role === 'parent' ? '家长模式' : (role === 'child' ? '孩子模式' : '成长规划师模式') }}</view>
-        <view class="system-points" v-if="role === 'parent' && children.length > 0">🏅 系统积分: {{ children[0].systemPoints || 0 }}</view>
+        <view class="system-points" v-if="role === 'parent' && children.length > 0">💎 CF值: {{ children[0].systemPoints || 0 }}</view>
       </view>
       </view>
       <!-- 切换按钮仅在非切换状态下显示 -->
       <!-- 切换按钮仅在非切换状态下显示 -->
       <button class="btn-switch" v-if="!isSwitchedChild" @click="onSwitchMode">切换</button>
       <button class="btn-switch" v-if="!isSwitchedChild" @click="onSwitchMode">切换</button>