Просмотр исходного кода

chore: auto bump version and changelog [skip ci]

iwt 1 месяц назад
Родитель
Сommit
7b37b7a318

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

@@ -10974,6 +10974,7 @@ sqls.add("INSERT IGNORE INTO health_norm_reference (dimension, gender, age_min,
             // 表已存在,忽略
         }
 
+<<<<<<< Updated upstream
         // 迁移318: 创建 DOA 个人目标-周计划-周复盘三表(家庭打卡个人目标模块,2026-09-12)
         try {
             jdbcTemplate.execute("CREATE TABLE IF NOT EXISTS doa_stage (" +
@@ -11035,6 +11036,111 @@ sqls.add("INSERT IGNORE INTO health_norm_reference (dimension, gender, age_min,
             log.info("迁移318: 已创建 doa_week 表");
         } catch (Exception e) {
             log.warn("迁移318: 创建 doa_week 表失败: {}", e.getMessage());
+=======
+        // 迁移318: 基础管理分组挂载「系统提示词」菜单(cfc-web菜单树同步)
+        migrateSystemPromptMenu();
+
+        // 迁移319: system_prompts 插入 health_plan 提示词种子(仅当不存在时)
+        try {
+            Integer count = jdbcTemplate.queryForObject(
+                "SELECT COUNT(*) FROM system_prompts WHERE prompt_key = 'health_plan'", Integer.class);
+            if (count == null || count == 0) {
+                jdbcTemplate.update(
+                    "INSERT INTO system_prompts (prompt_key, title, content, default_content, version, status, remark) VALUES (?, ?, ?, ?, 1, 1, ?)",
+                    "health_plan", "健康方案生成",
+                    "你是一个专业的家庭健康方案规划师。根据用户的健康数据和目标,生成结构化的改善方案。\n\n" +
+                    "## 输出格式(必须严格遵守 JSON)\n\n" +
+                    "```\n" +
+                    "{\n" +
+                    "  \"overview\": \"总体概述(100字以内,说明方案目标和核心策略)\",\n" +
+                    "  \"sections\": [\n" +
+                    "    {\n" +
+                    "      \"key\": \"nutrition\",\n" +
+                    "      \"title\": \"营养补充建议\",\n" +
+                    "      \"content\": \"Markdown 格式的详细内容,包含具体产品推荐、用量、服用时间\",\n" +
+                    "      \"items\": [{\"name\": \"产品名\", \"dosage\": \"用量\", \"timing\": \"服用时间\", \"reason\": \"推荐理由\"}]\n" +
+                    "    },\n" +
+                    "    {\n" +
+                    "      \"key\": \"diet\",\n" +
+                    "      \"title\": \"饮食建议\",\n" +
+                    "      \"content\": \"Markdown 格式的餐饮建议,包含早餐/午餐/晚餐建议\",\n" +
+                    "      \"items\": [{\"meal\": \"餐型\", \"food\": \"食物建议\", \"notes\": \"注意事项\"}]\n" +
+                    "    },\n" +
+                    "    {\n" +
+                    "      \"key\": \"exercise\",\n" +
+                    "      \"title\": \"运动计划\",\n" +
+                    "      \"content\": \"Markdown 格式的运动建议,包含频率、时长、类型\",\n" +
+                    "      \"items\": [{\"type\": \"运动类型\", \"duration\": \"时长\", \"frequency\": \"频率\", \"notes\": \"注意事项\"}]\n" +
+                    "    }\n" +
+                    "  ]\n" +
+                    "}\n" +
+                    "```\n\n" +
+                    "## 原则\n" +
+                    "1. 基于实际数据给出建议,不编造\n" +
+                    "2. 引用知识库时标注来源\n" +
+                    "3. 建议要具体可执行,避免空泛\n" +
+                    "4. 营养补充部分要具体到品牌/产品类型和用量\n" +
+                    "5. 严重健康问题建议咨询医生",
+                    "你是一个专业的家庭健康方案规划师。根据用户的健康数据和目标,生成结构化的改善方案。",
+                    "健康方案生成 prompt(营养+饮食+运动三段结构化输出)");
+                log.info("迁移319: 已插入 health_plan 提示词种子数据");
+            } else {
+                log.info("迁移319: health_plan 提示词已存在,跳过");
+            }
+        } catch (Exception e) {
+            log.warn("迁移319: 插入 health_plan 提示词种子数据失败: {}", e.getMessage());
+        }
+    }
+
+        // 迁移318: 基础管理分组挂载「系统提示词」菜单(cfc-web菜单树同步)
+        migrateSystemPromptMenu();
+
+    }
+
+    /**
+     * 迁移318: 系统配置·基础管理 挂载 系统提示词 菜单(幂等)
+     * 仅当 sys_menu 表已有数据(即角色授权已存在)时补授权,避免破坏兼容逻辑
+     */
+    private void migrateSystemPromptMenu() {
+        try {
+            Long baseManageId = queryMenuId("SELECT id FROM sys_menu WHERE title='基础管理'");
+            if (baseManageId == null) {
+                log.warn("迁移318: 未找到基础管理分组,跳过");
+                return;
+            }
+            Long promptId = insertSystemPromptMenu(baseManageId);
+            if (promptId != null) {
+                Integer grantCount = jdbcTemplate.queryForObject("SELECT COUNT(*) FROM sys_role_menu", Integer.class);
+                if (grantCount != null && grantCount > 0) {
+                    grantMenuToRole("admin", promptId);
+                    log.info("迁移318: 已授权 admin 角色");
+                }
+                log.info("迁移318: 系统提示词菜单挂载完成 id={}", promptId);
+            }
+        } catch (Exception e) {
+            log.warn("迁移318失败: {}", e.getMessage());
+        }
+    }
+
+    /**
+     * 按 path 幂等插入系统提示词叶子菜单,返回菜单 id(已存在返回原 id)
+     */
+    private Long insertSystemPromptMenu(Long parentId) {
+        Long existed = queryMenuId("SELECT id FROM sys_menu WHERE path='/system-prompt'");
+        if (existed != null) {
+            return existed;
+        }
+        try {
+            jdbcTemplate.update(
+                    "INSERT INTO sys_menu (parent_id, title, label, path, icon, perm, sort, visible) VALUES (?, NULL, '系统提示词', '/system-prompt', 'el-icon-chat-line-square', 'system:base', 8, 1)",
+                    parentId);
+            Long id = jdbcTemplate.queryForObject("SELECT LAST_INSERT_ID()", Long.class);
+            log.info("迁移318: 已挂载系统提示词菜单");
+            return id;
+        } catch (Exception e) {
+            log.warn("迁移318: 挂载菜单失败: {}", e.getMessage());
+            return null;
+>>>>>>> Stashed changes
         }
     }
 

+ 5 - 3
cfc-langgraph/app/graphs/health_plan_graph.py

@@ -18,6 +18,7 @@ from langchain_core.messages import SystemMessage, HumanMessage
 from app.rag.retriever import RagRetriever
 from app.config import settings
 from app.tools.java_client import JavaClient
+from app.prompt_service import get_prompt
 import logging
 
 logger = logging.getLogger(__name__)
@@ -186,9 +187,10 @@ async def collect_data(state: PlanState) -> dict:
     }
 
 
-def build_prompt(state: PlanState) -> str:
+async def build_prompt(state: PlanState) -> str:
     """组装 LLM prompt"""
-    parts = [DEFAULT_PROMPT]
+    base_prompt = await get_prompt("health_plan") or DEFAULT_PROMPT
+    parts = [base_prompt]
 
     parts.append(f"\n## 用户目标\n{state['goal']}")
     if state.get("dimensions"):
@@ -226,7 +228,7 @@ async def generate_plan(state: PlanState) -> dict:
         base_url=settings.llm_base_url,
         temperature=0.3,
     )
-    prompt = build_prompt(state)
+    prompt = await build_prompt(state)
     messages = [SystemMessage(content=prompt)]
     try:
         response = await llm.ainvoke(messages)

+ 1 - 1
cfc-web/.last_build_commit

@@ -1 +1 @@
-4ecfa50c72a9daf566a414cffd9ca9b9256f4391
+227168911b15f7bdf494395241fc975e14b4230b

+ 1 - 1
cfc-web/package.json

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

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

@@ -4,6 +4,45 @@
 
 ---
 
+## v1.0.1383 (2026-09-13)
+
+### 文档
+- add vendor order review spec, plan, and API reference entries
+- 登记DOA接口+统一能登录/不能登录用户口径规范
+
+### 重构
+- clean up review logic (remove unused var, fix computed, add log separators)
+
+### 新功能
+- add vendor order review page and entry
+- add vendorId to order detail response for permission check
+- 新增doa-stage-detail详情页+实体memberUserId字段
+- 新增doa-week-edit周计划复盘编辑页
+- 新增doa-stage-create创建阶段页
+- 新增doa-index家庭总览页
+- 前端API封装+页面注册+挑战页双tab入口
+- 新增DoaController(/api/doa 七接口)
+- 新增DoaService(创建阶段/家庭总览/详情/周计划/周复盘)
+- DoaStage新增memberUserId非表字段(为Task8代管详情准备)
+- 新增DoaStage/DoaGoal/DoaWeek实体与Mapper
+- 迁移314创建DOA三表(doa_stage/doa_goal/doa_week)
+
+### Bug 修复
+- 修复远程预存编译错误(BasicQuotaService/Collections import缺失)+ 迁移318花括号对齐
+- 挑战页双tab改用doa-前缀类名避免类名冲突
+- checkStageMemberPermission 空指针绕过同源修复
+- 修复代管校验空指针绕过与 weekStart Locale 依赖
+
+### 其他
+-    原条件直接跳过校验,非家庭成员可为任何成员(含可登录成员)创建阶段。
+-    收紧为 isSelf = selfMemberId != null && equals(memberId),null 视为非本人,
+-    不可代管可登录成员。
+- 2. weekStart():补 setFirstDayOfWeek(MONDAY),避免 en_US/C 等周日起始
+-    Locale 下 set(DAY_OF_WEEK, MONDAY) 使周日滚到下周,导致 week1 起点
+-    晚于 stage.startDate。
+- 
+
+
 ## v1.0.1382 (2026-09-12)
 
 ### 新功能

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

@@ -1,6 +1,6 @@
 # 更新日志
 
-> 当前版本: v1.0.1382
+> 当前版本: v1.0.1383
 
 ## 历史版本
 
@@ -8,6 +8,45 @@
 
 ---
 
+## v1.0.1383 (2026-09-13)
+
+### 文档
+- add vendor order review spec, plan, and API reference entries
+- 登记DOA接口+统一能登录/不能登录用户口径规范
+
+### 重构
+- clean up review logic (remove unused var, fix computed, add log separators)
+
+### 新功能
+- add vendor order review page and entry
+- add vendorId to order detail response for permission check
+- 新增doa-stage-detail详情页+实体memberUserId字段
+- 新增doa-week-edit周计划复盘编辑页
+- 新增doa-stage-create创建阶段页
+- 新增doa-index家庭总览页
+- 前端API封装+页面注册+挑战页双tab入口
+- 新增DoaController(/api/doa 七接口)
+- 新增DoaService(创建阶段/家庭总览/详情/周计划/周复盘)
+- DoaStage新增memberUserId非表字段(为Task8代管详情准备)
+- 新增DoaStage/DoaGoal/DoaWeek实体与Mapper
+- 迁移314创建DOA三表(doa_stage/doa_goal/doa_week)
+
+### Bug 修复
+- 修复远程预存编译错误(BasicQuotaService/Collections import缺失)+ 迁移318花括号对齐
+- 挑战页双tab改用doa-前缀类名避免类名冲突
+- checkStageMemberPermission 空指针绕过同源修复
+- 修复代管校验空指针绕过与 weekStart Locale 依赖
+
+### 其他
+-    原条件直接跳过校验,非家庭成员可为任何成员(含可登录成员)创建阶段。
+-    收紧为 isSelf = selfMemberId != null && equals(memberId),null 视为非本人,
+-    不可代管可登录成员。
+- 2. weekStart():补 setFirstDayOfWeek(MONDAY),避免 en_US/C 等周日起始
+-    Locale 下 set(DAY_OF_WEEK, MONDAY) 使周日滚到下周,导致 week1 起点
+-    晚于 stage.startDate。
+- 
+
+
 ## v1.0.1382 (2026-09-12)
 
 ### 新功能