|
|
@@ -0,0 +1,262 @@
|
|
|
+# 设计方案:穴位定位功能
|
|
|
+
|
|
|
+## 架构设计
|
|
|
+
|
|
|
+### 数据流
|
|
|
+
|
|
|
+```
|
|
|
+用户信息录入 → 体型数据处理 → 穴位坐标计算 → 经络图渲染 → 艾灸执行
|
|
|
+ │ │ │ │
|
|
|
+ │ │ │ ▼
|
|
|
+ │ │ │ 穴位选择/定制
|
|
|
+ │ │ │ │
|
|
|
+ └──────────────┴──────────────┴──────────────┘
|
|
|
+ ↕
|
|
|
+ 穴位数据库
|
|
|
+```
|
|
|
+
|
|
|
+### 技术选型
|
|
|
+
|
|
|
+| 层级 | 技术 | 理由 |
|
|
|
+|------|------|------|
|
|
|
+| 前端可视化 | Canvas + SVG | 经络图绘制,支持缩放、点击交互 |
|
|
|
+| 状态管理 | Zustand | 穴位选择状态,轻量高效 |
|
|
|
+| 数据格式 | JSON + 静态资源 | 穴位数据存储,易于维护 |
|
|
|
+| 坐标计算 | TypeScript | 类型安全,精度控制 |
|
|
|
+| API | RESTful | 与现有架构一致 |
|
|
|
+
|
|
|
+## 数据模型
|
|
|
+
|
|
|
+### 穴位数据结构
|
|
|
+
|
|
|
+```typescript
|
|
|
+// 穴位定义
|
|
|
+interface Acupoint {
|
|
|
+ id: string; // 穴位编号
|
|
|
+ name: string; // 穴位名称
|
|
|
+ pinyin: string; // 拼音
|
|
|
+ meridian: string; // 所属经络
|
|
|
+ location: { // 定位描述
|
|
|
+ anatomical: string; // 解剖位置描述
|
|
|
+ relative: string; // 相对位置描述(如:大椎穴下3寸)
|
|
|
+ };
|
|
|
+ offset: { // 相对于大椎穴的偏移(基于标准体型)
|
|
|
+ x: number; // 横向偏移(cm)
|
|
|
+ y: number; // 纵向偏移(cm)
|
|
|
+ };
|
|
|
+ effects: string[]; // 功效(驱寒、祛风等)
|
|
|
+ contraindications: string[]; // 禁忌
|
|
|
+}
|
|
|
+
|
|
|
+// 用户体型数据
|
|
|
+interface BodyData {
|
|
|
+ userId: string;
|
|
|
+ gender: 'male' | 'female';
|
|
|
+ age: number;
|
|
|
+ height: number; // cm
|
|
|
+ weight: number; // kg
|
|
|
+ shoulderHeight?: number; // 肩高(传感器检测)
|
|
|
+ shoulderWidth?: number; // 肩宽(传感器检测)
|
|
|
+}
|
|
|
+
|
|
|
+// 计算后的穴位位置
|
|
|
+interface CalculatedAcupoint {
|
|
|
+ acupointId: string;
|
|
|
+ position: {
|
|
|
+ x: number; // 实际坐标(cm)
|
|
|
+ y: number;
|
|
|
+ };
|
|
|
+ confidence: number; // 置信度 0-1
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+### 穴位数据库(初始数据)
|
|
|
+
|
|
|
+```typescript
|
|
|
+const ACUPOINT_DATABASE: Acupoint[] = [
|
|
|
+ {
|
|
|
+ id: 'dazhui',
|
|
|
+ name: '大椎穴',
|
|
|
+ pinyin: 'dazhui',
|
|
|
+ meridian: '督脉',
|
|
|
+ location: {
|
|
|
+ anatomical: '第七颈椎棘突下凹陷中',
|
|
|
+ relative: '基准穴位,位于背部最高点'
|
|
|
+ },
|
|
|
+ offset: { x: 0, y: 0 },
|
|
|
+ effects: ['驱寒', '祛湿', '解表', '清热'],
|
|
|
+ contraindications: ['孕妇慎用']
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: 'shenzhu',
|
|
|
+ name: '身柱穴',
|
|
|
+ pinyin: 'shenzhu',
|
|
|
+ meridian: '督脉',
|
|
|
+ location: {
|
|
|
+ anatomical: '第三胸椎棘突下凹陷中',
|
|
|
+ relative: '大椎穴下3寸'
|
|
|
+ },
|
|
|
+ offset: { x: 0, y: -7.5 },
|
|
|
+ effects: ['止咳平喘', '安神'],
|
|
|
+ contraindications: []
|
|
|
+ },
|
|
|
+ // ... 其他穴位
|
|
|
+];
|
|
|
+```
|
|
|
+
|
|
|
+## 穴位坐标计算算法
|
|
|
+
|
|
|
+### 基于体型的缩放因子
|
|
|
+
|
|
|
+```typescript
|
|
|
+function calculateScaleFactor(bodyData: BodyData): { x: number; y: number } {
|
|
|
+ // 标准体型参考(中国成年人平均)
|
|
|
+ const STANDARD = {
|
|
|
+ male: { height: 170, weight: 65, shoulderWidth: 42 },
|
|
|
+ female: { height: 158, weight: 55, shoulderWidth: 36 }
|
|
|
+ };
|
|
|
+
|
|
|
+ const ref = STANDARD[bodyData.gender];
|
|
|
+
|
|
|
+ // 高度缩放因子
|
|
|
+ const heightScale = bodyData.height / ref.height;
|
|
|
+
|
|
|
+ // 宽度缩放因子(肩宽与身高正相关)
|
|
|
+ const estimatedShoulderWidth = bodyData.shoulderWidth ||
|
|
|
+ (bodyData.gender === 'male' ? bodyData.height * 0.247 : bodyData.height * 0.228);
|
|
|
+ const widthScale = estimatedShoulderWidth / ref.shoulderWidth;
|
|
|
+
|
|
|
+ return { x: widthScale, y: heightScale };
|
|
|
+}
|
|
|
+
|
|
|
+function calculateAcupointPosition(
|
|
|
+ acupoint: Acupoint,
|
|
|
+ bodyData: BodyData
|
|
|
+): CalculatedAcupoint {
|
|
|
+ const scale = calculateScaleFactor(bodyData);
|
|
|
+
|
|
|
+ // 应用缩放因子
|
|
|
+ const position = {
|
|
|
+ x: acupoint.offset.x * scale.x,
|
|
|
+ y: acupoint.offset.y * scale.y
|
|
|
+ };
|
|
|
+
|
|
|
+ // 置信度计算(基于数据完整性)
|
|
|
+ let confidence = 0.8; // 基础置信度
|
|
|
+ if (bodyData.shoulderHeight) confidence += 0.1;
|
|
|
+ if (bodyData.shoulderWidth) confidence += 0.1;
|
|
|
+
|
|
|
+ return { acupointId: acupoint.id, position, confidence };
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+## API 设计
|
|
|
+
|
|
|
+### 端点
|
|
|
+
|
|
|
+| 方法 | 路径 | 描述 |
|
|
|
+|------|------|------|
|
|
|
+| GET | `/api/acupoints` | 获取所有穴位列表 |
|
|
|
+| GET | `/api/acupoints/:id` | 获取单个穴位详情 |
|
|
|
+| POST | `/api/acupoints/calculate` | 计算用户穴位位置 |
|
|
|
+| POST | `/api/acupoints/recommend` | 基于症状推荐穴位 |
|
|
|
+| GET | `/api/acupoints/meridian/:name` | 获取某经络的所有穴位 |
|
|
|
+
|
|
|
+### 请求/响应示例
|
|
|
+
|
|
|
+```typescript
|
|
|
+// POST /api/acupoints/calculate
|
|
|
+// Request
|
|
|
+{
|
|
|
+ "userId": "user_001",
|
|
|
+ "bodyData": {
|
|
|
+ "gender": "male",
|
|
|
+ "height": 175,
|
|
|
+ "weight": 70
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// Response
|
|
|
+{
|
|
|
+ "userId": "user_001",
|
|
|
+ "basePoint": {
|
|
|
+ "id": "dazhui",
|
|
|
+ "name": "大椎穴",
|
|
|
+ "position": { "x": 0, "y": 0 }
|
|
|
+ },
|
|
|
+ "acupoints": [
|
|
|
+ {
|
|
|
+ "acupointId": "shenzhu",
|
|
|
+ "name": "身柱穴",
|
|
|
+ "position": { "x": 0, "y": -7.72 },
|
|
|
+ "confidence": 0.8
|
|
|
+ },
|
|
|
+ // ...
|
|
|
+ ]
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+## 前端组件设计
|
|
|
+
|
|
|
+### 组件结构
|
|
|
+
|
|
|
+```
|
|
|
+src/components/
|
|
|
+├── MeridianGraph/
|
|
|
+│ ├── MeridianGraph.tsx # 经络图主组件
|
|
|
+│ ├── AcupointMarker.tsx # 穴位标记点
|
|
|
+│ ├── AcupointTooltip.tsx # 穴位信息浮层
|
|
|
+│ └── MeridianGraph.types.ts
|
|
|
+├── AcupointSelector/
|
|
|
+│ ├── AcupointSelector.tsx # 穴位选择器
|
|
|
+│ ├── AcupointCard.tsx # 穴位卡片
|
|
|
+│ └── AcupointFilter.tsx # 穴位筛选
|
|
|
+└── AcupointRecommendation/
|
|
|
+ ├── SymptomInput.tsx # 症状输入
|
|
|
+ └── RecommendationList.tsx # 推荐列表
|
|
|
+```
|
|
|
+
|
|
|
+### 经络图组件
|
|
|
+
|
|
|
+```tsx
|
|
|
+// MeridianGraph.tsx
|
|
|
+interface MeridianGraphProps {
|
|
|
+ acupoints: CalculatedAcupoint[];
|
|
|
+ selectedIds: string[];
|
|
|
+ onSelect: (id: string) => void;
|
|
|
+ mode: 'view' | 'select' | 'edit';
|
|
|
+}
|
|
|
+
|
|
|
+export function MeridianGraph({ acupoints, selectedIds, onSelect, mode }: MeridianGraphProps) {
|
|
|
+ // 人体背部轮廓 SVG
|
|
|
+ // 穴位点击交互
|
|
|
+ // 缩放和平移
|
|
|
+ // 穴位高亮显示
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+## 实施步骤
|
|
|
+
|
|
|
+### Wave 1: 数据层
|
|
|
+1. 创建穴位数据库 JSON
|
|
|
+2. 实现坐标计算算法
|
|
|
+3. 编写单元测试
|
|
|
+
|
|
|
+### Wave 2: API 层
|
|
|
+1. 创建 `/api/acupoints` 路由
|
|
|
+2. 实现计算和推荐接口
|
|
|
+3. API 文档
|
|
|
+
|
|
|
+### Wave 3: 前端可视化
|
|
|
+1. 经络图 SVG 组件
|
|
|
+2. 穴位交互逻辑
|
|
|
+3. 穴位选择器组件
|
|
|
+
|
|
|
+### Wave 4: 集成
|
|
|
+1. 与用户信息模块集成
|
|
|
+2. 与艾灸方案模块集成
|
|
|
+3. 端到端测试
|
|
|
+
|
|
|
+## 回滚策略
|
|
|
+
|
|
|
+每个 Wave 完成后提交 Git,可随时回退到上一稳定状态。
|