设计方案:穴位定位功能
架构设计
数据流
用户信息录入 → 体型数据处理 → 穴位坐标计算 → 经络图渲染 → 艾灸执行
│ │ │ │
│ │ │ ▼
│ │ │ 穴位选择/定制
│ │ │ │
└──────────────┴──────────────┴──────────────┘
↕
穴位数据库
技术选型
| 层级 |
技术 |
理由 |
| 前端可视化 |
Canvas + SVG |
经络图绘制,支持缩放、点击交互 |
| 状态管理 |
Zustand |
穴位选择状态,轻量高效 |
| 数据格式 |
JSON + 静态资源 |
穴位数据存储,易于维护 |
| 坐标计算 |
TypeScript |
类型安全,精度控制 |
| API |
RESTful |
与现有架构一致 |
数据模型
穴位数据结构
// 穴位定义
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
}
穴位数据库(初始数据)
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: []
},
// ... 其他穴位
];
穴位坐标计算算法
基于体型的缩放因子
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 |
获取某经络的所有穴位 |
请求/响应示例
// 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 # 推荐列表
经络图组件
// 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: 数据层
- 创建穴位数据库 JSON
- 实现坐标计算算法
- 编写单元测试
Wave 2: API 层
- 创建
/api/acupoints 路由
- 实现计算和推荐接口
- API 文档
Wave 3: 前端可视化
- 经络图 SVG 组件
- 穴位交互逻辑
- 穴位选择器组件
Wave 4: 集成
- 与用户信息模块集成
- 与艾灸方案模块集成
- 端到端测试
回滚策略
每个 Wave 完成后提交 Git,可随时回退到上一稳定状态。