Эх сурвалжийг харах

feat: 法律合规补全 - 隐私政策/用户协议/同意记录/注销/数据授权/日志脱敏

- 隐私政策重写:13章覆盖敏感信息/儿童数据/AI/第三方共享/跨境传输
- 用户协议重写:13章覆盖付费/退款/服务商/免责/争议解决
- 新增服务商入驻协议
- 后端:user_consent_records 表 + ConsentController(4接口)
- 后端:user_data_permissions 表 + DataPermissionController(2接口)
- 后端:账号注销匿名化 + 数据导出接口
- 后端:DataMaskUtil 日志脱敏工具
- 后端:DataCleanupTask 每日2点清理定时任务
- 前端:添加<14岁儿童时监护人同意弹窗
- 前端:API 层新增 consent/data-permission 调用
- 迁移168/169 + schema.sql 同步
Xiaogang Liao 2 сар өмнө
parent
commit
381ae83210
20 өөрчлөгдсөн 1458 нэмэгдсэн , 61 устгасан
  1. 40 0
      cfc-backend/src/main/java/com/etotem/cfc/common/DataMaskUtil.java
  2. 37 0
      cfc-backend/src/main/java/com/etotem/cfc/config/DatabaseInitializer.java
  3. 91 0
      cfc-backend/src/main/java/com/etotem/cfc/controller/ConsentController.java
  4. 60 0
      cfc-backend/src/main/java/com/etotem/cfc/controller/DataPermissionController.java
  5. 29 0
      cfc-backend/src/main/java/com/etotem/cfc/controller/UserController.java
  6. 40 0
      cfc-backend/src/main/java/com/etotem/cfc/entity/UserConsentRecord.java
  7. 45 0
      cfc-backend/src/main/java/com/etotem/cfc/entity/UserDataPermission.java
  8. 7 0
      cfc-backend/src/main/java/com/etotem/cfc/mapper/UserConsentRecordMapper.java
  9. 7 0
      cfc-backend/src/main/java/com/etotem/cfc/mapper/UserDataPermissionMapper.java
  10. 195 0
      cfc-backend/src/main/java/com/etotem/cfc/service/AccountCleanupService.java
  11. 114 0
      cfc-backend/src/main/java/com/etotem/cfc/service/ConsentService.java
  12. 99 0
      cfc-backend/src/main/java/com/etotem/cfc/service/DataPermissionService.java
  13. 68 0
      cfc-backend/src/main/java/com/etotem/cfc/task/DataCleanupTask.java
  14. 27 0
      cfc-backend/src/main/resources/schema.sql
  15. 6 0
      cfc-frontend/pages.json
  16. 127 3
      cfc-frontend/pages/family/add-member.vue
  17. 111 19
      cfc-frontend/pages/policy/agreement.vue
  18. 132 39
      cfc-frontend/pages/policy/privacy.vue
  19. 204 0
      cfc-frontend/pages/policy/provider-agreement.vue
  20. 19 0
      cfc-frontend/utils/api.js

+ 40 - 0
cfc-backend/src/main/java/com/etotem/cfc/common/DataMaskUtil.java

@@ -0,0 +1,40 @@
+package com.etotem.cfc.common;
+
+/**
+ * 数据脱敏工具类,用于日志和展示中对敏感信息进行脱敏处理。
+ * 遵循最小化原则,仅保留必要的标识信息。
+ */
+public class DataMaskUtil {
+
+    /** 身份证号:显示前3位和后4位,中间用*替代 */
+    public static String maskIdCard(String idCard) {
+        if (idCard == null || idCard.length() < 8) return idCard;
+        return idCard.substring(0, 3) + "********" + idCard.substring(idCard.length() - 4);
+    }
+
+    /** 手机号:显示前3位和后4位 */
+    public static String maskPhone(String phone) {
+        if (phone == null || phone.length() < 7) return phone;
+        return phone.substring(0, 3) + "****" + phone.substring(phone.length() - 4);
+    }
+
+    /** 姓名:显示姓氏,名用"某"替代 */
+    public static String maskName(String name) {
+        if (name == null || name.length() < 2) return name;
+        return name.substring(0, 1) + "某";
+    }
+
+    /** 地址:保留前10个字符,超出部分用...替代 */
+    public static String maskAddress(String address) {
+        if (address == null || address.length() <= 10) return address;
+        return address.substring(0, 10) + "...";
+    }
+
+    /** 邮箱:显示前3个字符和@后的域名 */
+    public static String maskEmail(String email) {
+        if (email == null || !email.contains("@")) return email;
+        String[] parts = email.split("@");
+        if (parts[0].length() <= 3) return parts[0].charAt(0) + "***@" + parts[1];
+        return parts[0].substring(0, 3) + "***@" + parts[1];
+    }
+}

+ 37 - 0
cfc-backend/src/main/java/com/etotem/cfc/config/DatabaseInitializer.java

@@ -7923,5 +7923,42 @@ private void runMigration100() {
 		} catch (Exception ex) {
 			log.warn("插入membership_benefits种子数据失败: {}", ex.getMessage());
 		}
+
+		// 迁移168: 创建用户同意记录表(法律合规)
+		try {
+			jdbcTemplate.execute("CREATE TABLE IF NOT EXISTS user_consent_records (" +
+				"id BIGINT AUTO_INCREMENT PRIMARY KEY, " +
+				"user_id BIGINT NOT NULL COMMENT '用户ID', " +
+				"consent_type VARCHAR(50) NOT NULL COMMENT '同意类型: privacy/agreement/children_data/ai_processing', " +
+				"version VARCHAR(20) NOT NULL COMMENT '协议版本号', " +
+				"status VARCHAR(20) NOT NULL DEFAULT 'agreed' COMMENT 'agreed/withdrawn/archived', " +
+				"ip_address VARCHAR(45) COMMENT '用户IP地址', " +
+				"created_at DATETIME NOT NULL, " +
+				"updated_at DATETIME, " +
+				"INDEX idx_user_consent (user_id, consent_type), " +
+				"INDEX idx_consent_type (consent_type)" +
+				") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户同意记录'");
+			log.info("已创建user_consent_records表");
+		} catch (Exception e) {
+			log.warn("创建user_consent_records表失败(可能已存在): " + e.getMessage());
+		}
+
+		// 迁移169: 创建用户数据授权表(法律合规)
+		try {
+			jdbcTemplate.execute("CREATE TABLE IF NOT EXISTS user_data_permissions (" +
+				"id BIGINT AUTO_INCREMENT PRIMARY KEY, " +
+				"user_id BIGINT NOT NULL COMMENT '用户ID', " +
+				"allow_ai_analysis TINYINT(1) DEFAULT 0 COMMENT '允许AI分析对话数据', " +
+				"allow_personalized_recommend TINYINT(1) DEFAULT 1 COMMENT '允许个性化推荐', " +
+				"allow_share_teacher TINYINT(1) DEFAULT 1 COMMENT '允许向成长规划师共享数据', " +
+				"allow_third_party_share TINYINT(1) DEFAULT 0 COMMENT '允许与第三方共享数据', " +
+				"created_at DATETIME NOT NULL, " +
+				"updated_at DATETIME, " +
+				"INDEX idx_user_perm (user_id)" +
+				") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户数据使用授权'");
+			log.info("已创建user_data_permissions表");
+		} catch (Exception e) {
+			log.warn("创建user_data_permissions表失败(可能已存在): " + e.getMessage());
+		}
 	}
 }

+ 91 - 0
cfc-backend/src/main/java/com/etotem/cfc/controller/ConsentController.java

@@ -0,0 +1,91 @@
+package com.etotem.cfc.controller;
+
+import com.etotem.cfc.common.Result;
+import com.etotem.cfc.service.ConsentService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.Map;
+
+/**
+ * 用户同意记录管理
+ * 记录用户对隐私政策、用户协议、儿童数据处理、AI数据处理等事项的同意和撤回。
+ */
+@Tag(name = "用户同意管理", description = "用户协议同意/撤回记录")
+@RestController
+@RequestMapping("/api/consent")
+public class ConsentController {
+
+    @Resource
+    private ConsentService consentService;
+
+    @Operation(summary = "记录用户同意")
+    @PostMapping("/record")
+    public Result<Boolean> recordConsent(@RequestBody Map<String, Object> params,
+                                          @RequestAttribute("userId") Long userId,
+                                          HttpServletRequest request) {
+        if (userId == null) {
+            return Result.error("用户未登录");
+        }
+
+        String consentType = params.get("consentType") != null ? params.get("consentType").toString() : null;
+        String version = params.get("version") != null ? params.get("version").toString() : null;
+
+        if (consentType == null || version == null) {
+            return Result.error("consentType和version不能为空");
+        }
+
+        String ipAddress = request.getRemoteAddr();
+        consentService.recordConsent(userId, consentType, version, ipAddress);
+        return Result.success(true);
+    }
+
+    @Operation(summary = "撤回同意")
+    @PostMapping("/withdraw")
+    public Result<Boolean> withdrawConsent(@RequestBody Map<String, Object> params,
+                                            @RequestAttribute("userId") Long userId) {
+        if (userId == null) {
+            return Result.error("用户未登录");
+        }
+
+        String consentType = params.get("consentType") != null ? params.get("consentType").toString() : null;
+        if (consentType == null) {
+            return Result.error("consentType不能为空");
+        }
+
+        consentService.withdrawConsent(userId, consentType);
+        return Result.success(true);
+    }
+
+    @Operation(summary = "查询用户同意记录")
+    @PostMapping("/status")
+    public Result<Map<String, Object>> getConsentStatus(@RequestAttribute("userId") Long userId) {
+        if (userId == null) {
+            return Result.error("用户未登录");
+        }
+
+        return Result.success(consentService.getConsentStatus(userId));
+    }
+
+    @Operation(summary = "检查是否已同意")
+    @PostMapping("/check")
+    public Result<Boolean> checkConsent(@RequestBody Map<String, Object> params,
+                                         @RequestAttribute("userId") Long userId) {
+        if (userId == null) {
+            return Result.error("用户未登录");
+        }
+
+        String consentType = params.get("consentType") != null ? params.get("consentType").toString() : null;
+        String version = params.get("version") != null ? params.get("version").toString() : null;
+
+        if (consentType == null || version == null) {
+            return Result.error("consentType和version不能为空");
+        }
+
+        boolean consented = consentService.hasConsented(userId, consentType, version);
+        return Result.success(consented);
+    }
+}

+ 60 - 0
cfc-backend/src/main/java/com/etotem/cfc/controller/DataPermissionController.java

@@ -0,0 +1,60 @@
+package com.etotem.cfc.controller;
+
+import com.etotem.cfc.common.Result;
+import com.etotem.cfc.entity.UserDataPermission;
+import com.etotem.cfc.service.DataPermissionService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import java.util.Map;
+
+/**
+ * 用户数据使用授权管理
+ * 用户可控制数据在AI分析、个性化推荐、规划师共享、第三方共享等方面的使用授权。
+ */
+@Tag(name = "数据授权管理", description = "用户数据使用授权设置")
+@RestController
+@RequestMapping("/api/data-permission")
+public class DataPermissionController {
+
+    @Resource
+    private DataPermissionService dataPermissionService;
+
+    @Operation(summary = "获取数据授权设置")
+    @PostMapping("/get")
+    public Result<UserDataPermission> getPermission(@RequestAttribute("userId") Long userId) {
+        if (userId == null) {
+            return Result.error("用户未登录");
+        }
+
+        return Result.success(dataPermissionService.getPermission(userId));
+    }
+
+    @Operation(summary = "更新数据授权设置")
+    @PostMapping("/update")
+    public Result<Boolean> updatePermission(@RequestBody Map<String, Object> params,
+                                             @RequestAttribute("userId") Long userId) {
+        if (userId == null) {
+            return Result.error("用户未登录");
+        }
+
+        Map<String, Boolean> permissionMap = new java.util.HashMap<>();
+        if (params.containsKey("allowAiAnalysis")) {
+            permissionMap.put("allowAiAnalysis", Boolean.valueOf(params.get("allowAiAnalysis").toString()));
+        }
+        if (params.containsKey("allowPersonalizedRecommend")) {
+            permissionMap.put("allowPersonalizedRecommend", Boolean.valueOf(params.get("allowPersonalizedRecommend").toString()));
+        }
+        if (params.containsKey("allowShareTeacher")) {
+            permissionMap.put("allowShareTeacher", Boolean.valueOf(params.get("allowShareTeacher").toString()));
+        }
+        if (params.containsKey("allowThirdPartyShare")) {
+            permissionMap.put("allowThirdPartyShare", Boolean.valueOf(params.get("allowThirdPartyShare").toString()));
+        }
+
+        dataPermissionService.updatePermission(userId, permissionMap);
+        return Result.success(true);
+    }
+}

+ 29 - 0
cfc-backend/src/main/java/com/etotem/cfc/controller/UserController.java

@@ -56,6 +56,9 @@ public class UserController {
     @Resource
     private com.etotem.cfc.service.OnboardingService onboardingService;
 
+    @Resource
+    private com.etotem.cfc.service.AccountCleanupService accountCleanupService;
+
     @PostMapping("/children/list")
     @Operation(summary = "获取子女列表")
     public Result<List<FamilyMemberInfoDTO>> getFamilyMemberren(HttpServletRequest request) {
@@ -210,4 +213,30 @@ public class UserController {
 
         return Result.success(stats);
     }
+
+    /**
+     * 注销账号(数据匿名化处理)
+     */
+    @PostMapping("/deactivate")
+    @Operation(summary = "注销账号")
+    public Result<Map<String, Object>> deactivateAccount(HttpServletRequest request) {
+        Long userId = (Long) request.getAttribute("userId");
+        if (userId == null) {
+            return Result.error("用户未登录");
+        }
+        return Result.success(accountCleanupService.deactivateAccount(userId));
+    }
+
+    /**
+     * 导出用户数据(个保法数据可携带权)
+     */
+    @PostMapping("/data-export")
+    @Operation(summary = "导出用户数据")
+    public Result<Map<String, Object>> exportUserData(HttpServletRequest request) {
+        Long userId = (Long) request.getAttribute("userId");
+        if (userId == null) {
+            return Result.error("用户未登录");
+        }
+        return Result.success(accountCleanupService.exportUserData(userId));
+    }
 }

+ 40 - 0
cfc-backend/src/main/java/com/etotem/cfc/entity/UserConsentRecord.java

@@ -0,0 +1,40 @@
+package com.etotem.cfc.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 用户同意记录
+ * 记录用户对隐私政策、用户协议、儿童数据处理、AI数据处理等事项的同意/撤回记录。
+ */
+@Data
+@TableName("user_consent_records")
+public class UserConsentRecord implements Serializable {
+
+    @TableId(type = IdType.AUTO)
+    private Long id;
+
+    /** 用户ID */
+    private Long userId;
+
+    /** 同意类型: privacy/agreement/children_data/ai_processing */
+    private String consentType;
+
+    /** 协议版本号,如 "2026-08-v1" */
+    private String version;
+
+    /** 状态: agreed/withdrawn/archived */
+    private String status;
+
+    /** 用户IP地址 */
+    private String ipAddress;
+
+    private Date createdAt;
+
+    private Date updatedAt;
+}

+ 45 - 0
cfc-backend/src/main/java/com/etotem/cfc/entity/UserDataPermission.java

@@ -0,0 +1,45 @@
+package com.etotem.cfc.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 用户数据使用授权
+ * 用户可控制其数据在AI分析、个性化推荐、共享给规划师、共享给第三方等方面的使用授权。
+ */
+@Data
+@TableName("user_data_permissions")
+public class UserDataPermission implements Serializable {
+
+    @TableId(type = IdType.AUTO)
+    private Long id;
+
+    /** 用户ID */
+    private Long userId;
+
+    /** 允许AI分析对话数据(默认关闭) */
+    @TableField("allow_ai_analysis")
+    private Boolean allowAiAnalysis;
+
+    /** 允许个性化推荐(默认开启) */
+    @TableField("allow_personalized_recommend")
+    private Boolean allowPersonalizedRecommend;
+
+    /** 允许向成长规划师共享数据(默认开启) */
+    @TableField("allow_share_teacher")
+    private Boolean allowShareTeacher;
+
+    /** 允许与第三方共享数据(默认关闭) */
+    @TableField("allow_third_party_share")
+    private Boolean allowThirdPartyShare;
+
+    private Date createdAt;
+
+    private Date updatedAt;
+}

+ 7 - 0
cfc-backend/src/main/java/com/etotem/cfc/mapper/UserConsentRecordMapper.java

@@ -0,0 +1,7 @@
+package com.etotem.cfc.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.etotem.cfc.entity.UserConsentRecord;
+
+public interface UserConsentRecordMapper extends BaseMapper<UserConsentRecord> {
+}

+ 7 - 0
cfc-backend/src/main/java/com/etotem/cfc/mapper/UserDataPermissionMapper.java

@@ -0,0 +1,7 @@
+package com.etotem.cfc.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.etotem.cfc.entity.UserDataPermission;
+
+public interface UserDataPermissionMapper extends BaseMapper<UserDataPermission> {
+}

+ 195 - 0
cfc-backend/src/main/java/com/etotem/cfc/service/AccountCleanupService.java

@@ -0,0 +1,195 @@
+package com.etotem.cfc.service;
+
+import com.etotem.cfc.entity.*;
+import com.etotem.cfc.mapper.*;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.DigestUtils;
+
+import javax.annotation.Resource;
+import java.nio.charset.StandardCharsets;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 账号清理服务
+ * 处理账号注销时的数据匿名化和数据导出。
+ */
+@Slf4j
+@Service
+public class AccountCleanupService {
+
+    @Resource
+    private UserMapper userMapper;
+
+    @Resource
+    private ChildMapper childMapper;
+
+    @Resource
+    private DanAssessmentResultMapper danAssessmentResultMapper;
+
+    @Resource
+    private HealthReportMapper healthReportMapper;
+
+    @Resource
+    private ChatMessageMapper chatMessageMapper;
+
+    @Resource
+    private FamilyMemberMapper familyMemberMapper;
+
+    @Resource
+    private AssessmentOrderMapper assessmentOrderMapper;
+
+    @Resource
+    private PaymentOrderMapper paymentOrderMapper;
+
+    @Resource
+    private TaskMapper taskMapper;
+
+    /**
+     * 注销账号:检查未完成订单后,对用户数据进行匿名化处理
+     */
+    @Transactional
+    public Map<String, Object> deactivateAccount(Long userId) {
+        Map<String, Object> result = new HashMap<>();
+
+        // 1. 查询用户
+        User user = userMapper.selectById(userId);
+        if (user == null) {
+            result.put("canDeactivate", false);
+            result.put("message", "用户不存在");
+            return result;
+        }
+
+        // 2. 检查是否有未完成订单
+        if (user.getFamilyId() != null) {
+            long pendingOrderCount = paymentOrderMapper.selectCount(
+                    new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<PaymentOrder>()
+                            .eq(PaymentOrder::getFamilyId, user.getFamilyId())
+                            .eq(PaymentOrder::getStatus, "pending")
+            );
+            if (pendingOrderCount > 0) {
+                result.put("canDeactivate", false);
+                result.put("message", "您有未完成的订单,请先处理后再注销账号");
+                return result;
+            }
+        }
+
+        long pendingAssessmentCount = assessmentOrderMapper.selectCount(
+                new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<AssessmentOrder>()
+                        .eq(AssessmentOrder::getUserId, userId)
+                        .eq(AssessmentOrder::getStatus, "pending")
+        );
+        if (pendingAssessmentCount > 0) {
+            result.put("canDeactivate", false);
+            result.put("message", "您有未完成的测评,请先处理后再注销账号");
+            return result;
+        }
+
+        // 3. 匿名化用户数据
+        if (user == null) {
+            result.put("canDeactivate", false);
+            result.put("message", "用户不存在");
+            return result;
+        }
+
+        // 匿名化主账号
+        String hashedOpenid = DigestUtils.md5DigestAsHex(
+                (user.getOpenid() + "_deleted_" + System.currentTimeMillis()).getBytes(StandardCharsets.UTF_8)
+        );
+        user.setRealName("");
+        user.setIdCard("");
+        user.setPhone("");
+        user.setOpenid(hashedOpenid);
+        user.setUnionid("");
+        user.setNickname("已注销用户");
+        user.setAvatar("");
+        user.setAddress("");
+        user.setSessionKey("");
+        user.setBirthHour(null);
+        user.setDeleted(1);
+        user.setUpdatedAt(new Date());
+        userMapper.updateById(user);
+
+        // 3. 匿名化关联的FamilyMember记录
+        familyMemberMapper.selectList(
+                new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<FamilyMember>()
+                        .eq(FamilyMember::getUserId, userId)
+        ).forEach(member -> {
+            member.setNickname("已注销");
+            member.setPhone("");
+            member.setAvatar("");
+            member.setIdCard("");
+            familyMemberMapper.updateById(member);
+        });
+
+        // 4. 匿名化关联的ChatMessage记录
+        chatMessageMapper.selectList(
+                new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<ChatMessage>()
+        ).stream()
+        .filter(msg -> {
+            // 尝试解析inputsJson找到userId,或通过conversation关联
+            return msg.getInputsJson() != null && msg.getInputsJson().contains("\"" + userId + "\"");
+        })
+        .forEach(msg -> {
+            msg.setContent("[该用户已注销]");
+            chatMessageMapper.updateById(msg);
+        });
+
+        log.info("账号已注销并匿名化: userId={}", userId);
+        result.put("canDeactivate", true);
+        result.put("message", "账号已成功注销,相关数据已匿名化处理");
+        return result;
+    }
+
+    /**
+     * 导出用户数据
+     */
+    public Map<String, Object> exportUserData(Long userId) {
+        Map<String, Object> data = new HashMap<>();
+
+        // 用户基本信息
+        User user = userMapper.selectById(userId);
+        if (user == null) {
+            return data;
+        }
+        Map<String, Object> userInfo = new HashMap<>();
+        userInfo.put("nickname", user.getNickname());
+        userInfo.put("phone", user.getPhone());
+        userInfo.put("realName", user.getRealName());
+        userInfo.put("gender", user.getGender());
+        userInfo.put("birthday", user.getBirthday());
+        userInfo.put("familyRole", user.getFamilyRole());
+        userInfo.put("memberLevel", user.getMemberLevel());
+        data.put("userInfo", userInfo);
+
+        // 孩子信息
+        data.put("children", childMapper.selectList(
+                new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<Child>()
+                        .eq(Child::getUserId, userId)
+        ));
+
+        // 测评结果
+        data.put("assessmentResults", danAssessmentResultMapper.selectList(
+                new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<DanAssessmentResult>()
+                        .eq(DanAssessmentResult::getFamilyMemberId, userId)
+        ));
+
+        // 健康报告
+        data.put("healthReports", healthReportMapper.selectList(
+                new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<HealthReport>()
+                        .eq(HealthReport::getUserId, userId)
+        ));
+
+        // 任务记录
+        data.put("tasks", taskMapper.selectList(
+                new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<Task>()
+                        .eq(Task::getCreatorId, userId)
+        ));
+
+        log.info("用户数据导出: userId={}", userId);
+        return data;
+    }
+}

+ 114 - 0
cfc-backend/src/main/java/com/etotem/cfc/service/ConsentService.java

@@ -0,0 +1,114 @@
+package com.etotem.cfc.service;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.etotem.cfc.entity.UserConsentRecord;
+import com.etotem.cfc.mapper.UserConsentRecordMapper;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 用户同意记录服务
+ * 管理用户对隐私政策、用户协议、儿童数据处理、AI数据处理等事项的同意和撤回。
+ */
+@Slf4j
+@Service
+public class ConsentService {
+
+    @Resource
+    private UserConsentRecordMapper userConsentRecordMapper;
+
+    /**
+     * 记录用户同意
+     */
+    public void recordConsent(Long userId, String consentType, String version, String ipAddress) {
+        // 检查是否已有相同类型的同意记录
+        UserConsentRecord existing = userConsentRecordMapper.selectOne(
+                new LambdaQueryWrapper<UserConsentRecord>()
+                        .eq(UserConsentRecord::getUserId, userId)
+                        .eq(UserConsentRecord::getConsentType, consentType)
+                        .eq(UserConsentRecord::getStatus, "agreed")
+                        .last("LIMIT 1")
+        );
+
+        if (existing != null) {
+            // 更新版本号
+            existing.setVersion(version);
+            existing.setUpdatedAt(new Date());
+            userConsentRecordMapper.updateById(existing);
+            log.info("更新用户同意记录: userId={}, consentType={}, version={}", userId, consentType, version);
+            return;
+        }
+
+        // 新建同意记录
+        UserConsentRecord record = new UserConsentRecord();
+        record.setUserId(userId);
+        record.setConsentType(consentType);
+        record.setVersion(version);
+        record.setStatus("agreed");
+        record.setIpAddress(ipAddress);
+        record.setCreatedAt(new Date());
+        record.setUpdatedAt(new Date());
+        userConsentRecordMapper.insert(record);
+        log.info("记录用户同意: userId={}, consentType={}, version={}", userId, consentType, version);
+    }
+
+    /**
+     * 撤回同意
+     */
+    public void withdrawConsent(Long userId, String consentType) {
+        UserConsentRecord existing = userConsentRecordMapper.selectOne(
+                new LambdaQueryWrapper<UserConsentRecord>()
+                        .eq(UserConsentRecord::getUserId, userId)
+                        .eq(UserConsentRecord::getConsentType, consentType)
+                        .eq(UserConsentRecord::getStatus, "agreed")
+                        .last("LIMIT 1")
+        );
+
+        if (existing != null) {
+            existing.setStatus("withdrawn");
+            existing.setUpdatedAt(new Date());
+            userConsentRecordMapper.updateById(existing);
+            log.info("用户撤回同意: userId={}, consentType={}", userId, consentType);
+        }
+    }
+
+    /**
+     * 查询用户所有同意记录
+     */
+    public Map<String, Object> getConsentStatus(Long userId) {
+        List<UserConsentRecord> records = userConsentRecordMapper.selectList(
+                new LambdaQueryWrapper<UserConsentRecord>()
+                        .eq(UserConsentRecord::getUserId, userId)
+                        .orderByDesc(UserConsentRecord::getCreatedAt)
+        );
+
+        Map<String, Object> result = new HashMap<>();
+        Map<String, Object> consentMap = new HashMap<>();
+        for (UserConsentRecord record : records) {
+            consentMap.put(record.getConsentType(), record);
+        }
+        result.put("consents", consentMap);
+        result.put("allRecords", records);
+        return result;
+    }
+
+    /**
+     * 检查用户是否已同意指定类型和版本
+     */
+    public boolean hasConsented(Long userId, String consentType, String version) {
+        UserConsentRecord record = userConsentRecordMapper.selectOne(
+                new LambdaQueryWrapper<UserConsentRecord>()
+                        .eq(UserConsentRecord::getUserId, userId)
+                        .eq(UserConsentRecord::getConsentType, consentType)
+                        .eq(UserConsentRecord::getStatus, "agreed")
+                        .last("LIMIT 1")
+        );
+        return record != null && record.getVersion().equals(version);
+    }
+}

+ 99 - 0
cfc-backend/src/main/java/com/etotem/cfc/service/DataPermissionService.java

@@ -0,0 +1,99 @@
+package com.etotem.cfc.service;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.etotem.cfc.entity.UserDataPermission;
+import com.etotem.cfc.mapper.UserDataPermissionMapper;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.Date;
+import java.util.Map;
+
+/**
+ * 用户数据使用授权服务
+ * 管理用户对数据使用的授权设置,包括AI分析、个性化推荐、规划师共享、第三方共享等。
+ */
+@Slf4j
+@Service
+public class DataPermissionService {
+
+    @Resource
+    private UserDataPermissionMapper userDataPermissionMapper;
+
+    /**
+     * 获取用户的数据授权设置,如不存在则创建默认设置
+     */
+    public UserDataPermission getPermission(Long userId) {
+        UserDataPermission permission = userDataPermissionMapper.selectOne(
+                new LambdaQueryWrapper<UserDataPermission>()
+                        .eq(UserDataPermission::getUserId, userId)
+                        .last("LIMIT 1")
+        );
+
+        if (permission == null) {
+            permission = createDefault(userId);
+        }
+
+        return permission;
+    }
+
+    /**
+     * 更新用户的数据授权设置
+     */
+    public void updatePermission(Long userId, Map<String, Boolean> params) {
+        UserDataPermission permission = userDataPermissionMapper.selectOne(
+                new LambdaQueryWrapper<UserDataPermission>()
+                        .eq(UserDataPermission::getUserId, userId)
+                        .last("LIMIT 1")
+        );
+
+        if (permission == null) {
+            permission = createDefault(userId);
+        }
+
+        if (params.containsKey("allowAiAnalysis")) {
+            permission.setAllowAiAnalysis(params.get("allowAiAnalysis"));
+        }
+        if (params.containsKey("allowPersonalizedRecommend")) {
+            permission.setAllowPersonalizedRecommend(params.get("allowPersonalizedRecommend"));
+        }
+        if (params.containsKey("allowShareTeacher")) {
+            permission.setAllowShareTeacher(params.get("allowShareTeacher"));
+        }
+        if (params.containsKey("allowThirdPartyShare")) {
+            permission.setAllowThirdPartyShare(params.get("allowThirdPartyShare"));
+        }
+
+        permission.setUpdatedAt(new Date());
+        userDataPermissionMapper.updateById(permission);
+        log.info("更新用户数据授权: userId={}, aiAnalysis={}, recommend={}, shareTeacher={}, thirdParty={}",
+                userId, permission.getAllowAiAnalysis(), permission.getAllowPersonalizedRecommend(),
+                permission.getAllowShareTeacher(), permission.getAllowThirdPartyShare());
+    }
+
+    /**
+     * 检查是否允许AI分析
+     */
+    public boolean canUseAiAnalysis(Long userId) {
+        UserDataPermission permission = getPermission(userId);
+        return permission.getAllowAiAnalysis() != null && permission.getAllowAiAnalysis();
+    }
+
+    /**
+     * 创建默认授权设置
+     */
+    private UserDataPermission createDefault(Long userId) {
+        UserDataPermission permission = new UserDataPermission();
+        permission.setUserId(userId);
+        permission.setAllowAiAnalysis(false);        // AI分析默认关闭
+        permission.setAllowPersonalizedRecommend(true); // 个性化推荐默认开启
+        permission.setAllowShareTeacher(true);        // 向规划师共享默认开启
+        permission.setAllowThirdPartyShare(false);     // 第三方共享默认关闭
+        permission.setCreatedAt(new Date());
+        permission.setUpdatedAt(new Date());
+        userDataPermissionMapper.insert(permission);
+        log.info("创建默认数据授权: userId={}", userId);
+        return permission;
+    }
+}

+ 68 - 0
cfc-backend/src/main/java/com/etotem/cfc/task/DataCleanupTask.java

@@ -0,0 +1,68 @@
+package com.etotem.cfc.task;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+
+/**
+ * 数据清理定时任务
+ * 每天凌晨2点执行,清理过期数据:已注销用户、旧的AI对话记录、旧的同意记录。
+ */
+@Slf4j
+@Component
+public class DataCleanupTask {
+
+    @Resource
+    private JdbcTemplate jdbcTemplate;
+
+    @Scheduled(cron = "0 0 2 * * ?")
+    public void cleanupExpiredData() {
+        log.info("数据清理任务开始");
+        cleanupDeactivatedUsers();
+        cleanupOldAiConversations();
+        archiveOldConsentRecords();
+        log.info("数据清理任务结束");
+    }
+
+    private void cleanupDeactivatedUsers() {
+        try {
+            int count = jdbcTemplate.update(
+                "DELETE FROM users WHERE deleted = 1 AND updated_at < DATE_SUB(NOW(), INTERVAL 180 DAY)"
+            );
+            if (count > 0) {
+                log.info("已清理 {} 条已注销用户数据", count);
+            }
+        } catch (Exception e) {
+            log.error("清理已注销用户数据异常", e);
+        }
+    }
+
+    private void cleanupOldAiConversations() {
+        try {
+            int count = jdbcTemplate.update(
+                "UPDATE ai_conversation_summary SET summary_text = '' WHERE created_at < DATE_SUB(NOW(), INTERVAL 1 YEAR)"
+            );
+            if (count > 0) {
+                log.info("已匿名化 {} 条AI对话记录", count);
+            }
+        } catch (Exception e) {
+            log.error("清理AI对话记录异常", e);
+        }
+    }
+
+    private void archiveOldConsentRecords() {
+        try {
+            int count = jdbcTemplate.update(
+                "UPDATE user_consent_records SET status = 'archived' WHERE created_at < DATE_SUB(NOW(), INTERVAL 3 YEAR)"
+            );
+            if (count > 0) {
+                log.info("已归档 {} 条同意记录", count);
+            }
+        } catch (Exception e) {
+            log.warn("归档同意记录跳过(表可能尚未创建): {}", e.getMessage());
+        }
+    }
+}

+ 27 - 0
cfc-backend/src/main/resources/schema.sql

@@ -4141,3 +4141,30 @@ CREATE TABLE IF NOT EXISTS family_join_requests (
     INDEX idx_target_family (target_family_id),
     INDEX idx_status (status)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='家庭加入请求(待审批)';
+
+-- 用户同意记录表
+CREATE TABLE IF NOT EXISTS user_consent_records (
+    id BIGINT AUTO_INCREMENT PRIMARY KEY,
+    user_id BIGINT NOT NULL COMMENT '用户ID',
+    consent_type VARCHAR(50) NOT NULL COMMENT '同意类型: privacy/agreement/children_data/ai_processing',
+    version VARCHAR(20) NOT NULL COMMENT '协议版本号',
+    status VARCHAR(20) NOT NULL DEFAULT 'agreed' COMMENT 'agreed/withdrawn/archived',
+    ip_address VARCHAR(45) COMMENT '用户IP地址',
+    created_at DATETIME NOT NULL,
+    updated_at DATETIME,
+    INDEX idx_user_consent (user_id, consent_type),
+    INDEX idx_consent_type (consent_type)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户同意记录';
+
+-- 用户数据授权表
+CREATE TABLE IF NOT EXISTS user_data_permissions (
+    id BIGINT AUTO_INCREMENT PRIMARY KEY,
+    user_id BIGINT NOT NULL COMMENT '用户ID',
+    allow_ai_analysis TINYINT(1) DEFAULT 0 COMMENT '允许AI分析对话数据',
+    allow_personalized_recommend TINYINT(1) DEFAULT 1 COMMENT '允许个性化推荐',
+    allow_share_teacher TINYINT(1) DEFAULT 1 COMMENT '允许向成长规划师共享数据',
+    allow_third_party_share TINYINT(1) DEFAULT 0 COMMENT '允许与第三方共享数据',
+    created_at DATETIME NOT NULL,
+    updated_at DATETIME,
+    INDEX idx_user_perm (user_id)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户数据使用授权';

+ 6 - 0
cfc-frontend/pages.json

@@ -1272,6 +1272,12 @@
           "style": {
             "navigationBarTitleText": "隐私政策"
           }
+        },
+        {
+          "path": "provider-agreement",
+          "style": {
+            "navigationBarTitleText": "服务商入驻协议"
+          }
         }
       ]
     },

+ 127 - 3
cfc-frontend/pages/family/add-member.vue

@@ -80,14 +80,31 @@
 <text class="hint">若手机号已注册,将自动关联该账号</text>
 </view>
 
-<button class="btn-primary" :loading="submitting" @click="submit">保存</button>
+<!-- 监护人同意弹窗 -->
+<view class="modal-overlay" v-if="showConsentModal">
+  <view class="modal-content">
+    <text class="modal-title">儿童个人信息保护确认</text>
+    <text class="modal-desc">您添加的家庭成员年龄小于14周岁。根据《中华人民共和国个人信息保护法》及《儿童个人信息网络保护规定》,作为法定监护人,您需要确认同意我们收集和使用该儿童的个人信息(包括姓名、性别、出生日期、身高体重、学校信息等),用于提供成长测评、健康分析、任务管理等相关服务。</text>
+    <text class="modal-link" @click="viewPrivacy">查看完整《隐私政策》中儿童个人信息保护章节</text>
+    <view class="modal-checkbox">
+      <label>
+        <checkbox :checked="consentChecked" @click="consentChecked = !consentChecked" />
+        <text class="checkbox-label">我已阅读并同意上述内容,作为法定监护人授权平台处理该儿童的个人信息</text>
+      </label>
+    </view>
+    <view class="modal-buttons">
+      <button class="modal-btn-cancel" @click="showConsentModal = false">取消</button>
+      <button class="modal-btn-confirm" :disabled="!consentChecked" @click="confirmConsent">确认并继续</button>
+    </view>
+  </view>
+</view>
 </view>
 </view>
 </view>
 </template>
 
 <script>
-import { addFamilyMember, updateFamilyMember } from '../../utils/api.js'
+import { addFamilyMember, updateFamilyMember, recordConsent } from '../../utils/api.js'
 import GenerationPicker from '../../components/GenerationPicker.vue'
 import { parseDate } from '../../utils/format.js'
 
@@ -121,7 +138,10 @@ cesareanOptions: [
 { value: 0, label: '顺产' },
 { value: 1, label: '剖腹产' }
 ],
-todayDate: ''
+todayDate: '',
+showConsentModal: false,
+consentChecked: false,
+pendingSubmitPayload: null
 }
 },
 computed: {
@@ -199,6 +219,35 @@ uni.showToast({ title: '请输入正确的手机号', icon: 'none' })
 return
 }
 
+// 检查是否为14岁以下儿童 -> 显示监护人同意弹窗
+if (!this.isEdit) {
+  var genLevel = (this.$refs.generationPicker && this.$refs.generationPicker.selectedGen) || this.form.generationLevel
+  // 辈分负值表示晚辈(孩子),且年龄 < 14
+  var age = this.calculatedAge ? parseInt(this.calculatedAge) : 0
+  if (genLevel < 0 && age < 14) {
+    this.pendingSubmitPayload = null
+    this.consentChecked = false
+    this.showConsentModal = true
+    return
+  }
+}
+
+this.doSubmit()
+},
+viewPrivacy() {
+  uni.navigateTo({ url: '/pages/policy/privacy' })
+},
+async confirmConsent() {
+  if (!this.consentChecked) return
+  this.showConsentModal = false
+  try {
+    await recordConsent({ consentType: 'children_data', version: '2026-08-v1' })
+  } catch (e) {
+    console.log('记录同意失败', e)
+  }
+  this.doSubmit()
+},
+async doSubmit() {
 try {
 this.submitting = true
 if (this.isEdit) {
@@ -272,4 +321,79 @@ this.submitting = false
 .age-display { border: 1rpx solid #ddd; border-radius: 10rpx; padding: 20rpx; font-size: 28rpx; color: #999; background: #f9f9f9; }
 .hint { font-size: 24rpx; color: #999; margin-top: 8rpx; display: block; }
 .btn-primary { background: #F97316; color: #fff; border-radius: 20rpx; margin-top: 40rpx; }
+
+/* 监护人同意弹窗 */
+.modal-overlay {
+  position: fixed;
+  top: 0; left: 0; right: 0; bottom: 0;
+  background: rgba(0,0,0,0.5);
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  z-index: 999;
+}
+.modal-content {
+  background: #fff;
+  border-radius: 20rpx;
+  padding: 40rpx;
+  margin: 40rpx;
+  max-height: 80vh;
+  overflow-y: auto;
+}
+.modal-title {
+  font-size: 32rpx;
+  font-weight: bold;
+  color: #333;
+  display: block;
+  text-align: center;
+  margin-bottom: 20rpx;
+}
+.modal-desc {
+  font-size: 26rpx;
+  color: #666;
+  display: block;
+  line-height: 1.7;
+  margin-bottom: 16rpx;
+}
+.modal-link {
+  font-size: 24rpx;
+  color: #667eea;
+  display: block;
+  text-align: center;
+  margin-bottom: 24rpx;
+  text-decoration: underline;
+}
+.modal-checkbox {
+  margin-bottom: 32rpx;
+}
+.checkbox-label {
+  font-size: 24rpx;
+  color: #333;
+  margin-left: 8rpx;
+}
+.modal-buttons {
+  display: flex;
+  gap: 20rpx;
+}
+.modal-btn-cancel {
+  flex: 1;
+  background: #f5f5f5;
+  color: #666;
+  border-radius: 44rpx;
+  font-size: 28rpx;
+  padding: 20rpx;
+  text-align: center;
+}
+.modal-btn-confirm {
+  flex: 1;
+  background: #F97316;
+  color: #fff;
+  border-radius: 44rpx;
+  font-size: 28rpx;
+  padding: 20rpx;
+  text-align: center;
+}
+.modal-btn-confirm[disabled] {
+  background: #ccc;
+}
 </style>

+ 111 - 19
cfc-frontend/pages/policy/agreement.vue

@@ -2,7 +2,7 @@
   <view class="policy-container">
     <view class="policy-content">
       <text class="policy-title">用户协议</text>
-      <text class="policy-update">更新日期:2026年6月</text>
+      <text class="policy-update">更新日期:2026年8月</text>
 
       <view class="policy-section">
         <text class="section-title">一、总则</text>
@@ -23,17 +23,20 @@
           2.2 您应妥善保管您的账号信息,因您保管不当导致的账号被盗用、信息泄露等损失由您自行承担。
         </text>
         <text class="section-text">
-          2.3 一个家庭可关联多个家庭成员账号,家长账号为家庭主账号,有权管理家庭成员及审核相关操作。
+          2.3 一个家庭可关联多个家庭成员账号,家长账号为家庭主账号,有权管理家庭成员、创建孩子账号、审批任务及审核相关操作。家长账号对家庭管理和孩子账号的创建、管理、注销承担相应责任。
         </text>
         <text class="section-text">
           2.4 如您发现账号存在安全漏洞或被他人非法使用,应立即通知我们。
         </text>
+        <text class="section-text">
+          2.5 您应保证在注册和使用过程中提供的信息真实、准确、完整。如您提供的信息不实,我们有权限制或终止您使用本平台服务。
+        </text>
       </view>
 
       <view class="policy-section">
         <text class="section-title">三、服务内容</text>
         <text class="section-text">
-          3.1 本平台提供包括但不限于:家庭任务管理、五维能量评估、成长测评、活动课程报名、商城购物、成长规划师咨询等服务。
+          3.1 本平台提供包括但不限于:家庭任务管理、五维能量评估、成长测评、活动课程报名、商城购物、成长规划师咨询、健康报告解析、AI成长助手等服务。
         </text>
         <text class="section-text">
           3.2 我们有权根据业务发展需要调整、增加或减少服务内容,变更后的服务内容将在平台上公示。
@@ -44,60 +47,149 @@
       </view>
 
       <view class="policy-section">
-        <text class="section-title">四、用户行为规范</text>
+        <text class="section-title">四、付费服务条款</text>
+        <text class="section-text">
+          4.1 本平台的付费服务包括但不限于:家庭会员服务(FAMILY/PREMIUM等级)、测评套餐、商城商品、订阅服务等。
+        </text>
+        <text class="section-text">
+          4.2 收费标准:各付费服务的价格以平台展示的当前价格为准。我们有权根据运营成本和市场情况调整服务价格,价格调整将提前30日在平台公示。已购买的服务按购买时的价格执行,不因调整而追溯。
+        </text>
+        <text class="section-text">
+          4.3 支付方式:本平台通过微信小程序虚拟支付渠道完成支付。您在下单购买前应确认购买的服务内容、价格和有效期限。
+        </text>
+        <text class="section-text">
+          4.4 自动续费:如您购买的是自动续费类服务,将按您选择的周期自动扣费。您可以随时在微信支付设置或平台相应页面中取消自动续费,取消后当前周期到期即不再续费。取消自动续费不影响您已支付周期的会员权益。
+        </text>
+        <text class="section-text">
+          4.5 家庭会员服务:家庭会员(FAMILY)支持年付。会员权益以平台公示的权益说明为准。购买家庭会员后,家庭内所有成员(家长及孩子)均可享受相应会员权益。
+        </text>
+        <text class="section-text">
+          4.6 测评套餐:测评套餐包含相应次数的测评服务。套餐有效期以购买时页面说明为准,逾期未使用的测评次数作废。
+        </text>
+      </view>
+
+      <view class="policy-section">
+        <text class="section-title">五、退款政策</text>
+        <text class="section-text">
+          5.1 会员服务退款:会员服务在购买后未使用的情况下,可申请全额退款。已开始使用的会员服务,退款金额按未使用天数占购买周期的比例计算,即:退款金额 = 实付金额 × 剩余天数 / 购买总天数。已享受的会员权益部分不予退还。
+        </text>
+        <text class="section-text">
+          5.2 测评套餐退款:测评套餐在购买后、未进行任何测评的情况下,可申请全额退款。已进行部分测评的,按未使用次数占套餐总次数的比例退款。
+        </text>
+        <text class="section-text">
+          5.3 商品退款:商城商品退款参照平台售后政策执行。虚拟商品(如测评次数、会员权益)一经使用,概不退款。
+        </text>
+        <text class="section-text">
+          5.4 退款时限:符合条件的退款申请,我们将在收到申请之日起7个工作日内完成退款处理(退款到账时间以支付渠道为准)。
+        </text>
+        <text class="section-text">
+          5.5 争议订单处理:如您对退款金额或处理结果有异议,可通过平台客服渠道提交争议,我们将于5个工作日内核实并答复。经核实确属我们责任的,将在答复后3个工作日内完成相关退款。
+        </text>
+        <text class="section-text">
+          5.6 下列情形不适用退款:因您违反本协议或法律法规导致的账号封禁;已完全使用完毕的服务;超过退款申请期限的服务。
+        </text>
+      </view>
+
+      <view class="policy-section">
+        <text class="section-title">六、用户行为规范</text>
+        <text class="section-text">
+          6.1 您承诺遵守国家法律法规,不得利用本平台从事任何违法违规活动。
+        </text>
         <text class="section-text">
-          4.1 您承诺遵守国家法律法规,不得利用本平台从事任何违法违规活动。
+          6.2 您不得利用本平台发布违法信息、侮辱诽谤他人、侵犯他人合法权益的内容,包括但不限于涉及色情、暴力、赌博、诈骗、传销等信息。
         </text>
         <text class="section-text">
-          4.2 您不得利用本平台发布违法信息、侮辱诽谤他人、侵犯他人合法权益的内容。
+          6.3 您不得对本平台进行反向工程、反向汇编、反向编译,不得破坏本平台的安全措施,不得以任何方式干扰本平台的正常运行。
         </text>
         <text class="section-text">
-          4.3 您不得对本平台进行反向工程、反向汇编、反向编译,不得破坏本平台的安全措施。
+          6.4 您不得利用本平台从事危害网络安全、破坏数据安全的行为,不得非法获取、窃取、篡改他人个人信息。
         </text>
         <text class="section-text">
-          4.4 如您违反上述约定,我们有权采取警告、限制功能、封禁账号等措施,并保留追究法律责任的权利。
+          6.5 如您违反上述约定,我们有权采取警告、限制功能、封禁账号等措施,并保留追究法律责任的权利。
         </text>
       </view>
 
       <view class="policy-section">
-        <text class="section-title">五、隐私保护</text>
+        <text class="section-title">七、隐私保护</text>
         <text class="section-text">
-          我们重视您的隐私保护,具体隐私政策请查阅《隐私政策》。我们采用业界通行的安全技术和管理措施保护您的个人信息安全。
+          我们重视您的隐私保护,具体隐私政策请查阅《隐私政策》。我们采用业界通行的安全技术和管理措施保护您的个人信息安全。您同意我们按照《隐私政策》的约定收集、使用、存储、共享和保护您的个人信息。
         </text>
       </view>
 
       <view class="policy-section">
-        <text class="section-title">六、知识产权</text>
+        <text class="section-title">八、服务商条款</text>
+        <text class="section-text">
+          8.1 本平台为符合条件的个人或机构提供服务商角色(包括成长规划师、活动规划师、商品供应商等)。服务商需通过平台审核后方可提供服务。
+        </text>
+        <text class="section-text">
+          8.2 入驻条件:服务商申请入驻时,应提供真实、准确、完整的资质信息和证明文件(包括但不限于身份证明、职业资质证书等)。我们有权对申请资料进行审核,审核不通过的,不予入驻。
+        </text>
+        <text class="section-text">
+          8.3 服务商的权利义务:服务商应按照平台规则和订单约定向用户提供真实、优质的服务,保证服务质量,不得虚假宣传、夸大承诺。服务商应遵守国家法律法规和平台各项规则。
+        </text>
+        <text class="section-text">
+          8.4 责任划分:服务商对其提供的服务质量、服务内容及与用户之间的服务纠纷承担相应责任。平台仅提供技术服务和技术支持,不成为服务商与用户之间服务合同的当事人。因服务商违约或侵权给用户造成的损失,由服务商自行承担。
+        </text>
+        <text class="section-text">
+          8.5 佣金与结算:服务商可依据平台规则获得相应佣金。佣金计算方式、结算周期、提现方式以平台公示的规则为准。我们对佣金规则保留调整权,调整将提前30日公示。
+        </text>
         <text class="section-text">
-          本平台的所有内容,包括但不限于文字、图片、软件、界面设计、数据等,均属于我们或相关权利人所有,受知识产权法律法规保护。
+          8.6 退出机制:服务商可申请退出服务,退出前需完成处理中的订单。服务商违反平台规则或国家法律法规的,我们有权取消其服务商资格。
         </text>
       </view>
 
       <view class="policy-section">
-        <text class="section-title">七、免责声明</text>
+        <text class="section-title">九、知识产权</text>
         <text class="section-text">
-          7.1 我们将尽力保证平台服务的稳定性和安全性,但无法保证服务不会中断或完全没有错误。
+          本平台的所有内容,包括但不限于文字、图片、软件、界面设计、数据、测评体系、五维能量概念等,均属于我们或相关权利人所有,受知识产权法律法规保护。未经我们书面许可,您不得以任何方式复制、传播、修改、使用上述内容。
         </text>
+      </view>
+
+      <view class="policy-section">
+        <text class="section-title">十、免责声明</text>
         <text class="section-text">
-          7.2 因不可抗力、系统维护、网络故障等原因导致的服务中断,我们不承担法律责任。
+          10.1 本平台提供的健康评估、成长建议、测评结果等信息仅供参考,不构成医疗建议、诊断结论或治疗方案。如您或您的家人存在健康问题,请及时咨询专业医疗机构。
         </text>
         <text class="section-text">
-          7.3 本平台提供的健康评估、成长建议等信息仅供参考,不构成医疗建议或诊断结论。
+          10.2 心理测评结果仅反映测评当次的状态,不代表临床诊断结论。测评结果不应用于替代专业心理咨询或医疗诊断。
+        </text>
+        <text class="section-text">
+          10.3 AI助手(浠宝/福宝)生成的内容仅供参考,我们不保证其准确性、完整性和适用性。AI生成内容不构成专业建议。
+        </text>
+        <text class="section-text">
+          10.4 本平台服务商(成长规划师等)提供的服务及其结果,由其自身对服务质量负责,我们不对服务商提供的专业意见承担担保责任。
+        </text>
+        <text class="section-text">
+          10.5 因不可抗力、系统维护、网络故障、第三方服务中断等原因导致的服务中断或数据丢失,在法律允许的范围内,我们不承担相应的法律责任。
+        </text>
+        <text class="section-text">
+          10.6 我们将尽力保证平台服务的稳定性和安全性,但无法保证服务不会中断或完全没有错误。
         </text>
       </view>
 
       <view class="policy-section">
-        <text class="section-title">八、协议修改</text>
+        <text class="section-title">十一、协议修改</text>
+        <text class="section-text">
+          我们有权根据需要修改本协议。修改后的协议将在平台公示,如您继续使用本平台服务,视为您接受修改后的协议。对于重大变更,我们将通过弹窗或其他方式通知您,并在必要时取得您的重新同意。
+        </text>
+      </view>
+
+      <view class="policy-section">
+        <text class="section-title">十二、争议解决</text>
+        <text class="section-text">
+          12.1 本协议的订立、效力、解释、履行及争议的解决均适用中华人民共和国法律。
+        </text>
         <text class="section-text">
-          我们有权根据需要修改本协议。修改后的协议将在平台公示,如您继续使用本平台服务,视为您接受修改后的协议。
+          12.2 因本协议引起的或与本协议有关的任何争议,双方应首先友好协商解决。协商不成的,任何一方均可将争议提交本平台运营方所在地有管辖权的人民法院诉讼解决。
         </text>
       </view>
 
       <view class="policy-section">
-        <text class="section-title">九、联系我们</text>
+        <text class="section-title">十三、联系我们</text>
         <text class="section-text">
           如您对本协议有任何疑问,请联系我们:service@etotem.com.cn
         </text>
+        <text class="section-text">运营主体:亿图腾(北京)科技有限公司</text>
       </view>
     </view>
   </view>

+ 132 - 39
cfc-frontend/pages/policy/privacy.vue

@@ -2,89 +2,182 @@
   <view class="policy-container">
     <view class="policy-content">
       <text class="policy-title">隐私政策</text>
-      <text class="policy-update">更新日期:2026年6月</text>
+      <text class="policy-update">更新日期:2026年8月</text>
 
       <view class="policy-section">
         <text class="section-title">一、引言</text>
         <text class="section-text">
-          亿图腾(北京)科技有限公司(以下简称"我们")深知个人信息对您的重要性,我们将按照法律法规的要求,尽全力保护您的个人信息安全。本隐私政策旨在向您说明我们在您使用浠艾福(Care Family)平台时如何收集、使用、存储和保护您的个人信息。
+          亿图腾(北京)科技有限公司(以下简称"我们"或"平台")深知个人信息对您的重要性,我们将按照《中华人民共和国个人信息保护法》《中华人民共和国数据安全法》《中华人民共和国网络安全法》《儿童个人信息网络保护规定》等法律法规的要求,尽全力保护您的个人信息安全。
         </text>
         <text class="section-text">
-          请您在使用本平台前仔细阅读本隐私政策。如您不同意本政策的任何内容,请立即停止使用本平台服务。
+          本隐私政策旨在向您说明我们在您使用浠艾福(Care Family)家庭健康成长俱乐部服务平台(以下简称"本平台")时如何收集、使用、存储、共享和保护您的个人信息。请您在使用本平台前仔细阅读并充分理解本隐私政策的全部内容。
+        </text>
+        <text class="section-text">
+          如您不同意本政策的任何内容,请立即停止使用本平台服务。您点击"同意"或继续使用本平台服务,即视为您已充分理解并同意本隐私政策的全部内容。
         </text>
       </view>
 
       <view class="policy-section">
         <text class="section-title">二、我们收集的信息</text>
-        <text class="section-text">在您使用本平台过程中,我们可能会收集以下信息:</text>
-        <text class="section-text">2.1 微信授权信息:微信昵称、微信头像、微信OpenID,用于登录和身份识别。</text>
-        <text class="section-text">2.2 用户资料:您填写的昵称、头像、手机号码、家庭成员信息等。</text>
-        <text class="section-text">2.3 使用记录:打卡记录、任务完成记录、测评结果、活动参与记录等。</text>
-        <text class="section-text">2.4 设备信息:设备型号、操作系统版本、网络状态等,用于提供更好的服务体验。</text>
-        <text class="section-text">2.5 位置信息:如您使用与位置相关的功能,我们可能会获取您的位置信息。</text>
+        <text class="section-text">在您使用本平台过程中,我们可能会收集以下类别的信息:</text>
+
+        <text class="section-text">2.1 微信授权信息:包括您的微信OpenID、UnionID、微信昵称、微信头像。这些信息用于登录认证、身份识别和账户关联。</text>
+
+        <text class="section-text">2.2 注册信息:您注册时提供的手机号码,用于账号创建和身份验证。</text>
+
+        <text class="section-text">2.3 个人资料:您在个人中心填写的昵称、真实姓名、性别、出生日期、出生时辰、头像照片。其中真实姓名和出生时辰用于为您提供个性化的成长评估服务。</text>
+
+        <text class="section-text">2.4 身份信息(敏感个人信息):您在认证或购买服务时提供的身份证号码。我们收集该信息仅用于实名认证和法律法规要求的身份核验。</text>
+
+        <text class="section-text">2.5 家庭信息:您创建或加入的家庭信息,包括家庭关系(爸爸/妈妈/爷爷/奶奶等)、家庭成员信息、家庭角色。其中家庭关系用于区分家庭成员角色和权限管理。</text>
+
+        <text class="section-text">2.6 详细个人资料:您可选填的民族、血型、最高学历、婚姻状况、兴趣爱好、饮食偏好、家庭角色。这些信息用于为您提供更加个性化的服务推荐。</text>
+
+        <text class="section-text">2.7 孩子信息(含14岁以下儿童个人信息——敏感个人信息):您为子女创建账号时提供的孩子姓名、年龄、性别、出生日期、身份证号(选填)、手机号(选填)、学校、年级、班级、身高、体重、家庭状况、父母学历、是否独生子女、在校成绩、紧急联系人姓名及电话。请注意,孩子的身份证号、学校、班级、紧急联系人信息属于敏感个人信息。</text>
+
+        <text class="section-text">2.8 心理测评数据(敏感个人信息):您或您孩子参加测评时产生的注意力得分、专注力得分、记忆力得分、逻辑思维得分、感知得分、空间思维得分、加工速度得分、情绪商数、心理韧性、压力应对能力、自我认知、开放性/尽责性/外向性/宜人性/神经质等大五人格维度评分、情绪管理能力、同理心、社会适应能力、自我激励能力、综合得分,以及测评过程中的游戏记录、分析报告和成长建议。</text>
+
+        <text class="section-text">2.9 健康数据(敏感个人信息):您上传或产生的体检报告数据、菌群检测报告数据,包括健康总分、菌群健康评分、慢病控制评分、营养均衡评分、肠道预测年龄、肠型分类、菌群平衡评分、多样性评分、有益菌/有害菌评分、核心菌属评分、健康评级等指标。</text>
+
+        <text class="section-text">2.10 使用记录:您在平台上的操作记录,包括任务创建和执行记录、打卡记录、心愿创建和兑换记录、积分变动记录、小游戏记录(舒尔特方格、猜数字、数独等)、成长档案、活动参与记录、课程学习记录。</text>
+
+        <text class="section-text">2.11 通讯内容:您与成长规划师之间的消息记录、您与AI助手(浠宝/福宝)的对话记录。请注意,AI对话内容可能会被记录并用于改进服务质量。</text>
+
+        <text class="section-text">2.12 位置信息:当您使用地址相关功能(如家庭地址设置、街道匹配)时,我们可能会收集您的位置信息。</text>
+
+        <text class="section-text">2.13 设备信息:设备型号、操作系统版本、网络状态、微信版本号、设备标识符,用于提供更好的服务体验和故障排查。</text>
+
+        <text class="section-text">2.14 媒体文件:您上传的图片、视频、音频文件,包括头像照片、测评相关图片、健康报告文件等。</text>
+
+        <text class="section-text">2.15 服务商信息:如您申请成为服务商(成长规划师/活动规划师/商品供应商),我们还会收集您的服务商资质信息、证书照片、审核材料、团队信息等。</text>
       </view>
 
       <view class="policy-section">
-        <text class="section-title">三、信息的使用</text>
+        <text class="section-title">三、信息的使用目的</text>
         <text class="section-text">我们收集的信息将用于以下目的:</text>
-        <text class="section-text">3.1 提供、维护和改进本平台的服务。</text>
-        <text class="section-text">3.2 个性化推荐和内容展示。</text>
-        <text class="section-text">3.3 与您沟通,发送服务通知、活动信息等。</text>
-        <text class="section-text">3.4 数据分析和研究,用于优化产品和服务。</text>
-        <text class="section-text">3.5 履行法定义务和保障平台安全。</text>
+        <text class="section-text">3.1 提供、维护和改进本平台的核心服务,包括家庭任务管理、五维能量评估、成长测评、活动课程、商城购物、成长规划师咨询等。</text>
+        <text class="section-text">3.2 个性化推荐和内容展示,根据您的使用习惯和偏好推荐适合的服务和内容。</text>
+        <text class="section-text">3.3 AI服务(经您单独同意后):用于AI对话分析、用户画像构建、智能推荐和成长建议生成。如您不同意,我们将不会将您的数据用于AI分析。</text>
+        <text class="section-text">3.4 与您沟通,发送服务通知、活动信息、系统公告等。</text>
+        <text class="section-text">3.5 数据分析和研究,用于优化产品功能、改进服务体验、提升平台安全性。</text>
+        <text class="section-text">3.6 履行法定义务,包括实名认证、税务合规、反洗钱、网络安全等法律法规要求。</text>
+        <text class="section-text">3.7 保障平台安全,检测和防范欺诈、滥用等违法违规行为。</text>
       </view>
 
       <view class="policy-section">
-        <text class="section-title">四、信息的共享与披露</text>
-        <text class="section-text">4.1 我们不会将您的个人信息出售给第三方。</text>
-        <text class="section-text">
-          4.2 在以下情况下,我们可能会共享您的信息:获得您的明确同意;为提供服务需要与合作伙伴共享(如支付服务商);法律法规要求;保护我们或他人的合法权益。
-        </text>
-        <text class="section-text">4.3 成长规划师在为您提供服务时,可查看您授权范围内的家庭信息和测评结果。</text>
+        <text class="section-title">四、敏感个人信息的处理</text>
+        <text class="section-text">4.1 本平台收集的敏感个人信息包括:身份证号码、心理测评数据(注意力/专注力/记忆力/情绪商数/大五人格等各类评分)、健康数据(体检报告/菌群检测报告)、14岁以下儿童的个人信息。这些信息一旦泄露或被非法使用,可能对您的人格尊严和人身财产安全造成严重损害。</text>
+        <text class="section-text">4.2 我们处理上述敏感个人信息的目的和必要性:</text>
+        <text class="section-text">(a) 身份证号码:用于实名认证、法律法规要求的身份核验和支付安全。</text>
+        <text class="section-text">(b) 心理测评数据:用于生成专业的成长评估报告和个性化发展建议,是平台核心服务的基础。</text>
+        <text class="section-text">(c) 健康数据:用于生成健康分析和改善建议,帮助您了解自身健康状况。</text>
+        <text class="section-text">(d) 儿童个人信息:用于儿童成长管理和教育服务,家长作为监护人全程管理。</text>
+        <text class="section-text">4.3 我们处理敏感个人信息前,会通过弹窗等方式取得您的单独同意,并仅以最小必要原则收集和使用。</text>
       </view>
 
       <view class="policy-section">
-        <text class="section-title">五、信息安全</text>
-        <text class="section-text">
-          我们采用SSL/TLS加密传输、数据脱敏、访问权限控制、安全审计等业界通行的安全措施保护您的个人信息。但请注意,没有任何安全措施是100%完美的,我们将持续改进安全能力。
-        </text>
+        <text class="section-title">五、儿童个人信息保护</text>
+        <text class="section-text">5.1 我们非常重视儿童个人信息的保护。本平台可能涉及收集14周岁以下儿童的个人信息,包括但不限于儿童姓名、年龄、性别、出生日期、身份证号、学校、年级、班级、身高、体重、心理测评数据、健康数据等。</text>
+        <text class="section-text">5.2 我们收集和处理儿童个人信息前,会通过家长(法定监护人)账号取得监护人的明确同意。监护人应仔细阅读本隐私政策,特别是本章节内容,并在同意后允许儿童使用本平台。</text>
+        <text class="section-text">5.3 监护人有权:</text>
+        <text class="section-text">(a) 查询和更正儿童的个人信息;</text>
+        <text class="section-text">(b) 要求删除儿童的个人信息;</text>
+        <text class="section-text">(c) 撤回对儿童个人信息处理的同意;</text>
+        <text class="section-text">(d) 注销儿童账号,注销后我们将删除或匿名化处理儿童的个人信息。</text>
+        <text class="section-text">5.4 我们采取以下措施保护儿童个人信息:</text>
+        <text class="section-text">(a) 指定专人负责儿童个人信息保护;</text>
+        <text class="section-text">(b) 对儿童个人信息采取加密存储和访问权限控制;</text>
+        <text class="section-text">(c) 严格限制儿童个人信息的使用范围,仅用于该儿童的教育和成长服务;</text>
+        <text class="section-text">(d) 不向第三方披露儿童个人信息,除非获得监护人同意或法律法规要求。</text>
+        <text class="section-text">5.5 如您是儿童的监护人,发现我们在未获监护人同意的情况下收集了儿童个人信息,请立即通过本政策底部联系方式与我们联系,我们将立即删除相关信息。</text>
       </view>
 
       <view class="policy-section">
-        <text class="section-title">六、信息存储期限</text>
+        <text class="section-title">六、信息的共享与披露</text>
+        <text class="section-text">6.1 我们不会将您的个人信息出售给任何第三方。</text>
+        <text class="section-text">6.2 在以下情况下,我们可能会共享您的信息:</text>
+        <text class="section-text">(a) 获得您的明确同意或单独授权;</text>
+        <text class="section-text">(b) 为提供服务需要与必要的合作伙伴共享,包括但不限于:</text>
+        <text class="section-text">—— 微信支付(深圳市腾讯计算机系统有限公司):处理虚拟支付交易,共享信息为订单号、支付金额、支付状态;</text>
+        <text class="section-text">—— 微信开放平台(深圳市腾讯计算机系统有限公司):提供微信登录和身份认证服务,共享信息为OpenID、UnionID、昵称、头像;</text>
+        <text class="section-text">—— Dify AI平台(如适用):提供AI对话和智能分析服务,共享信息为对话内容、用户查询;</text>
+        <text class="section-text">(c) 成长规划师在为您提供服务时,可在您授权范围内查看家庭信息和测评结果;</text>
+        <text class="section-text">(d) 法律法规要求或有关国家机关依法要求;</text>
+        <text class="section-text">(e) 为保护我们或他人的合法权益所必需。</text>
+        <text class="section-text">6.3 我们与第三方合作时,会通过合同约定其数据安全保护义务,要求其遵循本隐私政策的规定,不得将您的个人信息用于其他目的。</text>
+      </view>
+
+      <view class="policy-section">
+        <text class="section-title">七、跨境数据传输</text>
         <text class="section-text">
-          我们仅在实现本政策所述目的所必需的最短期限内保留您的个人信息,除非法律法规另有要求。超出保留期限后,我们将删除或匿名化处理您的信息。
+          我们仅在中华人民共和国境内(为本隐私政策之目的,不含香港、澳门和台湾地区)存储和处理您的个人信息。如我们使用的AI服务提供商(如Dify)的服务器位于境外,我们将按照法律法规的要求进行个人信息保护影响评估,采取必要的安全措施,并在取得您的单独同意后方将数据传输至境外。如您不同意跨境传输,我们将无法为您提供相关的AI服务,但不影响您使用平台的其他功能。
         </text>
       </view>
 
       <view class="policy-section">
-        <text class="section-title">七、您的权利</text>
-        <text class="section-text">您对您的个人信息享有以下权利:</text>
-        <text class="section-text">7.1 查询、更正您的个人信息。</text>
-        <text class="section-text">7.2 删除您的个人信息(在不妨碍我们履行法定义务的前提下)。</text>
-        <text class="section-text">7.3 撤回授权同意,但撤回不影响此前基于同意进行的处理。</text>
-        <text class="section-text">7.4 注销账号,注销后我们将删除或匿名化处理您的信息。</text>
+        <text class="section-title">八、信息安全措施</text>
+        <text class="section-text">我们采用业界通行的安全措施保护您的个人信息:</text>
+        <text class="section-text">8.1 传输加密:采用SSL/TLS加密协议保护数据传输过程中的安全。</text>
+        <text class="section-text">8.2 存储加密:对敏感个人信息(如身份证号、手机号、心理测评数据)进行加密存储。</text>
+        <text class="section-text">8.3 数据脱敏:在日志和显示中对身份证号、手机号、姓名等敏感信息进行脱敏处理。</text>
+        <text class="section-text">8.4 访问控制:实施严格的访问权限控制,仅授权人员可访问个人信息,且所有访问行为均有日志记录。</text>
+        <text class="section-text">8.5 安全审计:定期进行安全审计和漏洞扫描,持续改进安全能力。</text>
+        <text class="section-text">8.6 应急响应:建立数据安全事件应急响应机制,一旦发生数据泄露等安全事件,我们将立即启动应急预案,并在72小时内通知受影响的用户和监管部门。</text>
+        <text class="section-text">请注意,没有任何安全措施是100%完美的,我们将持续改进安全能力以保护您的信息安全。</text>
+      </view>
+
+      <view class="policy-section">
+        <text class="section-title">九、信息存储期限</text>
+        <text class="section-text">9.1 我们仅在实现本隐私政策所述目的所必需的最短期限内保留您的个人信息:</text>
+        <text class="section-text">(a) 用户基本资料:在您使用本平台期间持续保留,注销账号后180天内删除或匿名化处理;</text>
+        <text class="section-text">(b) 心理测评数据:自测评完成之日起保留7年(用于成长轨迹追踪),到期后匿名化处理;</text>
+        <text class="section-text">(c) 健康数据:自上传之日起保留5年,到期后匿名化处理;</text>
+        <text class="section-text">(d) AI对话记录:自对话完成之日起保留1年,到期后匿名化处理;</text>
+        <text class="section-text">(e) 交易记录:自交易完成之日起保留不少于5年(根据《电子商务法》要求);</text>
+        <text class="section-text">(f) 日志记录:自产生之日起保留6个月,到期后自动删除。</text>
+        <text class="section-text">9.2 超出上述保留期限后,我们将删除或匿名化处理您的个人信息。匿名化后的信息无法识别特定个人,不属于个人信息,可不受限制地使用。</text>
+      </view>
+
+      <view class="policy-section">
+        <text class="section-title">十、您的权利</text>
+        <text class="section-text">根据《中华人民共和国个人信息保护法》,您对您的个人信息享有以下权利:</text>
+        <text class="section-text">10.1 查询和复制权:您可以通过个人中心查看您的个人信息,也可以联系我们获取个人信息的副本。</text>
+        <text class="section-text">10.2 更正权:如您的个人信息不准确或不完整,您可以在个人中心自行更正,或联系我们协助更正。</text>
+        <text class="section-text">10.3 删除权:在以下情况下,您可以要求我们删除您的个人信息:</text>
+        <text class="section-text">(a) 处理目的已实现、无法实现或不再必要;</text>
+        <text class="section-text">(b) 您撤回同意且我们无其他合法依据继续处理;</text>
+        <text class="section-text">(c) 我们违反法律法规或约定处理您的信息;</text>
+        <text class="section-text">(d) 您注销账号。</text>
+        <text class="section-text">10.4 撤回同意权:您可以撤回对个人信息处理的同意,撤回不影响此前基于同意进行的处理。您可以通过个人中心的"数据授权管理"功能撤回相关授权。</text>
+        <text class="section-text">10.5 注销账号权:您可以通过"我的—设置—注销账号"申请注销账号。注销后,我们将删除或匿名化处理您的个人信息,但法律法规另有要求的除外。</text>
+        <text class="section-text">10.6 数据可携带权:您可以要求我们将您的个人信息以结构化、常用、机器可读的格式提供给您,或转移给您指定的第三方。</text>
+        <text class="section-text">10.7 拒绝自动化决策权:您有权拒绝我们仅通过自动化决策方式做出对您权益有重大影响的决定。如您对AI生成的测评结果或建议有异议,可以联系人工客服进行复核。</text>
+        <text class="section-text">10.8 逝者近亲属权利:已故用户的近亲属可以在符合法律法规规定的情况下,查阅、复制、更正、删除已故用户的个人信息。</text>
+        <text class="section-text">如您需要行使上述权利,请通过本政策底部的联系方式与我们联系。我们将在15个工作日内回复您的请求。</text>
       </view>
 
       <view class="policy-section">
-        <text class="section-title">八、未成年人保护</text>
+        <text class="section-title">十一、Cookie及类似技术</text>
         <text class="section-text">
-          我们非常重视未成年人个人信息保护。若您为未成年人,请在法定监护人陪同下阅读本政策,并确保在监护人同意后使用本平台服务。监护人应对未成年人的账号使用行为进行监督和管理。
+          本平台使用微信小程序提供的本地存储功能(类似于Cookie技术)来存储您的登录状态和应用设置。这些信息仅存储在您的设备本地,我们不会通过Cookie技术追踪您的跨站行为。您可以在微信小程序设置中清除本地存储数据。
         </text>
       </view>
 
       <view class="policy-section">
-        <text class="section-title">九、政策变更</text>
+        <text class="section-title">十二、政策变更</text>
         <text class="section-text">
-          我们可能适时修订本隐私政策。变更后的政策将在平台公示,重大变更我们会通过弹窗或推送等方式通知您。
+          我们可能适时修订本隐私政策。修订后的隐私政策将在平台公示,更新日期将同步修改。对于重大变更,我们会通过弹窗、推送通知或站内信等方式通知您,并在取得您的重新同意后继续处理您的个人信息。重大变更包括但不限于:我们的服务模式发生重大变化;个人信息处理目的、方式发生变化;个人信息共享对象或目的发生变化;您行使权利的方式发生重大变化等。
         </text>
       </view>
 
       <view class="policy-section">
-        <text class="section-title">十、联系方式</text>
+        <text class="section-title">十三、联系我们</text>
         <text class="section-text">
-          如您对本隐私政策有任何疑问、意见或投诉,请联系我们:service@etotem.com.cn
+          如您对本隐私政策有任何疑问、意见或投诉,或需要行使您的个人信息相关权利,请通过以下方式联系我们:
         </text>
+        <text class="section-text">电子邮件:service@etotem.com.cn</text>
+        <text class="section-text">运营主体:亿图腾(北京)科技有限公司</text>
+        <text class="section-text">我们将在收到您的请求后15个工作日内回复。如您对我们的回复不满意,或认为我们的个人信息处理行为损害了您的合法权益,您可以向网信办、工信部等监管部门投诉,或向有管辖权的人民法院提起诉讼。</text>
       </view>
     </view>
   </view>

+ 204 - 0
cfc-frontend/pages/policy/provider-agreement.vue

@@ -0,0 +1,204 @@
+<template>
+  <view class="policy-container">
+    <view class="policy-content">
+      <text class="policy-title">服务商入驻协议</text>
+      <text class="policy-update">更新日期:2026年8月</text>
+
+      <view class="policy-section">
+        <text class="section-title">一、总则</text>
+        <text class="section-text">
+          本协议适用于所有申请入驻浠艾福(Care Family)平台并成为服务商的个人或机构(以下简称"服务商"),包括但不限于成长规划师、活动规划师、商品供应商等。本平台由亿图腾(北京)科技有限公司(以下简称"我们"或"平台")运营。
+        </text>
+        <text class="section-text">
+          服务商在申请入驻前,应仔细阅读本协议全部内容。服务商提交入驻申请即视为已充分理解并接受本协议的全部内容。
+        </text>
+      </view>
+
+      <view class="policy-section">
+        <text class="section-title">二、入驻条件</text>
+        <text class="section-text">
+          2.1 服务商应为具备完全民事行为能力的自然人或合法存续的法人实体。
+        </text>
+        <text class="section-text">
+          2.2 服务商应提供真实、准确、完整的资质信息和证明文件,包括但不限于身份证明、职业资质证书、营业执照等。
+        </text>
+        <text class="section-text">
+          2.3 平台有权对服务商提交的申请资料进行审核,审核不通过的,不予入驻。平台有权要求服务商补充提交额外材料。
+        </text>
+        <text class="section-text">
+          2.4 服务商应保证其提供的资质信息持续真实有效,如有变更,应及时通知平台更新。
+        </text>
+      </view>
+
+      <view class="policy-section">
+        <text class="section-title">三、权利与义务</text>
+        <text class="section-text">
+          3.1 服务商有权在平台规则范围内使用平台提供的技术服务,发布服务信息,向用户提供专业服务。
+        </text>
+        <text class="section-text">
+          3.2 服务商应按照平台规则和订单约定向用户提供真实、优质的服务,保证服务质量符合行业标准。
+        </text>
+        <text class="section-text">
+          3.3 服务商不得进行虚假宣传、夸大承诺或误导用户。服务商应对其发布的服务信息真实性负责。
+        </text>
+        <text class="section-text">
+          3.4 服务商应遵守国家法律法规和平台各项规则,不得利用平台从事任何违法违规活动。
+        </text>
+        <text class="section-text">
+          3.5 服务商应妥善保管其平台账号,对账号下的一切行为承担法律责任。
+        </text>
+      </view>
+
+      <view class="policy-section">
+        <text class="section-title">四、服务标准</text>
+        <text class="section-text">
+          4.1 服务商应按照平台公示的服务标准和服务流程向用户提供服务。
+        </text>
+        <text class="section-text">
+          4.2 服务商应保证服务响应时间,及时回复用户咨询和需求。
+        </text>
+        <text class="section-text">
+          4.3 服务商提供服务过程中应尊重用户隐私,不得泄露用户个人信息。
+        </text>
+        <text class="section-text">
+          4.4 如用户对服务不满意,服务商应积极配合平台进行协调和解决。
+        </text>
+      </view>
+
+      <view class="policy-section">
+        <text class="section-title">五、佣金与结算</text>
+        <text class="section-text">
+          5.1 服务商可依据平台规则获得相应服务佣金。具体佣金比例、计算方式以平台公示的规则为准。
+        </text>
+        <text class="section-text">
+          5.2 佣金结算周期为每月一次,结算周期内的佣金将在次月15日前完成结算。
+        </text>
+        <text class="section-text">
+          5.3 服务商应按照国家税法规定,自行申报并缴纳相关税款。平台有权依法代扣代缴。
+        </text>
+        <text class="section-text">
+          5.4 平台有权根据运营情况调整佣金规则,调整将提前30日通过平台公示通知。
+        </text>
+      </view>
+
+      <view class="policy-section">
+        <text class="section-title">六、平台责任</text>
+        <text class="section-text">
+          6.1 平台提供技术服务和技术支持,包括但不限于系统维护、用户导流、支付结算、争议协调等。
+        </text>
+        <text class="section-text">
+          6.2 平台不成为服务商与用户之间服务合同的当事人。因服务商提供的服务质量、内容产生的纠纷,由服务商与用户自行解决。
+        </text>
+        <text class="section-text">
+          6.3 平台有权对服务商的服务质量进行监督和评估,对不符合标准的服务商采取相应管理措施。
+        </text>
+      </view>
+
+      <view class="policy-section">
+        <text class="section-title">七、退出机制</text>
+        <text class="section-text">
+          7.1 服务商可申请退出服务商身份,需提前30日书面通知平台,并完成处理中的未结订单。
+        </text>
+        <text class="section-text">
+          7.2 退出后,服务商在平台上的服务信息将下架,但已产生的订单和交易记录将按现有规则继续处理。
+        </text>
+        <text class="section-text">
+          7.3 服务商违反本协议或国家法律法规的,平台有权立即取消其服务商资格,并保留追究法律责任的权利。
+        </text>
+      </view>
+
+      <view class="policy-section">
+        <text class="section-title">八、违约责任</text>
+        <text class="section-text">
+          8.1 服务商违反本协议约定的,平台有权采取警告、限制功能、暂停服务、取消资格等措施。
+        </text>
+        <text class="section-text">
+          8.2 因服务商违约或侵权给用户或平台造成损失的,服务商应承担相应的赔偿责任。
+        </text>
+        <text class="section-text">
+          8.3 服务商利用平台从事违法违规活动的,平台将立即向有关部门报告,并配合调查处理。
+        </text>
+      </view>
+
+      <view class="policy-section">
+        <text class="section-title">九、免责声明</text>
+        <text class="section-text">
+          9.1 因不可抗力、系统维护、网络故障等原因导致的服务中断,平台不承担法律责任。
+        </text>
+        <text class="section-text">
+          9.2 平台不对服务商的收入做任何承诺,服务商收入完全取决于其服务质量、市场需求等因素。
+        </text>
+        <text class="section-text">
+          9.3 平台不保证服务商在平台上的推广效果和用户转化率。
+        </text>
+      </view>
+
+      <view class="policy-section">
+        <text class="section-title">十、争议解决</text>
+        <text class="section-text">
+          10.1 本协议的订立、效力、解释、履行及争议的解决均适用中华人民共和国法律。
+        </text>
+        <text class="section-text">
+          10.2 因本协议引起的或与本协议有关的任何争议,双方应首先友好协商解决。协商不成的,任何一方均可将争议提交本平台运营方所在地有管辖权的人民法院诉讼解决。
+        </text>
+      </view>
+
+      <view class="policy-section">
+        <text class="section-title">十一、联系我们</text>
+        <text class="section-text">
+          如您对本协议有任何疑问,请联系我们:service@etotem.com.cn
+        </text>
+        <text class="section-text">运营主体:亿图腾(北京)科技有限公司</text>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  data() { return {} }
+}
+</script>
+
+<style scoped>
+.policy-container {
+  padding: 30rpx;
+  background: #fff;
+  min-height: 100vh;
+}
+.policy-content {
+  line-height: 1.8;
+}
+.policy-title {
+  font-size: 40rpx;
+  font-weight: bold;
+  color: #333;
+  display: block;
+  text-align: center;
+  margin-bottom: 12rpx;
+}
+.policy-update {
+  font-size: 24rpx;
+  color: #999;
+  display: block;
+  text-align: center;
+  margin-bottom: 40rpx;
+}
+.policy-section {
+  margin-bottom: 30rpx;
+}
+.section-title {
+  font-size: 30rpx;
+  font-weight: bold;
+  color: #333;
+  display: block;
+  margin-bottom: 12rpx;
+}
+.section-text {
+  font-size: 26rpx;
+  color: #666;
+  display: block;
+  margin-bottom: 8rpx;
+  text-indent: 2em;
+}
+</style>

+ 19 - 0
cfc-frontend/utils/api.js

@@ -384,6 +384,25 @@ export const listFamilyMembers = () => {
   return request('/api/family/member/list', 'POST')
 }
 
+// 用户同意记录
+export const recordConsent = (data) => {
+  return request('/api/consent/record', 'POST', data)
+}
+export const withdrawConsent = (data) => {
+  return request('/api/consent/withdraw', 'POST', data)
+}
+export const getConsentStatus = () => {
+  return request('/api/consent/status', 'POST')
+}
+
+// 数据使用授权
+export const getDataPermission = () => {
+  return request('/api/data-permission/get', 'POST')
+}
+export const updateDataPermission = (data) => {
+  return request('/api/data-permission/update', 'POST', data)
+}
+
 export const switchToFamilyMember = (memberId, source) => {
   return request('/api/family/member/switch', 'POST', { memberId, source })
 }