| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 |
- from pydantic import BaseModel
- from typing import Literal, Optional, List, Dict, Any
- class HealthPlanGenerateRequest(BaseModel):
- member_ids: Optional[str] = None
- dimensions: Optional[str] = None
- goal: str = ""
- family_id: Optional[int] = None
- class PlanTask(BaseModel):
- action_type: Literal["buy", "read", "exercise", "checkin", "diet", "activity"]
- title: str
- dimension: Literal["body", "mind", "wisdom", "action", "wealth"]
- frequency: Literal["once", "daily"] = "daily"
- notes: Optional[str] = None
- class HealthPlanSection(BaseModel):
- key: str # "nutrition" | "diet" | "exercise"
- title: str
- content: str # markdown text
- items: List[dict] = [] # structured items for UI rendering
- tasks: List[PlanTask] = [] # machine-readable task intents
- class HealthPlanResponse(BaseModel):
- """单成员方案 / 兼容旧结构(扁平 sections)。
- 多成员(common+individual)请使用 MultiMemberPlanResponse。
- 本类保留以向后兼容单人方案路径(len(member_ids) <= 1)。
- """
- overview: str = ""
- sections: List[HealthPlanSection] = []
- abnormal_indicators: List[dict] = []
- knowledge_sources: List[dict] = []
- class PlanPart(BaseModel):
- """方案的一个逻辑部分:可承载共性(common)或个性(individual)。"""
- overview: str = ""
- sections: List[HealthPlanSection] = []
- abnormal_indicators: List[dict] = []
- knowledge_sources: List[dict] = []
- class MultiMemberPlanResponse(BaseModel):
- """多人方案:共性 + 各成员个性。
- - common: 适用于全体成员的共性方案部分
- - individual: 按 member_id 分组的个性方案部分
- """
- common: PlanPart = PlanPart()
- individual: Dict[str, PlanPart] = {}
- def build_rendered_content(self, member_names: Dict[str, str]) -> str:
- """把 common+individual 组合渲染为 Markdown 文本(供 planContent 使用)。
- member_names: {memberId: 成员名},用于在标题里标注个性部分归属。
- """
- out: List[str] = []
- out.append("# 健康方案\n\n")
- common = self.common
- out.append("## 共性方案\n")
- if common.overview:
- out.append("### 方案概述\n\n" + common.overview + "\n\n")
- for sec in common.sections:
- out.append(f"## {sec.title}\n\n{sec.content}\n\n")
- if common.abnormal_indicators:
- out.append("## 共性异常指标\n")
- for ind in common.abnormal_indicators:
- out.append(f"- {ind.get('member','?')} - {ind.get('indicator','')}: {ind.get('value','')} {ind.get('unit','')}")
- if self.individual:
- out.append("\n---\n\n# 个性方案\n")
- for mid, part in self.individual.items():
- name = member_names.get(mid, f"成员{mid}")
- out.append(f"\n## {name} 个性方案\n")
- if part.overview:
- out.append("### 概述\n\n" + part.overview + "\n")
- for sec in part.sections:
- out.append(f"### {sec.title}\n\n{sec.content}\n")
- if part.abnormal_indicators:
- out.append("### 异常指标\n")
- for ind in part.abnormal_indicators:
- out.append(f"- {ind.get('member','?')} - {ind.get('indicator','')}: {ind.get('value','')} {ind.get('unit','')}")
- return "".join(out)
|