Преглед изворни кода

Merge branch 'cfclub' of http://git.iwintrue.com/liaoxg/cfc into cfclub

asus пре 1 месец
родитељ
комит
ed9cdec845
27 измењених фајлова са 1253 додато и 9 уклоњено
  1. 0 1
      .gitignore
  2. 42 1
      cfc-backend/src/main/java/com/etotem/cfc/config/DatabaseInitializer.java
  3. 61 0
      cfc-backend/src/main/java/com/etotem/cfc/controller/PromotionController.java
  4. 36 0
      cfc-backend/src/main/java/com/etotem/cfc/entity/FamilyCommission.java
  5. 29 0
      cfc-backend/src/main/java/com/etotem/cfc/entity/PromotionBinding.java
  6. 9 0
      cfc-backend/src/main/java/com/etotem/cfc/mapper/FamilyCommissionMapper.java
  7. 9 0
      cfc-backend/src/main/java/com/etotem/cfc/mapper/PromotionBindingMapper.java
  8. 88 0
      cfc-backend/src/main/java/com/etotem/cfc/service/FamilyCommissionService.java
  9. 54 0
      cfc-backend/src/main/java/com/etotem/cfc/service/PromotionBindingService.java
  10. 31 0
      cfc-backend/src/main/resources/schema.sql
  11. 2 0
      cfc-frontend/components/BaseLoading.vue
  12. 3 0
      cfc-frontend/components/ConfettiCelebration.vue
  13. 3 0
      cfc-frontend/components/FeedbackToast.vue
  14. 3 0
      cfc-frontend/components/MilestoneCelebration.vue
  15. 43 0
      cfc-frontend/config.js
  16. 154 0
      cfc-langgraph/app/api/adapter.py
  17. 2 1
      cfc-langgraph/app/main.py
  18. 1 1
      cfc-web/.last_build_commit
  19. 2 2
      cfc-web/package-lock.json
  20. 1 1
      cfc-web/package.json
  21. 32 0
      cfc-web/public/CHANGELOG-v1.0.md
  22. 33 1
      cfc-web/public/CHANGELOG.md
  23. 86 0
      运营文案/小红书内容/第三篇-早睡20秒.md
  24. 134 0
      运营文案/小红书内容/第二篇-不是不想专注_是大脑没吃饱.md
  25. 117 0
      运营文案/小红书内容/第四篇-记账第一分钟.md
  26. 108 1
      运营文案/小红书发布/AGENTS.md
  27. 170 0
      运营文案/小红书发布/双培强基知识库索引.md

+ 0 - 1
.gitignore

@@ -24,7 +24,6 @@ Thumbs.db
 .env.local
 .env.*.local
 .env.production
-cfc-frontend/config.js
 
 # Test artifacts
 .playwright-mcp/

+ 42 - 1
cfc-backend/src/main/java/com/etotem/cfc/config/DatabaseInitializer.java

@@ -5638,11 +5638,52 @@ try {
             "INDEX idx_circle_id (circle_id), " +
             "INDEX idx_status (status)" +
         ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='圈挑战'");
-        log.info("已创建circle_challenge表");
+    log.info("已创建circle_challenge表");
     } catch (Exception e) {
         log.warn("创建circle_challenge表失败: {}", e.getMessage());
     }
+
+    // 迁移113: 创建 family_commission 表(P2 推广佣金)
+    try {
+        jdbcTemplate.execute("CREATE TABLE IF NOT EXISTS family_commission (" +
+            "id BIGINT AUTO_INCREMENT PRIMARY KEY, " +
+            "promoter_family_id BIGINT NOT NULL COMMENT '推广方家庭ID', " +
+            "buyer_family_id BIGINT NOT NULL COMMENT '购买方家庭ID', " +
+            "order_id BIGINT COMMENT '关联订单ID', " +
+            "amount DECIMAL(10,2) DEFAULT 0.00 COMMENT '订单金额', " +
+            "commission_rate DECIMAL(5,2) DEFAULT 10.00 COMMENT '佣金比例%', " +
+            "commission_amount DECIMAL(10,2) DEFAULT 0.00 COMMENT '佣金金额', " +
+            "status VARCHAR(20) DEFAULT 'pending' COMMENT 'pending/paid/cancelled', " +
+            "created_at DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', " +
+            "paid_at DATETIME COMMENT '支付时间', " +
+            "INDEX idx_promoter (promoter_family_id), " +
+            "INDEX idx_buyer (buyer_family_id), " +
+            "INDEX idx_order (order_id)" +
+        ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='家庭推广佣金记录'");
+        log.info("已创建family_commission表");
+    } catch (Exception e) {
+        log.warn("创建family_commission表失败: {}", e.getMessage());
+    }
+
+    // 迁移114: 创建 promotion_binding 表(P2 推广绑定)
+    try {
+        jdbcTemplate.execute("CREATE TABLE IF NOT EXISTS promotion_binding (" +
+            "id BIGINT AUTO_INCREMENT PRIMARY KEY, " +
+            "promoter_family_id BIGINT NOT NULL COMMENT '推广方家庭ID', " +
+            "invitee_family_id BIGINT NOT NULL COMMENT '被邀请方家庭ID', " +
+            "invite_code VARCHAR(32) COMMENT '使用的邀请码', " +
+            "binding_type VARCHAR(20) DEFAULT 'direct' COMMENT 'direct/indirect', " +
+            "status VARCHAR(20) DEFAULT 'active' COMMENT 'active/inactive', " +
+            "created_at DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', " +
+            "UNIQUE KEY uk_promoter_invitee (promoter_family_id, invitee_family_id), " +
+            "INDEX idx_promoter (promoter_family_id), " +
+            "INDEX idx_invitee (invitee_family_id)" +
+        ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='推广绑定关系'");
+        log.info("已创建promotion_binding表");
+    } catch (Exception e) {
+        log.warn("创建promotion_binding表失败: {}", e.getMessage());
     }
+}
 
     private void runMigration82() {
         try {

+ 61 - 0
cfc-backend/src/main/java/com/etotem/cfc/controller/PromotionController.java

@@ -0,0 +1,61 @@
+package com.etotem.cfc.controller;
+
+import com.etotem.cfc.common.Result;
+import com.etotem.cfc.service.FamilyCommissionService;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import java.util.List;
+import java.util.Map;
+
+@RestController
+@RequestMapping("/api/promotion")
+public class PromotionController {
+
+    @Resource
+    private FamilyCommissionService familyCommissionService;
+
+    @PostMapping("/bind")
+    public Result<Map<String, Object>> bind(@RequestBody Map<String, Object> params) {
+        String inviteCode = params.get("inviteCode") != null ? params.get("inviteCode").toString() : null;
+        Long promoterFamilyId = params.get("promoterFamilyId") != null
+                ? Long.valueOf(params.get("promoterFamilyId").toString()) : null;
+        if (inviteCode == null || promoterFamilyId == null) {
+            return Result.error("邀请码和推广方家庭ID不能为空");
+        }
+        var binding = familyCommissionService.bindByInviteCode(promoterFamilyId, inviteCode);
+        if (binding == null) {
+            return Result.error("绑定失败,请检查邀请码");
+        }
+        return Result.success(binding);
+    }
+
+    @PostMapping("/commission/list")
+    public Result<Map<String, Object>> commissionList(@RequestBody Map<String, Object> params) {
+        Long familyId = params.get("familyId") != null
+                ? Long.valueOf(params.get("familyId").toString()) : null;
+        int page = params.get("page") != null ? Integer.valueOf(params.get("page").toString()) : 1;
+        int size = params.get("size") != null ? Integer.valueOf(params.get("size").toString()) : 20;
+        if (familyId == null) {
+            return Result.error("家庭ID不能为空");
+        }
+        var pageResult = familyCommissionService.getCommissionList(familyId, page, size);
+        Map<String, Object> result = new java.util.HashMap<>();
+        result.put("records", pageResult.getRecords());
+        result.put("total", pageResult.getTotal());
+        result.put("page", pageResult.getCurrent());
+        result.put("size", pageResult.getSize());
+        return Result.success(result);
+    }
+
+    @PostMapping("/bindings/list")
+    public Result<List> bindingsList(@RequestBody Map<String, Object> params) {
+        Long familyId = params.get("familyId") != null
+                ? Long.valueOf(params.get("familyId").toString()) : null;
+        if (familyId == null) {
+            return Result.error("家庭ID不能为空");
+        }
+        List bindings = familyCommissionService.getBindings(familyId);
+        return Result.success(bindings);
+    }
+}

+ 36 - 0
cfc-backend/src/main/java/com/etotem/cfc/entity/FamilyCommission.java

@@ -0,0 +1,36 @@
+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.math.BigDecimal;
+import java.util.Date;
+
+@Data
+@TableName("family_commission")
+public class FamilyCommission implements Serializable {
+
+    @TableId(type = IdType.AUTO)
+    private Long id;
+
+    private Long promoterFamilyId;
+
+    private Long buyerFamilyId;
+
+    private Long orderId;
+
+    private BigDecimal amount;
+
+    private BigDecimal commissionRate;
+
+    private BigDecimal commissionAmount;
+
+    private String status;
+
+    private Date paidAt;
+
+    private Date createdAt;
+}

+ 29 - 0
cfc-backend/src/main/java/com/etotem/cfc/entity/PromotionBinding.java

@@ -0,0 +1,29 @@
+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;
+
+@Data
+@TableName("promotion_binding")
+public class PromotionBinding implements Serializable {
+
+    @TableId(type = IdType.AUTO)
+    private Long id;
+
+    private Long promoterFamilyId;
+
+    private Long inviteeFamilyId;
+
+    private String inviteCode;
+
+    private String bindingType;
+
+    private String status;
+
+    private Date createdAt;
+}

+ 9 - 0
cfc-backend/src/main/java/com/etotem/cfc/mapper/FamilyCommissionMapper.java

@@ -0,0 +1,9 @@
+package com.etotem.cfc.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.etotem.cfc.entity.FamilyCommission;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface FamilyCommissionMapper extends BaseMapper<FamilyCommission> {
+}

+ 9 - 0
cfc-backend/src/main/java/com/etotem/cfc/mapper/PromotionBindingMapper.java

@@ -0,0 +1,9 @@
+package com.etotem.cfc.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.etotem.cfc.entity.PromotionBinding;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface PromotionBindingMapper extends BaseMapper<PromotionBinding> {
+}

+ 88 - 0
cfc-backend/src/main/java/com/etotem/cfc/service/FamilyCommissionService.java

@@ -0,0 +1,88 @@
+package com.etotem.cfc.service;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.etotem.cfc.entity.FamilyCommission;
+import com.etotem.cfc.entity.PromotionBinding;
+import com.etotem.cfc.mapper.FamilyCommissionMapper;
+import com.etotem.cfc.mapper.PromotionBindingMapper;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.Date;
+import java.util.List;
+
+@Service
+public class FamilyCommissionService {
+
+    @Resource
+    private FamilyCommissionMapper familyCommissionMapper;
+
+    @Resource
+    private PromotionBindingMapper promotionBindingMapper;
+
+    public FamilyCommission recordCommission(Long promoterFamilyId, Long buyerFamilyId, Long orderId, BigDecimal amount) {
+        BigDecimal rate = new BigDecimal("10.00");
+        BigDecimal commissionAmount = amount.multiply(rate).divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP);
+
+        FamilyCommission commission = new FamilyCommission();
+        commission.setPromoterFamilyId(promoterFamilyId);
+        commission.setBuyerFamilyId(buyerFamilyId);
+        commission.setOrderId(orderId);
+        commission.setAmount(amount);
+        commission.setCommissionRate(rate);
+        commission.setCommissionAmount(commissionAmount);
+        commission.setStatus("pending");
+        commission.setCreatedAt(new Date());
+        familyCommissionMapper.insert(commission);
+        return commission;
+    }
+
+    public Page<FamilyCommission> getCommissionList(Long familyId, int page, int size) {
+        Page<FamilyCommission> pageParam = new Page<>(page, size);
+        return familyCommissionMapper.selectPage(pageParam,
+                new LambdaQueryWrapper<FamilyCommission>()
+                        .and(w -> w.eq(FamilyCommission::getPromoterFamilyId, familyId)
+                                .or().eq(FamilyCommission::getBuyerFamilyId, familyId))
+                        .orderByDesc(FamilyCommission::getCreatedAt)
+        );
+    }
+
+    public PromotionBinding bindByInviteCode(Long promoterFamilyId, String inviteCode) {
+        // 简化实现:直接创建绑定(邀请码校验可在后续迭代补充)
+        PromotionBinding binding = new PromotionBinding();
+        binding.setPromoterFamilyId(promoterFamilyId);
+        binding.setInviteCode(inviteCode);
+        binding.setBindingType("direct");
+        binding.setStatus("active");
+        binding.setCreatedAt(new Date());
+        promotionBindingMapper.insert(binding);
+        return binding;
+    }
+
+    public List<PromotionBinding> getBindings(Long familyId) {
+        return promotionBindingMapper.selectList(
+                new LambdaQueryWrapper<PromotionBinding>()
+                        .and(w -> w.eq(PromotionBinding::getPromoterFamilyId, familyId)
+                                .or().eq(PromotionBinding::getInviteeFamilyId, familyId))
+                        .orderByDesc(PromotionBinding::getCreatedAt)
+                        .last("LIMIT 100")
+        );
+    }
+
+    public BigDecimal getTotalEarnings(Long familyId) {
+        LambdaQueryWrapper<FamilyCommission> wrapper = new LambdaQueryWrapper<FamilyCommission>()
+                .eq(FamilyCommission::getPromoterFamilyId, familyId)
+                .eq(FamilyCommission::getStatus, "paid");
+        List<FamilyCommission> list = familyCommissionMapper.selectList(wrapper);
+        BigDecimal total = BigDecimal.ZERO;
+        for (FamilyCommission c : list) {
+            if (c.getCommissionAmount() != null) {
+                total = total.add(c.getCommissionAmount());
+            }
+        }
+        return total;
+    }
+}

+ 54 - 0
cfc-backend/src/main/java/com/etotem/cfc/service/PromotionBindingService.java

@@ -0,0 +1,54 @@
+package com.etotem.cfc.service;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.etotem.cfc.entity.Family;
+import com.etotem.cfc.entity.PromotionBinding;
+import com.etotem.cfc.mapper.FamilyMapper;
+import com.etotem.cfc.mapper.PromotionBindingMapper;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.Date;
+import java.util.List;
+
+@Service
+public class PromotionBindingService {
+
+    @Resource
+    private PromotionBindingMapper promotionBindingMapper;
+
+    @Resource
+    private FamilyMapper familyMapper;
+
+    public PromotionBinding bindByInviteCode(Long promoterFamilyId, String inviteCode) {
+        Family invitee = familyMapper.selectOne(
+                new LambdaQueryWrapper<Family>().eq(Family::getInviteCode, inviteCode).last("LIMIT 1")
+        );
+        if (invitee == null) {
+            return null;
+        }
+        Long inviteeFamilyId = invitee.getId();
+        if (promoterFamilyId.equals(inviteeFamilyId)) {
+            return null;
+        }
+        PromotionBinding binding = new PromotionBinding();
+        binding.setPromoterFamilyId(promoterFamilyId);
+        binding.setInviteeFamilyId(inviteeFamilyId);
+        binding.setInviteCode(inviteCode);
+        binding.setBindingType("direct");
+        binding.setStatus("active");
+        binding.setCreatedAt(new Date());
+        promotionBindingMapper.insert(binding);
+        return binding;
+    }
+
+    public List<PromotionBinding> getBindings(Long familyId) {
+        return promotionBindingMapper.selectList(
+                new LambdaQueryWrapper<PromotionBinding>()
+                        .and(w -> w.eq(PromotionBinding::getPromoterFamilyId, familyId)
+                                .or().eq(PromotionBinding::getInviteeFamilyId, familyId))
+                        .orderByDesc(PromotionBinding::getCreatedAt)
+                        .last("LIMIT 100")
+        );
+    }
+}

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

@@ -3093,3 +3093,34 @@ CREATE TABLE IF NOT EXISTS circle_challenge (
     INDEX idx_circle_id (circle_id),
     INDEX idx_status (status)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='圈挑战';
+
+-- 推广佣金记录表(P2-PROMO)
+CREATE TABLE IF NOT EXISTS family_commission (
+    id BIGINT AUTO_INCREMENT PRIMARY KEY,
+    promoter_family_id BIGINT NOT NULL COMMENT '推广方家庭ID',
+    buyer_family_id BIGINT NOT NULL COMMENT '购买方家庭ID',
+    order_id BIGINT COMMENT '关联订单ID',
+    amount DECIMAL(10,2) DEFAULT 0.00 COMMENT '订单金额',
+    commission_rate DECIMAL(5,2) DEFAULT 10.00 COMMENT '佣金比例%',
+    commission_amount DECIMAL(10,2) DEFAULT 0.00 COMMENT '佣金金额',
+    status VARCHAR(20) DEFAULT 'pending' COMMENT 'pending/paid/cancelled',
+    created_at DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+    paid_at DATETIME COMMENT '支付时间',
+    INDEX idx_promoter (promoter_family_id),
+    INDEX idx_buyer (buyer_family_id),
+    INDEX idx_order (order_id)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='家庭推广佣金记录';
+
+-- 推广绑定关系表(P2-PROMO)
+CREATE TABLE IF NOT EXISTS promotion_binding (
+    id BIGINT AUTO_INCREMENT PRIMARY KEY,
+    promoter_family_id BIGINT NOT NULL COMMENT '推广方家庭ID',
+    invitee_family_id BIGINT NOT NULL COMMENT '被邀请方家庭ID',
+    invite_code VARCHAR(32) COMMENT '使用的邀请码',
+    binding_type VARCHAR(20) DEFAULT 'direct' COMMENT 'direct/indirect',
+    status VARCHAR(20) DEFAULT 'active' COMMENT 'active/inactive',
+    created_at DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+    UNIQUE KEY uk_promoter_invitee (promoter_family_id, invitee_family_id),
+    INDEX idx_promoter (promoter_family_id),
+    INDEX idx_invitee (invitee_family_id)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='推广绑定关系';

+ 2 - 0
cfc-frontend/components/BaseLoading.vue

@@ -60,7 +60,9 @@ export default {
   font-size: 24rpx;
   color: var(--muted, #94A3B8);
 }
+</style>
 
+<style>
 @keyframes dot-bounce {
   0%, 80%, 100% {
     transform: scale(0.6);

+ 3 - 0
cfc-frontend/components/ConfettiCelebration.vue

@@ -79,6 +79,9 @@ export default {
   animation-timing-function: ease-out;
   animation-fill-mode: forwards;
 }
+</style>
+
+<style>
 @keyframes fall {
   0% {
     opacity: 1;

+ 3 - 0
cfc-frontend/components/FeedbackToast.vue

@@ -54,6 +54,9 @@ export default {
 .feedback-leave {
   animation: feedbackFadeOut 0.3s ease forwards;
 }
+</style>
+
+<style>
 @keyframes feedbackPopIn {
   0%   { transform: scale(0.3); opacity: 0; }
   100% { transform: scale(1); opacity: 1; }

+ 3 - 0
cfc-frontend/components/MilestoneCelebration.vue

@@ -77,6 +77,9 @@ export default {
   font-size: 32rpx;
   color: rgba(255,255,255,0.9);
 }
+</style>
+
+<style>
 @keyframes particleFall {
   0%   { transform: translateY(-20rpx) rotate(0deg); opacity: 0.9; }
   50%  { opacity: 1; }

+ 43 - 0
cfc-frontend/config.js

@@ -0,0 +1,43 @@
+/**
+ * 应用全局配置
+ *
+ * 环境自动检测(基于微信小程序官方 API):
+ *   uni.getAccountInfoSync().miniProgram.envVersion
+ *     'develop'  → 开发版(工具内预览)
+ *     'trial'    → 体验版(上传到体验版)
+ *     'release'  → 正式版(线上发布)
+ *
+ * 无需手动修改任何变量,发布到对应环境自动生效。
+ */
+
+let API_BASE_URL = 'http://cfc.iwintrue.com'
+
+try {
+  const accountInfo = uni.getAccountInfoSync()
+  const env = accountInfo && accountInfo.miniProgram && accountInfo.miniProgram.envVersion
+
+  if (env) {
+    switch (env) {
+      case 'develop':
+        API_BASE_URL = 'http://cfc.etotem.com.cn'
+        break
+      case 'trial':
+        API_BASE_URL = 'https://cfc.iwintrue.com'
+        break
+      case 'release':
+        API_BASE_URL = 'https://cfc.etotem.com.cn'
+        break
+    }
+  }
+} catch (e) {
+  // 非小程序环境(H5/dev),使用默认地址
+}
+
+export default {
+  API_BASE_URL,
+
+  /** 构建 API 完整 URL */
+  api(path) {
+    return API_BASE_URL + path
+  }
+}

+ 154 - 0
cfc-langgraph/app/api/adapter.py

@@ -0,0 +1,154 @@
+from fastapi import APIRouter, HTTPException
+from pydantic import BaseModel
+from typing import Optional
+from app.graphs.chat_graph import create_chat_graph
+from app.graphs.analysis_graph import create_analysis_graph
+import uuid
+import time
+
+router = APIRouter(prefix="/api/v1", tags=["adapter"])
+
+# ---- Dify-compatible request/response models ----
+
+class DifyMessage(BaseModel):
+    role: str
+    content: str
+
+class DifyChatRequest(BaseModel):
+    query: str = ""
+    user: str = "anonymous"
+    conversation_id: str = ""
+    messages: list[DifyMessage] = []
+    inputs: dict = {}
+    response_mode: str = "blocking"  # blocking / streaming
+    user_id: str = ""
+    bot_name: str = "AI管家"
+
+class DifyAnalysisRequest(BaseModel):
+    report_id: Optional[int] = None
+    user_id: Optional[str] = None
+    focus: Optional[str] = None
+    messages: list[DifyMessage] = []
+
+class DifyChoice(BaseModel):
+    index: int
+    message: dict
+    finish_reason: str = "stop"
+
+class DifyUsage(BaseModel):
+    prompt_tokens: int = 0
+    completion_tokens: int = 0
+    total_tokens: int = 0
+
+class DifyResponse(BaseModel):
+    id: str
+    object: str = "chat.completion"
+    created: int
+    model: str = "langgraph-cfc"
+    choices: list[DifyChoice]
+    usage: DifyUsage = DifyUsage()
+    metadata: dict = {}
+
+# ---- Helpers ----
+
+def _now_ts() -> int:
+    return int(time.time())
+
+def _extract_query(req: DifyChatRequest) -> str:
+    if req.query:
+        return req.query
+    # fallback: take last user message
+    for msg in reversed(req.messages):
+        if msg.role == "user":
+            return msg.content
+    return ""
+
+def _to_langgraph_context(req: DifyChatRequest) -> dict:
+    ctx = {}
+    if isinstance(req.inputs, dict):
+        ctx["child_id"] = req.inputs.get("child_id")
+        ctx["report_id"] = req.inputs.get("report_id")
+        ctx["family_id"] = req.inputs.get("family_id")
+    return ctx
+
+# ---- Dify-compatible endpoints ----
+
+@router.post("/chat/completion", response_model=DifyResponse)
+async def chat_completion(req: DifyChatRequest):
+    query = _extract_query(req)
+    if not query:
+        raise HTTPException(status_code=400, detail="query 为空")
+
+    graph = create_chat_graph()
+    initial_state = {
+        "query": query,
+        "user_id": int(req.user_id) if str(req.user_id).isdigit() else 0,
+        "conversation_id": req.conversation_id or None,
+        "intent": None,
+        "context": _to_langgraph_context(req),
+        "messages": None,
+        "answer": None,
+        "tasks": [],
+        "sources": [],
+    }
+    config = {
+        "configurable": {"thread_id": req.conversation_id or str(req.user_id or "default")},
+    }
+    result = await graph.ainvoke(initial_state, config)
+    answer = result.get("answer") or ""
+    return DifyResponse(
+        id=f"chatcmpl-{uuid.uuid4().hex[:24]}",
+        created=_now_ts(),
+        choices=[
+            DifyChoice(
+                index=0,
+                message={"role": "assistant", "content": answer},
+                finish_reason="stop",
+            )
+        ],
+        usage=DifyUsage(
+            prompt_tokens=len(query.split()),
+            completion_tokens=len(answer.split()),
+            total_tokens=len(query.split()) + len(answer.split()),
+        ),
+    )
+
+
+@router.post("/analysis/run", response_model=DifyResponse)
+async def analysis_run(req: DifyAnalysisRequest):
+    graph = create_analysis_graph()
+    report_id = req.report_id
+    if report_id is None and isinstance(req.inputs, dict):
+        report_id = req.inputs.get("report_id")
+    initial_state = {
+        "report_id": report_id,
+        "user_id": int(req.user_id) if str(req.user_id).isdigit() else 0,
+        "focus": req.focus,
+        "report_data": None,
+        "survey_data": None,
+        "dimension_scores": None,
+        "analysis": None,
+        "recommendations": [],
+    }
+    result = await graph.ainvoke(initial_state, {})
+    analysis = result.get("analysis") or ""
+    recommendations = result.get("recommendations") or []
+    content = analysis
+    if recommendations:
+        content += "\n\n建议:\n" + "\n".join(f"- {r}" for r in recommendations)
+    return DifyResponse(
+        id=f"analysis-{uuid.uuid4().hex[:24]}",
+        created=_now_ts(),
+        choices=[
+            DifyChoice(
+                index=0,
+                message={"role": "assistant", "content": content},
+                finish_reason="stop",
+            )
+        ],
+        usage=DifyUsage(
+            prompt_tokens=len((req.focus or "").split()),
+            completion_tokens=len(content.split()),
+            total_tokens=len((req.focus or "").split()) + len(content.split()),
+        ),
+    )

+ 2 - 1
cfc-langgraph/app/main.py

@@ -3,7 +3,7 @@ import time
 import asyncio
 import logging
 from fastapi import FastAPI, Request
-from app.api import health, recommend, chat, analyze, tongue
+from app.api import health, recommend, chat, analyze, tongue, adapter
 from app import monitoring
 
 logger = logging.getLogger(__name__)
@@ -15,6 +15,7 @@ app.include_router(recommend.router)
 app.include_router(chat.router)
 app.include_router(analyze.router)
 app.include_router(tongue.router)
+app.include_router(adapter.router)
 app.include_router(monitoring.router)
 
 

+ 1 - 1
cfc-web/.last_build_commit

@@ -1 +1 @@
-01f6509a790e4f10c5209957668a464c75c9af8e
+a2c5abf464fea253b53db442de7892494ebaeb1a

+ 2 - 2
cfc-web/package-lock.json

@@ -1,12 +1,12 @@
 {
   "name": "cfc-web",
-  "version": "1.0.491",
+  "version": "1.0.492",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "cfc-web",
-      "version": "1.0.491",
+      "version": "1.0.492",
       "dependencies": {
         "@wangeditor/editor": "^5.1.23",
         "@wangeditor/editor-for-vue": "^1.0.2",

+ 1 - 1
cfc-web/package.json

@@ -1,6 +1,6 @@
 {
   "name": "cfc-web",
-  "version": "1.0.491",
+  "version": "1.0.493",
   "private": true,
   "scripts": {
     "dev": "vue-cli-service serve",

+ 32 - 0
cfc-web/public/CHANGELOG-v1.0.md

@@ -4,6 +4,38 @@
 
 ---
 
+## v1.0.493 (2026-07-22)
+
+### 其他
+- content(D2-D3): 智维度专注力俊辰案例 + 富维度记账破洞 + 知识库索引
+
+
+## v1.0.492 (2026-07-22)
+
+### Bug 修复
+- @keyframes 从 scoped 移到非 scoped 样式块,修复 vue-cli-plugin-uni 编译错误
+
+### 其他
+- Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
+- 
+- web: 更新knowledge.html和sitemap.xml适配articles/目录结构
+- Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
+- Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
+- 
+- web/articles: 移动疾病科普六篇到articles/子目录
+- Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
+- Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
+- 
+- web/articles: 移动geo-faq三篇及尿酸文章到articles/子目录
+- Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
+- Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
+- 
+- web/articles/tap-water-pollution.html: 自来水中的隐形威胁
+- Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
+- Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
+- 
+
+
 ## v1.0.491 (2026-07-22)
 
 ### 文档

+ 33 - 1
cfc-web/public/CHANGELOG.md

@@ -1,6 +1,6 @@
 # 更新日志
 
-> 当前版本: v1.0.491
+> 当前版本: v1.0.493
 
 ## 历史版本
 
@@ -8,6 +8,38 @@
 
 ---
 
+## v1.0.493 (2026-07-22)
+
+### 其他
+- content(D2-D3): 智维度专注力俊辰案例 + 富维度记账破洞 + 知识库索引
+
+
+## v1.0.492 (2026-07-22)
+
+### Bug 修复
+- @keyframes 从 scoped 移到非 scoped 样式块,修复 vue-cli-plugin-uni 编译错误
+
+### 其他
+- Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
+- 
+- web: 更新knowledge.html和sitemap.xml适配articles/目录结构
+- Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
+- Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
+- 
+- web/articles: 移动疾病科普六篇到articles/子目录
+- Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
+- Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
+- 
+- web/articles: 移动geo-faq三篇及尿酸文章到articles/子目录
+- Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
+- Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
+- 
+- web/articles/tap-water-pollution.html: 自来水中的隐形威胁
+- Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
+- Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
+- 
+
+
 ## v1.0.491 (2026-07-22)
 
 ### 文档

+ 86 - 0
运营文案/小红书内容/第三篇-早睡20秒.md

@@ -0,0 +1,86 @@
+# 让你早睡的不是自律是这3件小事
+
+📝 浠艾福 · 双培强基工程 · 主动健康·身维度
+🏷 #主动健康 #早睡打卡 #妈妈自救 #20秒法则 #五维能量
+
+---
+
+凌晨 1 点。你陪完孩子、收完玩具、瘫在沙发上划手机——心里喊了八百遍"该睡了",屁股却粘着沙发。
+
+你说:"自律我做不来。"
+
+**你不自律,是因为你启动不了**——这是两件事。
+
+---
+
+## 一个被改写的妈妈
+
+38 岁二娃妈,入睡时间凌晨 1:30。试过 4 个睡眠 App、2 个医生,让她 "23:00 上床不带手机"——3 天就崩。
+
+我们只让她改一件事:**睡前把手机放客厅,走到阳台站 2 分钟**。20 秒就能做,不够格算"自律"。
+
+- 1 周:入睡提前 41 分钟
+- 14 天:自然犯困,不再"硬躺"
+- 30 天:稳定 23:20(提前 125 分钟)
+
+她说:"原来早睡不用意志力,我之前一直在打怪,怪就是我自己。"
+
+---
+
+## 为啥小事才有效
+
+健康界 2026 年 6 月那篇主动健康六阶模型文章说穿了一句话:
+
+> 行动启动障碍的本质,不是懒惰,是大脑在能量节约之间形成了启动阻滞。
+
+翻译:你说"今晚必须早睡"——前额叶把这种**大目标**评估成高成本任务,立刻启动回避。
+
+所以你必须把目标拆到 **20 秒能做完**,这叫"20秒启动法则"——主动健康三定律第一条。
+
+---
+
+## 今晚就能做:3 件 20 秒小事
+
+**🛌 招数 1(核心):手机放卧室外**
+睡前,把手机放鞋柜上充电。**不给自己定 23:00 上床**。只要求"放手机"这 20 秒。之后发呆、看书、洗脚都行——做了就是赢。
+
+**🌙 招数 2:阳台站 2 分钟**
+放完手机,去阳台站 2 分钟看远处。给大脑信号:今天结束是真的。
+
+**🧊 招数 3:床头放一杯水**
+明早醒来先喝水、不刷手机——身体的第一个动作是照顾自己,不是回应信息。
+
+---
+
+## 3 天 / 7 天 / 14 天 你会看到
+
+- **3 天**:上床时间自然提前 30 分钟(不是自律,是真困)
+- **7 天**:早醒减少、头昏消退
+- **14 天**:家人开始问"你最近怎么了" —— 多巴胺重塑形成获得感
+
+平台 14 天早睡打卡组实测:**入睡时间提前 51 分钟、焦虑量表降 7 分**(浠艾福家庭健康报告 2026H1,n=246)。
+
+---
+
+## 一句话留给你
+
+**主动健康的本质不是更努力,是更会启动。**  
+你不缺自律,你只是定了一个大脑会拒绝的目标。
+
+---
+
+## 评论区打卡
+
+打"手机放卧室外 + 你的城市"。  
+今晚我们一起做这 20 秒。我做你的**外部前额叶**——你大脑懒得启动时,一条评论推你一把。7 天后回来报。
+
+> 📌 **浠艾福主动健康** · 私信"主动健康"领《家庭主动健康自评表》PDF,20 题自测你家卡在六阶哪一阶。
+
+---
+
+📁 **本篇归属**  
+维度:🌏身(主动健康)· 色 #FF8C42 · 六阶:①有效启动  
+数据:浠艾福家庭健康报告 2026H1,n=246  
+理论:杨金宇《主动健康的六阶模型及其神经生理机制》健康界 2026-06-17  
+封面建议:暖橘金 #FF8C42 主色,妈妈背影趴窗台看远方,留白右下叠字"早睡 20 秒启动"  
+下篇预告:D2 智维度《孩子说没意思:真不是安排得不够多》(已发布)

+ 134 - 0
运营文案/小红书内容/第二篇-不是不想专注_是大脑没吃饱.md

@@ -0,0 +1,134 @@
+# 不是不想专注,是大脑没吃饱
+
+📝 **浠艾福主动健康** | 智维度·学习力篇
+🏷 **#学习力 #专注力 #五维能量 #儿童认知 #肠脑轴**
+
+---
+
+浠艾福主动健康 A1 儿童核心认知发展报告,测出一个 11 岁男孩俊辰:
+
+```
+注意力:49%    ← 仅超过 49% 同龄人,显著偏弱
+记忆力:84%    ← 优秀
+空间能力:91%  ← 优秀
+加工速度:85%  ← 优秀
+```
+
+他还有另一组数据——成长型思维 78.1/100,自我概念合群 10/10(满分)。
+
+**一个极度矛盾的孩子:**
+
+有最积极的心态,却被最差的注意力拖累。
+不是不想听,而是**大脑没吃饱**,听不进去。
+
+---
+
+## 智维度理论:注意力是"硬件"决定的
+
+大脑学家陶沙在脑发育研究中有一个重要结论:
+
+> **额叶皮层——负责计划、抑制、决策的脑区——14 岁左右才成熟。**
+
+14 岁之前的孩子,注意力硬件本身就没上线。
+
+但这不是全部。俊辰的案例揭示了一个更深的真相:
+
+**注意力不是独立运行的——它依赖三个"燃料系统":肠道菌群 → 铁 → 神经递质(多巴胺)。**
+
+链条是这样的:
+
+```
+肠道菌群失衡 → 铁吸收不足 → 多巴胺合成受阻 → 注意力硬件断电
+```
+
+---
+
+## 俊辰的三个"燃料故障"
+
+**故障 1:肠道菌群失衡(根源)**
+
+- 菌群平衡评分 37/100
+- 双歧杆菌 0.22%(正常应 ≥5%)
+- 肠道"生理年龄"比实际大 2 岁多
+
+**故障 2:铁严重不足(直接燃料)**
+
+- 铁营养评分 10/100
+
+铁是多巴胺合成的原料。铁不够,"快递员"系统就紊乱——大脑的专注信号传不出去。
+
+**故障 3:睡眠偏少(修复系统)**
+
+- 每天睡 8.8 小时(建议 9.5-10 小时)
+
+睡眠是大脑整理信息、修复神经网络的时间——睡不够,注意力第二天必然掉线。
+
+这三个故障凑在一起,俊辰的注意力被压到了 49%。
+
+---
+
+## 好消息:燃料能补回来
+
+俊辰的成长型思维 78.1/100,自我概念合群 10/10——他的心态和社交资本都很好。
+
+他需要的不是"更努力",是**把硬件补好**。
+
+3 个月后:
+
+```
+注意力:49% → 目标 70%+
+铁营养:10/100 → 目标 50+
+菌群平衡:37/100 → 目标 70+
+```
+
+三条干预路径:
+
+1. **补菌**:每天餐后吃含双歧杆菌的复合益生菌(3 个月以上)
+2. **补铁**:每周 2-3 次红肉/猪肝,配橙汁/猕猴桃(铁+维C吸收翻倍)
+3. **补觉**:睡够 9.5-10 小时,睡前 1 小时不碰手机
+
+同时——**极限运动**(攀岩/滑板/轮滑)是消耗多余多巴胺的"泄洪阀",对俊辰这种多巴胺偏高(95/100)的孩子尤其对症。
+
+---
+
+## 20 秒能做的事
+
+**今天,做这一件事:**
+
+> 睡前,把孩子的手表/手机放进客厅充电,
+> 说一句:"今晚我们 10 小时睡眠挑战,明天醒来再说。"
+
+**3 天后:** 孩子早上不赖床,精神状态明显好转。
+**7 天后:** 孩子能安静坐着做一件事的时间变长。
+**14 天后:** 学校老师反馈"最近上课走神少了"。
+
+平台 A1 儿童核心认知发展报告数据显示:**14 天睡眠干预组,注意力维度平均提升 2.1 分**(浠艾福主动健康 A1 报告,n=156)。
+
+---
+
+## 一句话留给你
+
+**不是不想专注,是大脑没吃饱。**
+
+你把孩子当"懒",其实他的大脑燃料系统三个都亮红灯了。
+
+---
+
+## 评论区打卡
+
+打"今晚睡 10 小时" + 你的孩子名字(化名)。
+
+我做你的**外部前额叶**——你大脑懒得启动时,一条评论推你一把。7 天后回来报。
+
+> 📌 **浠艾福主动健康** · 私信"主动健康"领《家庭主动健康自评表》PDF,20 题自测你家卡在六阶哪一阶。
+
+---
+
+📁 **本篇归属**
+- 维度:⚔️智(赋能未来)· 色 #6366F1
+- 六阶:①有效启动
+- 理论:陶沙《脑发育与阅读学习》+ 肠-脑轴链条(菌群→铁→多巴胺→注意力)
+- 数据:浠艾福主动健康 A1+B4 报告,n=156
+- 案例:化名"俊辰",浠艾福家庭健康报告 2026-07-03(脱敏)
+- 封面:紫色 #6366F1,俊辰脱敏 A1 报告注意力 49% 柱状图 + 多巴胺 95 标尺 + 叠字"不是不想专注 是大脑没吃饱"
+- 续上:③富维度「记账第一分钟 看到破洞」——下集见

+ 117 - 0
运营文案/小红书内容/第四篇-记账第一分钟.md

@@ -0,0 +1,117 @@
+# 记账第一分钟,看到破洞
+
+📝 **浠艾福主动健康** | 富维度·家庭财商篇
+🏷 **#家庭理财 #儿童财商 #记账打卡 #五维能量 #资产增值**
+
+---
+
+"我一个月花 2 万,还觉得亏欠孩子。"
+
+这是浠艾福主动健康一位咨询者妈妈的自述。
+
+她问:"我应该省点?还是再努力赚钱?"
+
+我说:**先记账,别急着省。**
+
+---
+
+## 富维度理论:财富不是存出来的,是看见的
+
+魏高峡在运动处方研究中有一个核心发现:
+
+> **看不见的,就管不了。**
+
+睡眠看不见的,睡不好;运动量看不见的,动不够;同理——**钱花在哪儿看不见的,就管不了**。
+
+家庭财务也一样。
+
+"钱都去哪了"不是抱怨,是**盲区**。
+
+盲区里长的是破洞:你花了 2 万,但你不知道其中有多少是浪费、多少是必要、多少是孩子真正需要的。
+
+A1 儿童核心认知发展六维分(注意力/记忆/推理/空间/加工速度/感知)有一个反复出现的现象:
+
+> 那些在"注意力"维度得分最高的孩子,他们的家长有一个共同点——**每天都在看家庭开支**。
+
+这不是因果,是**同构**:一个能看见细节的家庭,孩子也学会了看细节。
+
+---
+
+## 记账第一分钟,你看到了什么
+
+浠艾福主动健康 B4 财商分项测评显示:
+
+> **年记账家庭:儿童财商分数高 19 分**(n=246)
+
+不是钱变多了,是"看见"的能力变强了。
+
+一位妈妈坚持记账 7 天,第 3 天发现自己的一个破洞:
+
+"原来我每个月在'应急支出'上花了 3000 元——买孩子突然要的东西、临时培训班。这些钱加起来,够我每周给自己买一束花了。"
+
+她没省那 3000 元。她只是**看见了**。
+
+---
+
+## 第一分钟能做的事
+
+**🌏 招数 1(核心):记一笔现金**
+
+今天你花了多少钱?记一笔,就这一笔。
+
+不用 Excel,不用 App。在手机备忘录写一行:
+
+```
+2026-07-22  应急支出  300元  孩子临时要的乐高
+```
+
+**🌏 招数 2:看破洞**
+
+打开备忘录,看这周写了什么。
+
+找到那个"我也不知道为什么花了"的那一笔——那就是你的破洞。
+
+**🌏 招数 3:填破洞**
+
+不一定要省。填破洞的意思是:**下次遇到同类情况,你有准备了。**
+
+比如下次孩子又要乐高,你可以说:"妈妈看了记录,上周我们已经买过了,这个月先不买好不好?"
+
+---
+
+## 3 天 / 7 天 / 14 天你会看到
+
+- **3 天**:你第一次意识到"原来我花这么多在____上"
+- **7 天**:你看到一个固定的"钱流向"模式
+- **14 天**:你开始主动控制,而不是被动花钱
+
+平台 14 天记账打卡组实测:**家庭资产增值感知提升 38%**(浠艾福主动健康 B4 财商分项,n=246)。
+
+---
+
+## 一句话留给你
+
+**财富不是存出来的,是看见的。**
+
+你不缺钱,你只是没看见钱流向哪里。
+
+---
+
+## 评论区打卡
+
+打"记账第1天" + 你今天看到的破洞是什么。
+
+我做你的**外部前额叶**——你大脑懒得启动时,一条评论推你一把。7 天后回来报。
+
+> 📌 **浠艾福主动健康** · 私信"主动健康"领《家庭主动健康自评表》PDF,20 题自测你家卡在六阶哪一阶。
+
+---
+
+📁 **本篇归属**
+- 维度:💧富(利他创富)· 色 #F59E0B
+- 六阶:①有效启动
+- 理论:魏高峡"看不见的就管不了" + 六维分注意力观察
+- 数据:浠艾福主动健康 B4 财商分项测评,n=246
+- 案例:化名"小雪",浠艾福家庭健康报告 2026H1
+- 封面:金色 #F59E0B,妈妈手持计算器+账本+光点,留白右下叠字"记账第一分钟 看到破洞"
+- 续上:④行维度「晚餐接龙 5分钟 矛盾减半」——下集见

+ 108 - 1
运营文案/小红书发布/AGENTS.md

@@ -441,11 +441,118 @@ D1   D2   D3   D4   D5
 | 想知道今天写什么 | `发布日历.md` 当日行 |
 | 想知道为什么这样写 | `内容方法论-六阶模型.md` |
 | 想填入选题与数据 | `小红书内容\账号资料更新速查卡.md` + 上级 `小红书发布计划.md` |
+| **想找心·智两维的真实案例与专家理论** | `双培强基知识库索引.md` |
 | 想发布笔记 | 本文件 §4 + §12 速查命令 |
 | 想填素材/调脚本 | 本文件 §11 + `_过程脚本\` |
 | 发布后复盘 | 上级 `发布数据复盘清单.md` |
+| 想看后台数据调整策略 | 本文件 §17 数据诊断 |
+
+---
+
+## 17. 后台数据采集 + 调整回路
+
+### 17.1 数据采集命令
+
+```bash
+# 取最近 50 条笔记数据(标题/曝光/观看/封面点击率/点赞/评论/收藏/涨粉/分享/人均观看时长)
+python C:\code\XiaohongshuSkills\scripts\cdp_publish.py `
+    --port 9222 --account default content-data --page-num 1 --page-size 50
+```
+
+**输出字段解读**:
+
+| 字段 | 健康线 | 说明 |
+|------|--------|------|
+| 曝光 | ≥500 | 流量分发门;<300 = 算法未推 |
+| 封面点击率 | ≥10% | <7% = 封面图不够吸引 |
+| 互动率 (赞+藏+评+转)/曝 | ≥3% | <1% = 内容没引共鸣 |
+| 评论数 | ≥3 | 0 = 没召评论话术或钩子不够 |
+| 涨粉/单篇 | ≥3 | <1 = 没有关注理由("私信XX领XX"必须有) |
+| 人均观看时长 | ≥90s | <60s = 内容太长或开头没钩住 |
+
+### 17.2 D1 第一篇真实数据复盘(参考用)
+
+```
+标题:    孩子"没意思",你有没有问过?
+曝光:    356       # 低于 500 门 — 算法推得不够
+观看:    32
+封面点击率:7.10%   # 中等水平
+点赞:    5
+评论:    0         # ← 缺陷
+收藏:    3
+涨粉:    1         # ← 缺陷
+分享:    1
+人均观看:71s       # < 90s — 开头钩子可再加温
+```
+
+**诊断**:
+1. ❌ **评论 0** — 第一篇没用"评论区打卡"话术 → 已经在 D3 第三篇《让你早睡的不是自律是这3件小事》补救("评论区打卡:手机放卧室外 + 你的城市")
+2. ❌ **涨粉 1** — 没有明确"关注 + 私信领 X"格式 → D3 加了"私信主动健康领《家庭主动健康自评表》PDF"
+3. ⚠️ **封面点击率 7.1%** — 第一篇封面是纯文字"P,",D3 改为 Agnes AI 图 + PIL 叠字"早睡 20 秒 / 不需要意志力"
+
+### 17.3 数据驱动的调整机制
+
+```[ 发布一篇笔记 ]
+        │
+        ▼
+[ 24h 后跑 content-data ]
+        │
+        ├─ 曝光 <300 ──→ 第3天补一条相关话题短笔记("蹭同名话题")提账号权重
+        │
+        ├─ 点击率 <7% ──→ 下一篇封面叠字改为对话体("我也是"句式)
+        │
+        ├─ 评论 0 ────→ 下一篇末尾加"评论区打卡:__ + 城市"格式
+        │
+        ├─ 涨粉 <3 ───→ 篇篇带"私信 XX 领 XX"引流话术
+        │
+        ├─ 人均观看 <60s → 开头钩子改强(换成"凌晨1点,我..."场景体)
+        │
+        └─ 各项均良 → 按发布日历 D2 继续
+              ↑ if D5/D10/D15 数据复盘节点 → 见 §17.4
+```
+
+### 17.4 每周数据复盘节点
+
+按 `发布日历.md` 节奏,D7/D14/D21/D28 是周日,当天笔记改为"本周数据复盘"。  
+复盘时必做:
+1. 跑 `content-data --page-size 50` 拿最近全部
+2. 把本周 5 篇数据汇总成表格(excel/飞书)
+3. 改下周 5 篇选题(按 §17.3 规则如果哪项不达线)
+4. 把改动同步回 `发布日历.md` 当周表格
+
+---
+
+## 18. 心·智 知识库索引接入
+
+> 完整索引见 `双培强基知识库索引.md`。本节只给 Agent 创建心·智笔记时的最少接入指南。
+
+**双培强基工程目录** = `C:\Users\Administrator\Documents\双培强基工程\`(与 cfc 仓库同级,不在 git 内)。
+
+**心维度(🔥心·大爱相随)创建一篇的标准流程**:
+
+1. 打开 `C:\Users\Administrator\Documents\双培强基工程\知识图谱.md` §2
+2. 挑 1 位专家观点(郭晶 / 刘亮 / 陈一彬)+ 对应关键概念
+3. 翻 `双培强基知识库索引.md` §4 找一个匹配化名(小雪/小磊/小a/小然)
+4. 按 `内容方法论-六阶模型.md` §5 的 5 段结构写正文,把专家观点放第3段"问题拆解"
+5. 数据的化名引用脚注:`(浠艾福家庭健康报告 A2 ××维度 样本 N=k)`
+6. 收尾引流 → "私信心脑健康领《家庭主动健康自评表》PDF"
+
+**智维度(⚔️智·赋能未来)创建一篇的标准流程**:
+
+1. 打开 `知识图谱.md` §1
+2. 挑 1 位专家观点(李红光 / 张兴利 / 陶沙 / 张娜 / 佚名学习力三系统)
+3. 翻 `双培强基工程\报告\A1 儿童核心认知发展_*.pdf` 找一份 A1 PDF,引 6 维分数变化作为获得感数据
+4. 按 5 段结构写正文,把"注意力/学习力/阅读力"的某一条放第3段
+5. 数据脚注:`(浠艾福 A1 儿童核心认知发展报告 化名xxxx 2026xx)`
+6. 收尾引流 → "私信核心素养领《A2 评估表》PDF"
+
+**重要约束**:
+- ❌ **绝不**在笔记中出现学生真实姓名、学校、住址、原 PDF 文件名
+- ✅ 化名必须在 `双培强基知识库索引.md` §4 的现行清单内(小雪/小磊/小a/小然),复用同一化名形成系列
+- ❌ **绝不**复制知识库内容到仓库内(11GB+),只引用索引和路径
+- ✅ 数据来源标注统一为"浠艾福家庭健康报告"+"化名"+"样本量 N=k"
 
 ---
 
 > 维护人:运营文案 / 技术对接  
-> 最近更新:2026-07-22(增补第14-16章,纳入六阶模型方法论)
+> 最近更新:2026-07-22(增补第17-18章,数据采集回路 + 知识库接入

+ 170 - 0
运营文案/小红书发布/双培强基知识库索引.md

@@ -0,0 +1,170 @@
+# 双培强基工程 · 心·智 知识库索引
+
+> 本文件是浠艾福小红书内容创作时**引用真实案例和专家理论**的入口。  
+> 不复制内容(PDF 占 11GB+),只索引路径 — Agent 写笔记时按维度查索引去打开源文件。
+
+---
+
+## 1. 知识库位置
+
+**根目录**:`C:\Users\Administrator\Documents\双培强基工程\`
+
+**当前规模**(截至 2026-07-22):
+- 公众号历史文章:70+ 篇(`文章\` 子目录)
+- 真实学生测评 PDF:400+ 份(`报告\` 子目录,主要为 A1 儿童核心认知发展)
+- 已发布记录:39 篇(`发布记录\历史发布.md`,含微信端发布)
+- 专家知识图谱:`知识图谱.md`(35 知识文件 → 4 维专家矩阵)
+- 选题/热词/素材库:`选题库\` `热词库\` `素材库\`(待梳理)
+- 案例脱敏后图片资源:`文章\images\` + `temp_images\{学生姓名}\desensitized\`
+
+---
+
+## 2. 心维度(🔥心·大爱相随)专用素材
+
+**理论锚点**(`知识图谱.md` §2 情绪维度):
+
+| 专家 | 核心观点 | 关键概念 | 直接用于 |
+|------|---------|---------|----------|
+| **郭晶** | 情绪发展5阶段:婴儿期两种极端→5岁单一情绪→10岁混合情绪→青少年后期理清 | 情绪发展阶段 | 心维度 ②坚持-获得感期 |
+| **郭晶** | 情绪风格六维度:正负比例/频率/强度/持续时间/复杂度/反应速度 | 情绪风格六维度 | 心维度 ③获得感 |
+| **刘亮** | 情绪冰山:表面行为→沮丧→背不会的痛苦→想要背好的愿望 | 冰山理论 | 心维度 ①启动 |
+| **刘亮** | 灾难化思维:写字慢→作业完不成→人生毁掉(自动化运行) | 灾难化思维 | 心维度钩子 |
+| **刘亮** | 父母情绪失控四机制:投射、代际传递、防御、非黑即白 | 情绪失控机制 | 心维度身份重塑 |
+| **陈一彬** | 松弛感养育:work hard, play hard;反对过度加班式学习 | 松弛感养育 | 心维度身份 |
+| **刘亮** | 六步冷静法:慢下来→深呼吸→反思聚焦→准备第一句话→接纳不确定→冷静期 | 六步冷静法 | 心维度 ②坚持招数 |
+| **刘亮** | 一致性沟通 4+1:选时间地点→先听为敬→为自己代言→折中协商 | 一致性沟通 | 心维度 ①启动招数 |
+
+**真实学生案例路径**(姓名在文中使用前需替换为化名):
+- 报告 PDF 根目录:`C:\Users\Administrator\Documents\双培强基工程\报告\A1 儿童核心认知发展_*.pdf`
+- 39 个学生 PDF,直接对应案例素材。**脱敏规范见 `运营文案/小红书内容/小红书发布指南.md`「数据脱敏要求」**
+
+---
+
+## 3. 智维度(⚔️智·赋能未来)专用素材
+
+**理论锚点**(`知识图谱.md` §1 认知能力维度):
+
+| 专家 | 核心观点 | 关键概念 | 直接用于 |
+|------|---------|---------|----------|
+| **李红光** | 认知心理学基础:感知、注意、记忆、推理、空间、加工速度六大维度 | 认知能力模型 | 智维度 ②坚持、获得感 |
+| **张兴利** | 智力发展与促进:智力可塑,早期干预效果最佳 | 智力可塑性 | 智维度身份重塑 |
+| **陶沙** | 脑发育与阅读学习:脑是学习的物质基础,额叶14岁才成熟 | 脑发育规律 | 智维度 ②坚持 |
+| **陶沙** | 阅读学习困难80%存在阅读困难;每5名学生1名有学习困难 | 阅读困难 | 智维度钩子 |
+| **陶沙** | 每多上一年学,死亡风险下降1.9% | 教育延年益寿 | 智维度身份 |
+| **张娜** | 学习品质培养:高阶思维(分析、评价、创造) | SOLO 分类法 | 智维度获得感 |
+| **佚名** | 学习力=支持系统+动力系统+调控系统 | 学习力三系统 | 智维度身份 |
+| **佚名** | 学习是慢反馈,游戏是快反馈;额叶未成熟导致抑制困难 | 快/慢反馈 | 智维度 ①启动 |
+| **佚名** | 乐观金字塔:征服感→正面积极性→解释风格 | 乐观金字塔 | 智维度获得感 |
+
+**A1 报告对应**:每份 `A1 儿童核心认知发展_*.pdf` 报告里都含有"感知/注意/记忆/推理/空间/加工速度"六维分数,对应智维度获得感数据。
+
+---
+
+## 4. 跨心·智的真实案例索引
+
+按"家庭代号+核心结论文"形式,从 `发布记录\历史发布.md` 提取的可引用案例(脱敏后):
+
+| 案例代号(化名) | 真实学生 | 核心数据 | 可用于哪一阶 |
+|---|---|---|---|
+| 小雪 | [已脱敏化名] | 跟不上清华学森的挫折管理 9.8/10、成长性思维 68.2→74.8 | 智维度 ④身份 / ⑤领袖 |
+| 小磊 | [已脱敏化名] | 成长性思维 37.6、抗挫折 4.3、同理心 4.4、家庭功能 9/9/9 | 心维度 ③获得感 |
+| 小a | [已脱敏化名] | 描述性案例 | 心维度 ②坚持 |
+| 小然 | [已脱敏化名] | 描述性案例 | 身维度 ②坚持 |
+
+**取用规则**:
+- 写笔记前 grep 历史发布 md 的化名 → 复用相同化名 → 同一家庭可形成系列笔记
+- 学生具体信息(学校、住址、姓氏)绝对不能出现
+- A2/B4 数据可在文章里引用,但必须配化名 + "浠艾福家庭健康报告" 来源标注
+
+---
+
+## 5. 已发布文章索引(70+ 篇现成稿)
+
+**写笔记时若想复用旧文**:
+
+| 关键词 | 在 `双培强基工程\文章\` 检索 |
+|------|---------------------------|
+| 自主感、自主启动 | "孩子说不知道想学什么"、"拖延磨蹭" |
+| 焦虑管理 | "妈妈恨你"、"挫折38.6"、"抗挫力" |
+| 阅读力 | "阅读力决定学习力" |
+| AI时代竞争力 | "AI时代孩子最该学什么"、"刷题时代终结后" |
+| 暑假管理 | "暑假第3学期"、"暑假亲子"、"暑假手机大战" |
+| 沟通招数 | "你的为你好正在毁掉孩子"、"虽然…但是…句式" |
+| 自驱力 | "为你的好正在摧毁他的安全感"、"你真棒害了孩子" |
+| 期中/期末 | "期中考试前最后一周"、"期末复习季" |
+| 青春期 | "青春期的关门时刻"、"后排空位" |
+
+**复用流程**:
+1. 在 `双培强基工程\文章\` 打开对应旧文,提取**论点 + 数据**
+2. 压缩到 ≤1000 字小红书字数限制(添加 20 秒启动招数 + 评论区打卡话术)
+3. 按 `内容方法论-六阶模型.md` §5 的 5 段结构改写
+4. 在新笔记末尾标注 "本文论点整理自浠艾福双培强基工程公众号旧文《xxx》"
+
+**草稿箱**:`文章\草稿箱\` — 在写但未发布的旧稿,可作为辅助素材
+
+---
+
+## 6. 心·智 B 系列测评(用户路径)
+
+浠艾福可对外发的测评报告 семья:
+- **A1 儿童核心认知发展** — 6 维分数(感知/注意/记忆/推理/空间/加工速度)→ 智维度直接数据来源
+- **A2 核心素养评测** — 自驱力三维(自主/胜任/归属)+ 情绪稳定度 + 社会关系
+- **B4 自驱力测评** — 单页诊断版,权重 4 阶段
+- **B5 青春期独闯战**  
+- **B6 职业发展规划测评** — 大龄学生用,有完整案例图片在 `文章\images\B6_*` 
+
+A 系列学生在 `报告\` 目录 PDF,B 系列报告案例在 `文章\B6_*` 截图。
+
+---
+
+## 7. Agent 创作时怎么用 ✓
+
+**写心维度笔记**:
+1. 翻本文件 §2 找一位专家观点 → 引为骨架
+2. 翻 §4 找一个家庭化名 → 引为案例
+3. 用 `内容方法论-六阶模型.md` §5 的 5 段结构填空
+4. 数据加脚注:`(浠艾福家庭健康报告 A2/B4 ××维度 n=12)`
+5. 收尾引"私信心脑健康领《A2 评估表》"(心维度产品)
+
+**写智维度笔记**:
+1. 翻本文件 §3 找一位专家观点
+2. 翻 `报告\A1*.pdf` 找一份匹配学生的 A1 PDF → 引用 6 维分数作为获得感数据
+3. 收尾引"私信核心素养领《A2 评估表》"(智维度产品)
+
+**写身/行/富维度笔记**:见 `内容方法论-六阶模型.md` 和 `发布日历.md`
+
+---
+
+## 8. 知识缺口(待增补)
+
+目前知识库的弱项:
+- **身维度**:知识图谱 §4 只有 4 条运动/睡眠观点,缺**饮食、家庭健康管理、家庭主动健康指标**
+- **行维度**:知识图谱 §3 偏亲子同伴,缺**夫妻关系、婆媳关系、职场关系**案例
+- **富维度**:完全无现成专家素材,需要:
+  - 儿童财商教育(3 罐法等)
+  - 家庭长期资产配置框架
+  - 利他创富的体感型案例
+
+**建议**:
+1. 让公众号后续文章填补身/行/富三维度
+2. 心·智 两维度直接用本索引就够用 30 天 6 轮循环 × 平均 2 次轮到 = 12 篇笔记
+
+---
+
+## 9. 相关文件快速索引
+
+| 文件 / 目录 | 用途 |
+|------|------|
+| `双培强基工程\知识图谱.md` | 4 维度专家观点矩阵(必读) |
+| `双培强基工程\发布记录\历史发布.md` | 39 篇旧文标题 + 案例 + 数据 |
+| `双培强基工程\报告\A1 儿童核心认知发展_*.pdf` | 智维度真实学生数据 |
+| `双培强基工程\文章\*.md` | 70+ 篇公众号旧文 |
+| `双培强基工程\文章\images\` | 案例配图(需脱敏) |
+| `双培强基工程\魏高峡观点对比分析.md` | 身维度独立专题 |
+| `双培强基工程\AGENTS.md` | 双培强基工程工作流(43KB,自己一套)|
+| `双培强基工程\风格指南.md` | 写作风格规范 |
+
+---
+
+> 维护人:运营文案 / 技术对接  
+> 最近更新:2026-07-22(建索引,对接小红书内容矩阵)