feat: 新增饮食记录和分析功能
- 创建饮食记录相关的数据库模型、DTO和API接口,支持用户手动添加和AI视觉识别记录饮食。 - 实现饮食分析服务,提供营养分析和健康建议,优化AI教练服务以集成饮食分析功能。 - 更新用户控制器,添加饮食记录的增删查改接口,增强用户饮食管理体验。 - 提供详细的API使用指南和数据库创建脚本,确保功能的完整性和可用性。
This commit is contained in:
192
docs/DIET_ANALYSIS_REFACTORING_SUMMARY.md
Normal file
192
docs/DIET_ANALYSIS_REFACTORING_SUMMARY.md
Normal file
@@ -0,0 +1,192 @@
|
||||
# 饮食分析功能重构总结
|
||||
|
||||
## 重构目标
|
||||
|
||||
原本的 `AiCoachService` 类承担了太多职责,包括:
|
||||
- AI 对话管理
|
||||
- 体重记录分析
|
||||
- 饮食图片识别
|
||||
- 营养数据分析
|
||||
- 用户上下文构建
|
||||
|
||||
这导致代码可读性差、维护困难、职责不清。因此我们将饮食分析相关功能抽取成独立的服务。
|
||||
|
||||
## 重构方案
|
||||
|
||||
### 1. 创建独立的饮食分析服务
|
||||
|
||||
**新文件**: `src/ai-coach/services/diet-analysis.service.ts`
|
||||
|
||||
**职责分离**:
|
||||
```typescript
|
||||
// 原来 AiCoachService 的职责
|
||||
class AiCoachService {
|
||||
- AI 对话管理 ✅ (保留)
|
||||
- 体重记录分析 ✅ (保留)
|
||||
- 饮食图片识别 ❌ (移除)
|
||||
- 营养数据分析 ❌ (移除)
|
||||
- 用户上下文构建 ❌ (移除)
|
||||
}
|
||||
|
||||
// 新的 DietAnalysisService 职责
|
||||
class DietAnalysisService {
|
||||
+ 饮食图片识别 ✅ (专门负责)
|
||||
+ 营养数据分析 ✅ (专门负责)
|
||||
+ 饮食上下文构建 ✅ (专门负责)
|
||||
+ 饮食记录处理 ✅ (专门负责)
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 功能模块化设计
|
||||
|
||||
#### DietAnalysisService 主要方法:
|
||||
|
||||
1. **`analyzeDietImageEnhanced()`** - 增强版图片分析
|
||||
2. **`processDietRecord()`** - 处理饮食记录并保存到数据库
|
||||
3. **`buildUserNutritionContext()`** - 构建用户营养信息上下文
|
||||
4. **`buildEnhancedDietAnalysisPrompt()`** - 构建分析提示
|
||||
|
||||
#### 私有辅助方法:
|
||||
- `getSuggestedMealType()` - 根据时间推断餐次
|
||||
- `buildDietAnalysisPrompt()` - 构建AI分析提示
|
||||
- `parseAndValidateResult()` - 解析和验证AI结果
|
||||
- `buildNutritionSummaryText()` - 构建营养汇总文本
|
||||
- `buildMealDistributionText()` - 构建餐次分布文本
|
||||
- `buildRecentMealsText()` - 构建最近饮食详情文本
|
||||
- `buildNutritionTrendText()` - 构建营养趋势文本
|
||||
|
||||
### 3. 接口标准化
|
||||
|
||||
**导出接口**:
|
||||
```typescript
|
||||
export interface DietAnalysisResult {
|
||||
shouldRecord: boolean;
|
||||
confidence: number;
|
||||
extractedData?: {
|
||||
foodName: string;
|
||||
mealType: MealType;
|
||||
portionDescription?: string;
|
||||
estimatedCalories?: number;
|
||||
proteinGrams?: number;
|
||||
carbohydrateGrams?: number;
|
||||
fatGrams?: number;
|
||||
fiberGrams?: number;
|
||||
nutritionDetails?: any;
|
||||
};
|
||||
analysisText: string;
|
||||
}
|
||||
```
|
||||
|
||||
## 重构效果
|
||||
|
||||
### 📈 代码质量提升
|
||||
|
||||
| 指标 | 重构前 | 重构后 | 改善 |
|
||||
|------|--------|--------|------|
|
||||
| AiCoachService 行数 | ~1057行 | ~700行 | -33% |
|
||||
| 方法数量 | 15+ | 10 | 专注核心功能 |
|
||||
| 单一职责 | ❌ | ✅ | 职责清晰 |
|
||||
| 可测试性 | 中等 | 优秀 | 独立测试 |
|
||||
| 可维护性 | 困难 | 容易 | 模块化设计 |
|
||||
|
||||
### 🎯 架构优势
|
||||
|
||||
1. **单一职责原则 (SRP)**
|
||||
- `AiCoachService`: 专注 AI 对话和体重分析
|
||||
- `DietAnalysisService`: 专注饮食分析和营养评估
|
||||
|
||||
2. **依赖注入优化**
|
||||
- 清晰的服务依赖关系
|
||||
- 更好的可测试性
|
||||
- 松耦合设计
|
||||
|
||||
3. **可扩展性提升**
|
||||
- 饮食分析功能可独立扩展
|
||||
- 容易添加新的营养分析算法
|
||||
- 支持多种AI模型集成
|
||||
|
||||
### 🔧 技术实现
|
||||
|
||||
#### 在 AiCoachService 中的使用:
|
||||
```typescript
|
||||
// 重构前:所有逻辑在一个方法中
|
||||
const dietAnalysisResult = await this.analyzeDietImageEnhanced(params.imageUrls);
|
||||
// ... 复杂的处理逻辑 ...
|
||||
|
||||
// 重构后:清晰的服务调用
|
||||
const dietAnalysisResult = await this.dietAnalysisService.analyzeDietImageEnhanced(params.imageUrls);
|
||||
const createDto = await this.dietAnalysisService.processDietRecord(params.userId, dietAnalysisResult, params.imageUrls[0]);
|
||||
const nutritionContext = await this.dietAnalysisService.buildUserNutritionContext(params.userId);
|
||||
```
|
||||
|
||||
#### 模块依赖更新:
|
||||
```typescript
|
||||
// ai-coach.module.ts
|
||||
providers: [AiCoachService, DietAnalysisService]
|
||||
```
|
||||
|
||||
### 📊 性能优化
|
||||
|
||||
1. **内存使用优化**
|
||||
- AI模型实例复用(DietAnalysisService 管理)
|
||||
- 减少 AiCoachService 的内存占用
|
||||
|
||||
2. **代码加载优化**
|
||||
- 按需加载饮食分析功能
|
||||
- 更好的树摇(Tree Shaking)支持
|
||||
|
||||
3. **缓存友好**
|
||||
- 独立的饮食分析服务便于实现缓存策略
|
||||
|
||||
## 使用示例
|
||||
|
||||
### 调用饮食分析服务:
|
||||
```typescript
|
||||
// 在 AiCoachService 中
|
||||
constructor(
|
||||
private readonly dietAnalysisService: DietAnalysisService,
|
||||
) {}
|
||||
|
||||
// 使用饮食分析功能
|
||||
const analysisResult = await this.dietAnalysisService.analyzeDietImageEnhanced(imageUrls);
|
||||
if (analysisResult.shouldRecord) {
|
||||
const dietRecord = await this.dietAnalysisService.processDietRecord(userId, analysisResult, imageUrl);
|
||||
}
|
||||
```
|
||||
|
||||
### 单独使用营养分析:
|
||||
```typescript
|
||||
// 在其他服务中也可以使用
|
||||
const nutritionContext = await this.dietAnalysisService.buildUserNutritionContext(userId);
|
||||
```
|
||||
|
||||
## 扩展建议
|
||||
|
||||
基于重构后的架构,未来可以考虑:
|
||||
|
||||
1. **更多分析服务**
|
||||
- `ExerciseAnalysisService` - 运动分析服务
|
||||
- `HealthMetricsService` - 健康指标服务
|
||||
- `RecommendationService` - 推荐算法服务
|
||||
|
||||
2. **插件化架构**
|
||||
- 支持第三方营养数据库插件
|
||||
- 支持多种AI模型提供商
|
||||
- 支持自定义分析算法
|
||||
|
||||
3. **微服务化**
|
||||
- 饮食分析服务可独立部署
|
||||
- 支持水平扩展
|
||||
- 更好的故障隔离
|
||||
|
||||
## 总结
|
||||
|
||||
通过这次重构,我们成功地:
|
||||
|
||||
✅ **提高了代码可读性** - 职责清晰,逻辑分明
|
||||
✅ **增强了可维护性** - 模块化设计,便于维护
|
||||
✅ **改善了可测试性** - 独立服务,易于单元测试
|
||||
✅ **保持了功能完整性** - 所有原有功能正常工作
|
||||
✅ **优化了架构设计** - 符合SOLID原则
|
||||
|
||||
重构后的代码更加专业、清晰,为后续的功能扩展和维护奠定了良好的基础。
|
||||
165
docs/DIET_RECORDS_IMPLEMENTATION_SUMMARY.md
Normal file
165
docs/DIET_RECORDS_IMPLEMENTATION_SUMMARY.md
Normal file
@@ -0,0 +1,165 @@
|
||||
# 饮食记录功能实现总结
|
||||
|
||||
## 功能概述
|
||||
|
||||
根据您的需求,我已经参照现有体重记录的实现,完整地实现了饮食记录功能。该功能包括:
|
||||
|
||||
1. **数据库模型** - 完整的饮食记录数据结构
|
||||
2. **API接口** - RESTful API支持增删查改操作
|
||||
3. **AI视觉识别** - 优化的图片分析和自动记录
|
||||
4. **营养分析** - 基于最近饮食记录的健康建议
|
||||
5. **AI教练集成** - 智能对话中的饮食指导
|
||||
|
||||
## 实现的文件清单
|
||||
|
||||
### 数据库模型
|
||||
- `src/users/models/user-diet-history.model.ts` - 饮食记录数据模型
|
||||
|
||||
### DTO 结构
|
||||
- `src/users/dto/diet-record.dto.ts` - 完整的请求/响应数据传输对象
|
||||
|
||||
### 服务层
|
||||
- `src/users/users.service.ts` - 新增饮食记录相关方法:
|
||||
- `addDietRecord()` - 添加饮食记录
|
||||
- `addDietRecordByVision()` - 通过AI视觉识别添加记录
|
||||
- `getDietHistory()` - 获取饮食历史记录
|
||||
- `updateDietRecord()` - 更新饮食记录
|
||||
- `deleteDietRecord()` - 删除饮食记录
|
||||
- `getRecentNutritionSummary()` - 获取营养汇总
|
||||
|
||||
### 控制器层
|
||||
- `src/users/users.controller.ts` - 新增API端点:
|
||||
- `POST /users/diet-records` - 添加饮食记录
|
||||
- `GET /users/diet-records` - 获取饮食记录列表
|
||||
- `PUT /users/diet-records/:id` - 更新饮食记录
|
||||
- `DELETE /users/diet-records/:id` - 删除饮食记录
|
||||
- `GET /users/nutrition-summary` - 获取营养分析
|
||||
|
||||
### AI教练服务增强
|
||||
- `src/ai-coach/ai-coach.service.ts` - 新增功能:
|
||||
- `analyzeDietImageEnhanced()` - 增强版饮食图片分析
|
||||
- `buildUserNutritionContext()` - 构建用户营养上下文
|
||||
- `buildEnhancedDietAnalysisPrompt()` - 增强版分析提示
|
||||
- 支持 `#记饮食` 指令和自动记录
|
||||
|
||||
### 配置文件
|
||||
- `src/users/users.module.ts` - 注册新的数据模型
|
||||
|
||||
### 文档
|
||||
- `docs/diet-records-table-create.sql` - 数据库表创建脚本
|
||||
- `docs/diet-records-api-guide.md` - API使用指南
|
||||
|
||||
## 核心功能特性
|
||||
|
||||
### 1. 智能视觉识别
|
||||
- **结构化数据返回** - AI分析结果以JSON格式返回,包含完整营养信息
|
||||
- **自动餐次判断** - 根据当前时间智能推断餐次类型
|
||||
- **置信度评估** - 只有置信度足够高才自动记录到数据库
|
||||
- **营养成分估算** - 自动计算热量、蛋白质、碳水、脂肪等
|
||||
|
||||
### 2. 个性化营养分析
|
||||
- **历史记录整合** - 结合用户最近10顿饮食记录
|
||||
- **趋势分析** - 分析热量摄入、营养均衡等趋势
|
||||
- **智能建议** - 基于个人饮食习惯提供针对性建议
|
||||
- **营养评分** - 0-100分的综合营养评价
|
||||
|
||||
### 3. 完整的数据结构
|
||||
参照健康管理应用的最佳实践,包含:
|
||||
- 基础信息:食物名称、餐次、份量、时间
|
||||
- 营养成分:热量、三大营养素、膳食纤维、钠含量等
|
||||
- 扩展字段:图片URL、AI分析结果、用户备注
|
||||
- 数据来源:手动输入、AI识别、其他
|
||||
|
||||
### 4. AI教练智能对话
|
||||
- **指令识别** - 支持 `#记饮食`、`#饮食` 等指令
|
||||
- **上下文感知** - 自动提供用户饮食历史上下文
|
||||
- **个性化回复** - 基于用户饮食记录给出专业建议
|
||||
- **健康指导** - 综合最近饮食情况提供改善建议
|
||||
|
||||
## 技术实现亮点
|
||||
|
||||
### 1. 数据安全与性能
|
||||
- 使用数据库事务确保数据一致性
|
||||
- 合理的索引设计优化查询性能
|
||||
- 软删除机制保护用户数据
|
||||
- 活动日志记录用户操作
|
||||
|
||||
### 2. 错误处理与验证
|
||||
- 完整的数据验证规则
|
||||
- 合理的错误提示信息
|
||||
- 容错机制和降级处理
|
||||
- 详细的日志记录
|
||||
|
||||
### 3. API设计规范
|
||||
- RESTful API设计原则
|
||||
- 完整的Swagger文档注解
|
||||
- 统一的响应格式
|
||||
- 分页查询支持
|
||||
|
||||
### 4. AI集成优化
|
||||
- 结构化的AI输出格式
|
||||
- 智能的数据验证和清洗
|
||||
- 用户体验优化(自动记录)
|
||||
- 个性化的营养分析
|
||||
|
||||
## 使用示例
|
||||
|
||||
### 1. 手动添加饮食记录
|
||||
```bash
|
||||
curl -X POST /users/diet-records \
|
||||
-H "Authorization: Bearer <token>" \
|
||||
-d '{
|
||||
"mealType": "lunch",
|
||||
"foodName": "鸡胸肉沙拉",
|
||||
"estimatedCalories": 280,
|
||||
"proteinGrams": 35.0
|
||||
}'
|
||||
```
|
||||
|
||||
### 2. AI拍照记录饮食
|
||||
用户发送:`#记饮食` + 食物图片
|
||||
系统自动:分析图片 → 提取数据 → 保存记录 → 提供建议
|
||||
|
||||
### 3. 获取营养分析
|
||||
```bash
|
||||
curl -X GET /users/nutrition-summary?mealCount=10 \
|
||||
-H "Authorization: Bearer <token>"
|
||||
```
|
||||
|
||||
## 部署说明
|
||||
|
||||
1. **数据库表创建**
|
||||
```bash
|
||||
mysql -u username -p database_name < docs/diet-records-table-create.sql
|
||||
```
|
||||
|
||||
2. **环境变量配置**
|
||||
确保AI模型相关的环境变量已正确配置:
|
||||
- `DASHSCOPE_API_KEY`
|
||||
- `DASHSCOPE_BASE_URL`
|
||||
- `DASHSCOPE_VISION_MODEL`
|
||||
|
||||
3. **应用重启**
|
||||
```bash
|
||||
npm run build
|
||||
npm run start:prod
|
||||
```
|
||||
|
||||
## 扩展建议
|
||||
|
||||
基于当前实现,未来可以考虑以下扩展:
|
||||
|
||||
1. **营养数据库集成** - 接入专业的食物营养数据库
|
||||
2. **饮食目标设定** - 允许用户设定个性化的营养目标
|
||||
3. **社交分享功能** - 用户可以分享饮食记录和成就
|
||||
4. **更精确的AI识别** - 使用更专业的食物识别模型
|
||||
5. **营养师咨询** - 集成专业营养师在线咨询服务
|
||||
|
||||
## 测试建议
|
||||
|
||||
1. **功能测试** - 测试所有API端点的正常功能
|
||||
2. **AI识别测试** - 使用各种食物图片测试识别准确性
|
||||
3. **性能测试** - 测试大量数据情况下的查询性能
|
||||
4. **集成测试** - 测试与AI教练对话的完整流程
|
||||
|
||||
该实现完全按照您的要求,参照体重记录的实现模式,提供了完整、智能、用户友好的饮食记录功能。
|
||||
159
docs/diet-records-api-guide.md
Normal file
159
docs/diet-records-api-guide.md
Normal file
@@ -0,0 +1,159 @@
|
||||
# 饮食记录功能 API 使用指南
|
||||
|
||||
## 功能概述
|
||||
|
||||
饮食记录功能允许用户通过多种方式记录和管理饮食信息,包括:
|
||||
- 手动添加饮食记录
|
||||
- AI视觉识别自动记录(通过拍照)
|
||||
- 获取饮食历史记录
|
||||
- 营养分析和健康建议
|
||||
|
||||
## 数据库模型
|
||||
|
||||
### 饮食记录表 (t_user_diet_history)
|
||||
|
||||
包含以下关键字段:
|
||||
- 基础信息:食物名称、餐次类型、用餐时间
|
||||
- 营养成分:热量、蛋白质、碳水化合物、脂肪、膳食纤维等
|
||||
- 记录来源:手动输入、AI视觉识别、其他
|
||||
- AI分析结果:完整的识别数据(JSON格式)
|
||||
|
||||
## API 端点
|
||||
|
||||
### 1. 添加饮食记录
|
||||
```
|
||||
POST /users/diet-records
|
||||
```
|
||||
|
||||
**请求体示例:**
|
||||
```json
|
||||
{
|
||||
"mealType": "lunch",
|
||||
"foodName": "鸡胸肉沙拉",
|
||||
"foodDescription": "烤鸡胸肉配蔬菜沙拉",
|
||||
"portionDescription": "1份",
|
||||
"estimatedCalories": 280,
|
||||
"proteinGrams": 35.0,
|
||||
"carbohydrateGrams": 15.5,
|
||||
"fatGrams": 8.0,
|
||||
"fiberGrams": 5.2,
|
||||
"source": "manual",
|
||||
"notes": "午餐很健康"
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 获取饮食记录历史
|
||||
```
|
||||
GET /users/diet-records?startDate=2024-01-01&endDate=2024-01-31&mealType=lunch&page=1&limit=20
|
||||
```
|
||||
|
||||
**响应示例:**
|
||||
```json
|
||||
{
|
||||
"records": [
|
||||
{
|
||||
"id": 1,
|
||||
"mealType": "lunch",
|
||||
"foodName": "鸡胸肉沙拉",
|
||||
"estimatedCalories": 280,
|
||||
"proteinGrams": 35.0,
|
||||
"source": "manual",
|
||||
"createdAt": "2024-01-15T12:30:00.000Z"
|
||||
}
|
||||
],
|
||||
"total": 1,
|
||||
"page": 1,
|
||||
"limit": 20,
|
||||
"totalPages": 1
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 更新饮食记录
|
||||
```
|
||||
PUT /users/diet-records/:id
|
||||
```
|
||||
|
||||
### 4. 删除饮食记录
|
||||
```
|
||||
DELETE /users/diet-records/:id
|
||||
```
|
||||
|
||||
### 5. 获取营养汇总分析
|
||||
```
|
||||
GET /users/nutrition-summary?mealCount=10
|
||||
```
|
||||
|
||||
**响应示例:**
|
||||
```json
|
||||
{
|
||||
"nutritionSummary": {
|
||||
"totalCalories": 2150,
|
||||
"totalProtein": 85.5,
|
||||
"totalCarbohydrates": 180.2,
|
||||
"totalFat": 65.8,
|
||||
"totalFiber": 28.5,
|
||||
"recordCount": 10,
|
||||
"dateRange": {
|
||||
"start": "2024-01-10T08:00:00.000Z",
|
||||
"end": "2024-01-15T19:00:00.000Z"
|
||||
}
|
||||
},
|
||||
"recentRecords": [...],
|
||||
"healthAnalysis": "基于您最近的饮食记录,我将为您提供个性化的营养分析和健康建议。",
|
||||
"nutritionScore": 78,
|
||||
"recommendations": [
|
||||
"建议增加膳食纤维摄入,多吃蔬菜、水果和全谷物。",
|
||||
"您的饮食结构相对均衡,继续保持良好的饮食习惯!"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## AI教练集成
|
||||
|
||||
### 饮食记录指令
|
||||
|
||||
用户可以使用以下指令触发饮食记录功能:
|
||||
- `#记饮食` 或 `#饮食` 或 `#记录饮食`
|
||||
|
||||
### AI视觉识别流程
|
||||
|
||||
1. 用户发送 `#记饮食` 指令并上传食物图片
|
||||
2. AI使用视觉模型分析图片,提取:
|
||||
- 食物名称和类型
|
||||
- 营养成分估算
|
||||
- 份量描述
|
||||
- 餐次类型(基于时间自动判断)
|
||||
3. 如果识别置信度足够,自动保存到数据库
|
||||
4. 结合用户历史饮食记录,提供个性化营养分析
|
||||
|
||||
### 营养分析上下文
|
||||
|
||||
AI教练会自动获取用户最近的饮食记录,提供:
|
||||
- 营养摄入趋势分析
|
||||
- 个性化健康建议
|
||||
- 基于历史记录的改善建议
|
||||
|
||||
## 数据库配置
|
||||
|
||||
1. 运行 SQL 脚本创建表:
|
||||
```bash
|
||||
mysql -u username -p database_name < docs/diet-records-table-create.sql
|
||||
```
|
||||
|
||||
2. 在 UsersModule 中已自动注册 UserDietHistory 模型
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **营养数据准确性**:AI估算的营养数据仅供参考,实际值可能有差异
|
||||
2. **图片质量**:为了更好的识别效果,建议上传清晰的食物图片
|
||||
3. **隐私保护**:用户饮食数据会安全存储,仅用于个性化分析
|
||||
4. **性能优化**:使用了合适的数据库索引来优化查询性能
|
||||
|
||||
## 扩展功能
|
||||
|
||||
未来可以考虑添加:
|
||||
- 食物营养数据库集成
|
||||
- 更精确的营养成分计算
|
||||
- 饮食目标设定和追踪
|
||||
- 营养师在线咨询
|
||||
- 社交分享功能
|
||||
@@ -1,67 +0,0 @@
|
||||
-- 一键导入普拉提动作分类与动作(MySQL 8+)
|
||||
-- 说明:表由 Sequelize 同步创建(t_exercise_categories / t_exercises)
|
||||
-- 若要幂等导入,使用 INSERT ... ON DUPLICATE KEY UPDATE
|
||||
|
||||
USE `db-plates`;
|
||||
|
||||
START TRANSACTION;
|
||||
|
||||
-- 分类
|
||||
INSERT INTO `t_exercise_categories` (`key`, `name`, `sort_order`, `created_at`, `updated_at`) VALUES
|
||||
('core', '核心与腹部', 0, NOW(), NOW()),
|
||||
('spine_posterior_chain', '脊柱与后链', 1, NOW(), NOW()),
|
||||
('lateral_hip', '侧链与髋', 2, NOW(), NOW()),
|
||||
('balance_support', '平衡与支撑', 3, NOW(), NOW()),
|
||||
('advanced_control', '进阶控制', 4, NOW(), NOW()),
|
||||
('mobility_stretch', '柔韧与拉伸', 5, NOW(), NOW())
|
||||
ON DUPLICATE KEY UPDATE `name` = VALUES(`name`), `sort_order` = VALUES(`sort_order`), `updated_at` = NOW();
|
||||
|
||||
-- 动作
|
||||
INSERT INTO `t_exercises` (`key`, `name`, `description`, `category_key`, `category_name`, `sort_order`, `created_at`, `updated_at`) VALUES
|
||||
('hundred', '百次拍击 (The Hundred)', '仰卧桌面位,小幅摆臂协同吸呼,核心激活。', 'core', '核心与腹部', 0, NOW(), NOW()),
|
||||
('single_leg_stretch', '单腿伸展 (Single Leg Stretch)', '交替伸直一条腿,另一腿屈膝抱向胸口,稳定骨盆。', 'core', '核心与腹部', 1, NOW(), NOW()),
|
||||
('double_leg_stretch', '双腿伸展 (Double Leg Stretch)', '双臂双腿同时伸直/收回,呼吸控制,核心稳定。', 'core', '核心与腹部', 2, NOW(), NOW()),
|
||||
('criss_cross', '扭转卷腹 (Criss Cross)', '肘碰对侧膝,腹斜肌发力与呼吸配合。', 'core', '核心与腹部', 3, NOW(), NOW()),
|
||||
('single_straight_leg', '单腿直剪 (Scissors)', '交替拉长上抬直腿,控制下放,避免耸肩。', 'core', '核心与腹部', 4, NOW(), NOW()),
|
||||
('double_straight_leg', '双腿抬降 (Double Straight Leg Lower Lift)', '双腿并拢抬降,腹直肌抗伸展。', 'core', '核心与腹部', 5, NOW(), NOW()),
|
||||
('spine_stretch_forward', '脊柱前伸 (Spine Stretch Forward)', '坐姿脊柱分节前伸,强调轴向延展与呼吸。', 'core', '核心与腹部', 6, NOW(), NOW()),
|
||||
('roll_up', '卷起 (Roll Up)', '仰卧分节卷起到坐,前屈后还原,控制节律。', 'core', '核心与腹部', 7, NOW(), NOW()),
|
||||
('rolling_like_a_ball', '小球滚动 (Rolling Like a Ball)', '抱膝蜷成球,控制滚动回正,核心稳定。', 'core', '核心与腹部', 8, NOW(), NOW()),
|
||||
('teaser', '船式 (Teaser)', 'V字平衡,腿躯干对抗重力与摆动。', 'core', '核心与腹部', 9, NOW(), NOW()),
|
||||
|
||||
('swan', '天鹅式 (Swan)', '俯卧伸展胸椎,后链发力,延展不挤压。', 'spine_posterior_chain', '脊柱与后链', 10, NOW(), NOW()),
|
||||
('swan_dive', '天鹅下潜 (Swan Dive)', '在Swan基础上前后摆动,弹性控制。', 'spine_posterior_chain', '脊柱与后链', 11, NOW(), NOW()),
|
||||
('swimming', '游泳式 (Swimming)', '俯卧交替抬对侧上肢与下肢,脊柱中立。', 'spine_posterior_chain', '脊柱与后链', 12, NOW(), NOW()),
|
||||
('shoulder_bridge', '肩桥 (Shoulder Bridge)', '仰卧卷尾抬盆,臀腿后侧力量与脊柱分节。', 'spine_posterior_chain', '脊柱与后链', 13, NOW(), NOW()),
|
||||
('spine_twist', '脊柱扭转 (Spine Twist)', '坐姿轴向延展上的控制旋转。', 'spine_posterior_chain', '脊柱与后链', 14, NOW(), NOW()),
|
||||
('saw', '锯式 (Saw)', '坐姿分腿,旋转前屈触对侧脚尖。', 'spine_posterior_chain', '脊柱与后链', 15, NOW(), NOW()),
|
||||
|
||||
('side_kick_front_back', '侧踢腿 前后摆 (Side Kick Front/Back)', '侧卧,髋稳定,腿前后摆动。', 'lateral_hip', '侧链与髋', 16, NOW(), NOW()),
|
||||
('side_kick_up_down', '侧踢腿 上下 (Side Kick Up/Down)', '侧卧,上侧腿上抬下放,控制不耸肩。', 'lateral_hip', '侧链与髋', 17, NOW(), NOW()),
|
||||
('side_leg_lift', '侧抬腿 (Side Leg Lift)', '侧卧抬腿,髋稳定,中臀肌激活。', 'lateral_hip', '侧链与髋', 18, NOW(), NOW()),
|
||||
('clam', '蛤蜊式 (Clam)', '侧卧屈髋屈膝,抬起上侧膝,臀中刺激。', 'lateral_hip', '侧链与髋', 19, NOW(), NOW()),
|
||||
('mermaid', '美人鱼 (Mermaid)', '坐姿侧屈拉伸,改善侧链柔韧。', 'lateral_hip', '侧链与髋', 20, NOW(), NOW()),
|
||||
|
||||
('plank', '平板支撑 (Plank)', '掌/前臂支撑,身体成一直线,核心稳定。', 'balance_support', '平衡与支撑', 21, NOW(), NOW()),
|
||||
('side_plank', '侧板支撑 (Side Plank)', '单侧支撑,侧链与肩带稳定。', 'balance_support', '平衡与支撑', 22, NOW(), NOW()),
|
||||
('push_up', '俯卧撑 (Push Up)', '胸肩臂与核心协同的推举支撑。', 'balance_support', '平衡与支撑', 23, NOW(), NOW()),
|
||||
('leg_pull_front', '前拉腿 (Leg Pull Front)', '俯撑抬腿,后链与肩带控制。', 'balance_support', '平衡与支撑', 24, NOW(), NOW()),
|
||||
('leg_pull_back', '后拉腿 (Leg Pull Back)', '仰撑抬腿,后链与肩带控制。', 'balance_support', '平衡与支撑', 25, NOW(), NOW()),
|
||||
|
||||
('jackknife', '折刀 (Jackknife)', '仰卧抬腿过头后折刀上推,核心与控制。', 'advanced_control', '进阶控制', 26, NOW(), NOW()),
|
||||
('open_leg_rocker', '开腿摇滚 (Open Leg Rocker)', '开腿V坐平衡,来回滚动。', 'advanced_control', '进阶控制', 27, NOW(), NOW()),
|
||||
('corkscrew', '开瓶器 (Corkscrew)', '躯干稳定下的双腿画圈,控制髋与核心。', 'advanced_control', '进阶控制', 28, NOW(), NOW()),
|
||||
('boomerang', '回旋镖 (Boomerang)', '融合Roll Over/Teaser的串联流畅控制。', 'advanced_control', '进阶控制', 29, NOW(), NOW()),
|
||||
('control_balance', '控制平衡 (Control Balance)', '过头位下的单腿抬降与控制。', 'advanced_control', '进阶控制', 30, NOW(), NOW()),
|
||||
('neck_pull', '抱颈卷起 (Neck Pull)', '更具挑战的卷起,背侧链参与更高。', 'advanced_control', '进阶控制', 31, NOW(), NOW()),
|
||||
('roll_over', '翻滚过头 (Roll Over)', '仰卧双腿过头落地,脊柱分节控制。', 'advanced_control', '进阶控制', 32, NOW(), NOW()),
|
||||
|
||||
('cat_cow', '猫牛 (Cat-Cow)', '四点支撑的屈伸热身/整理放松。', 'mobility_stretch', '柔韧与拉伸', 33, NOW(), NOW()),
|
||||
('hamstring_stretch', '腘绳肌拉伸', '仰卧或坐姿,拉伸大腿后侧。', 'mobility_stretch', '柔韧与拉伸', 34, NOW(), NOW()),
|
||||
('hip_flexor_stretch', '髋屈肌拉伸', '弓步位,前髋前侧拉伸。', 'mobility_stretch', '柔韧与拉伸', 35, NOW(), NOW()),
|
||||
('thoracic_extension', '胸椎伸展', '泡沫轴/垫上胸椎延展放松。', 'mobility_stretch', '柔韧与拉伸', 36, NOW(), NOW())
|
||||
ON DUPLICATE KEY UPDATE `name` = VALUES(`name`), `description` = VALUES(`description`), `category_key` = VALUES(`category_key`), `category_name` = VALUES(`category_name`), `sort_order` = VALUES(`sort_order`), `updated_at` = NOW();
|
||||
|
||||
COMMIT;
|
||||
|
||||
|
||||
@@ -1,121 +0,0 @@
|
||||
-- 普拉提分类和动作数据导入 SQL
|
||||
-- 执行前请确保数据库表结构已更新
|
||||
|
||||
-- 清空现有数据(可选,根据实际情况决定是否执行)
|
||||
-- DELETE FROM t_exercises;
|
||||
-- DELETE FROM t_exercise_categories;
|
||||
|
||||
-- 插入普拉提分类数据
|
||||
INSERT INTO t_exercise_categories (key, name, pilates_type, equipment_name, sort_order, created_at, updated_at) VALUES
|
||||
-- 垫上普拉提
|
||||
('mat_pilates', '垫上普拉提', 'mat_pilates', NULL, 1, NOW(), NOW()),
|
||||
|
||||
-- 器械普拉提
|
||||
('reformer', '核心床', 'equipment_pilates', '核心床', 2, NOW(), NOW()),
|
||||
('cadillac', '凯迪拉克', 'equipment_pilates', '凯迪拉克', 3, NOW(), NOW()),
|
||||
('chair', '普拉提椅', 'equipment_pilates', '普拉提椅', 4, NOW(), NOW()),
|
||||
('barrel', '普拉提桶', 'equipment_pilates', '普拉提桶', 5, NOW(), NOW());
|
||||
|
||||
-- 插入垫上普拉提动作数据
|
||||
INSERT INTO t_exercises (
|
||||
key, name, category_name, description, target_muscle_groups, equipment_name,
|
||||
beginner_reps, beginner_sets, breathing_cycles, hold_duration, special_instructions,
|
||||
category_key, sort_order, created_at, updated_at
|
||||
) VALUES
|
||||
('mat_hundred', '百次拍打', '垫上普拉提', '经典的普拉提动作,通过有节奏的手臂拍打配合呼吸来激活核心', '核心肌群、呼吸肌群、肩部稳定性', NULL, NULL, NULL, 10, NULL, '10个呼吸循环', 'mat_pilates', 1, NOW(), NOW()),
|
||||
|
||||
('mat_roll_up', '卷起', '垫上普拉提', '从仰卧位缓慢卷起至坐姿,锻炼脊柱逐节控制能力', '核心肌群、脊柱灵活性、腘绳肌柔韧性', NULL, 6, NULL, NULL, NULL, NULL, 'mat_pilates', 2, NOW(), NOW()),
|
||||
|
||||
('mat_single_leg_circle', '单腿画圈', '垫上普拉提', '单腿做圆周运动,保持骨盆稳定', '核心稳定性、髋关节灵活性、股四头肌、腘绳肌、臀肌', NULL, 5, NULL, NULL, NULL, '每条腿每个方向5次', 'mat_pilates', 3, NOW(), NOW()),
|
||||
|
||||
('mat_rolling_like_ball', '滚球', '垫上普拉提', '保持紧凑姿势前后滚动,挑战平衡和控制', '核心肌群、脊柱柔韧性、平衡感', NULL, 8, NULL, NULL, NULL, '6-8次', 'mat_pilates', 4, NOW(), NOW()),
|
||||
|
||||
('mat_single_leg_stretch', '单腿伸展', '垫上普拉提', '交替单腿伸展,保持上身抬起', '核心肌群、髋屈肌、股四头肌', NULL, 10, NULL, NULL, NULL, '每侧8-10次', 'mat_pilates', 5, NOW(), NOW()),
|
||||
|
||||
('mat_double_leg_stretch', '双腿伸展', '垫上普拉提', '双腿和手臂同时伸展,回到起始位置', '核心肌群、髋屈肌、股四头肌、肩部稳定性', NULL, 10, NULL, NULL, NULL, '6-10次', 'mat_pilates', 6, NOW(), NOW()),
|
||||
|
||||
('mat_spine_stretch', '脊柱伸展', '垫上普拉提', '坐姿前屈,逐节伸展脊柱', '脊柱柔韧性、腘绳肌伸展、核心控制', NULL, 6, NULL, NULL, NULL, NULL, 'mat_pilates', 7, NOW(), NOW()),
|
||||
|
||||
('mat_saw', '锯式', '垫上普拉提', '坐姿扭转配合前屈,增强脊柱旋转能力', '腹斜肌、背部伸肌、脊柱旋转灵活性', NULL, 6, NULL, NULL, NULL, '每侧6次', 'mat_pilates', 8, NOW(), NOW()),
|
||||
|
||||
('mat_swan', '天鹅式', '垫上普拉提', '俯卧位脊柱后伸,强化背部肌群', '背部伸肌、臀肌、腘绳肌', NULL, 6, NULL, NULL, NULL, NULL, 'mat_pilates', 9, NOW(), NOW()),
|
||||
|
||||
('mat_shoulder_bridge', '肩桥', '垫上普拉提', '仰卧抬臀,激活后链肌群', '臀肌、腘绳肌、下背部、脊柱灵活性', NULL, 6, NULL, NULL, NULL, NULL, 'mat_pilates', 10, NOW(), NOW());
|
||||
|
||||
-- 插入核心床(Reformer)动作数据
|
||||
INSERT INTO t_exercises (
|
||||
key, name, category_name, description, target_muscle_groups, equipment_name,
|
||||
beginner_reps, beginner_sets, breathing_cycles, hold_duration, special_instructions,
|
||||
category_key, sort_order, created_at, updated_at
|
||||
) VALUES
|
||||
('reformer_footwork', '脚部练习系列', '核心床', '在核心床上进行各种脚部位置的推蹬练习', '腿部、足部、核心稳定性', '核心床', 10, NULL, NULL, NULL, NULL, 'reformer', 1, NOW(), NOW()),
|
||||
|
||||
('reformer_hundred', '百次拍打', '核心床', '在核心床上进行百次拍打,增加阻力挑战', '核心肌群、呼吸肌群、上身耐力', '核心床', NULL, NULL, 10, NULL, '10个呼吸循环', 'reformer', 2, NOW(), NOW()),
|
||||
|
||||
('reformer_bridge', '桥式', '核心床', '在核心床上进行桥式动作,利用弹簧阻力', '臀肌、腘绳肌、脊柱关节', '核心床', 10, NULL, NULL, NULL, '6-10次', 'reformer', 3, NOW(), NOW()),
|
||||
|
||||
('reformer_straps', '脚套带练习', '核心床', '使用脚套带进行各种腿部和髋部练习', '髋部灵活性、骨盆稳定性、身体控制、内收肌', '核心床', 10, NULL, NULL, NULL, '8-10次', 'reformer', 4, NOW(), NOW()),
|
||||
|
||||
('reformer_elephant', '象式', '核心床', '四点跪撑位置进行推拉练习', '核心肌群、腘绳肌、背部伸肌、肩部稳定性', '核心床', 10, NULL, NULL, NULL, '8-10次', 'reformer', 5, NOW(), NOW()),
|
||||
|
||||
('reformer_knee_stretch', '跪姿伸展系列', '核心床', '跪姿位置进行多种伸展动作', '核心肌群、髋部灵活性、肩部控制', '核心床', 10, NULL, NULL, NULL, NULL, 'reformer', 6, NOW(), NOW());
|
||||
|
||||
-- 插入凯迪拉克(Cadillac)动作数据
|
||||
INSERT INTO t_exercises (
|
||||
key, name, category_name, description, target_muscle_groups, equipment_name,
|
||||
beginner_reps, beginner_sets, breathing_cycles, hold_duration, special_instructions,
|
||||
category_key, sort_order, created_at, updated_at
|
||||
) VALUES
|
||||
('cadillac_leg_springs', '腿部弹簧系列', '凯迪拉克', '使用腿部弹簧进行各种腿部强化练习', '腘绳肌、股四头肌、臀肌、髋屈肌、内收肌', '凯迪拉克', 20, NULL, NULL, NULL, '10-20次', 'cadillac', 1, NOW(), NOW()),
|
||||
|
||||
('cadillac_arm_springs', '手臂弹簧系列', '凯迪拉克', '使用手臂弹簧进行上身力量训练', '胸部、肩部、上背部、手臂', '凯迪拉克', 15, NULL, NULL, NULL, '10-15次', 'cadillac', 2, NOW(), NOW()),
|
||||
|
||||
('cadillac_roll_down_bar', '滚背杆卷下', '凯迪拉克', '使用滚背杆进行脊柱逐节控制练习', '腹部肌肉、脊柱灵活性', '凯迪拉克', 12, NULL, NULL, NULL, '8-12次', 'cadillac', 3, NOW(), NOW()),
|
||||
|
||||
('cadillac_push_through_bar', '推杆', '凯迪拉克', '推拉横杆进行全身协调练习', '肩部、核心、背部', '凯迪拉克', 12, NULL, NULL, NULL, '8-12次', 'cadillac', 4, NOW(), NOW());
|
||||
|
||||
-- 插入普拉提椅(Chair)动作数据
|
||||
INSERT INTO t_exercises (
|
||||
key, name, category_name, description, target_muscle_groups, equipment_name,
|
||||
beginner_reps, beginner_sets, breathing_cycles, hold_duration, special_instructions,
|
||||
category_key, sort_order, created_at, updated_at
|
||||
) VALUES
|
||||
('chair_seated_march', '坐姿行进', '普拉提椅', '坐在椅子上进行交替抬腿练习', '核心肌群、髋屈肌', '普拉提椅', 12, NULL, NULL, NULL, '每侧10-12次', 'chair', 1, NOW(), NOW()),
|
||||
|
||||
('chair_seated_leg_lift', '坐姿抬腿', '普拉提椅', '坐姿单腿伸展练习', '股四头肌、核心肌群', '普拉提椅', 12, NULL, NULL, NULL, '每侧10-12次', 'chair', 2, NOW(), NOW()),
|
||||
|
||||
('chair_seated_arm_circles', '坐姿手臂画圈', '普拉提椅', '坐姿手臂做圆周运动', '肩部、上背部、手臂', '普拉提椅', 12, NULL, NULL, NULL, '前后各10-12次', 'chair', 3, NOW(), NOW()),
|
||||
|
||||
('chair_spine_twist', '脊柱扭转', '普拉提椅', '坐姿脊柱旋转练习', '腹斜肌、脊柱旋转肌', '普拉提椅', 10, NULL, NULL, NULL, '每侧8-10次', 'chair', 4, NOW(), NOW()),
|
||||
|
||||
('chair_squat', '椅子深蹲', '普拉提椅', '使用椅子进行深蹲练习', '臀肌、股四头肌、腘绳肌、核心', '普拉提椅', 12, NULL, NULL, NULL, '10-12次', 'chair', 5, NOW(), NOW());
|
||||
|
||||
-- 插入普拉提桶(Barrel)动作数据
|
||||
INSERT INTO t_exercises (
|
||||
key, name, category_name, description, target_muscle_groups, equipment_name,
|
||||
beginner_reps, beginner_sets, breathing_cycles, hold_duration, special_instructions,
|
||||
category_key, sort_order, created_at, updated_at
|
||||
) VALUES
|
||||
('barrel_spine_stretch', '脊柱伸展', '普拉提桶', '在桶上进行脊柱后伸练习', '核心肌群、脊柱伸肌、背部肌肉', '普拉提桶', 12, 3, NULL, NULL, '10-12次,2-3组', 'barrel', 1, NOW(), NOW()),
|
||||
|
||||
('barrel_mermaid', '美人鱼伸展', '普拉提桶', '侧坐在桶上进行侧向伸展', '核心肌群、腹斜肌、侧向柔韧性', '普拉提桶', 10, 3, NULL, NULL, '每侧8-10次,2-3组', 'barrel', 2, NOW(), NOW()),
|
||||
|
||||
('barrel_side_bend', '侧弯', '普拉提桶', '侧卧在桶上进行侧向弯曲练习', '腹斜肌、腰部塑形、平衡感、核心稳定性', '普拉提桶', 10, 3, NULL, NULL, '每侧8-10次,2-3组', 'barrel', 3, NOW(), NOW()),
|
||||
|
||||
('barrel_teaser_prep', '预备式Teaser', '普拉提桶', '在桶上进行Teaser动作的预备练习', '核心肌群、平衡感、本体感受', '普拉提桶', 5, 2, NULL, 3, '5次,2组,保持3秒', 'barrel', 4, NOW(), NOW()),
|
||||
|
||||
('barrel_swan_dive_prep', '预备式Swan Dive', '普拉提桶', '在桶上进行Swan Dive的预备练习', '背部伸肌、脊柱伸展、平衡感', '普拉提桶', 5, 2, NULL, 3, '5次,2组,保持3秒', 'barrel', 5, NOW(), NOW());
|
||||
|
||||
-- 提交事务
|
||||
COMMIT;
|
||||
|
||||
-- 验证数据插入
|
||||
SELECT
|
||||
ec.name as category_name,
|
||||
ec.pilates_type,
|
||||
ec.equipment_name,
|
||||
COUNT(e.key) as exercise_count
|
||||
FROM t_exercise_categories ec
|
||||
LEFT JOIN t_exercises e ON ec.key = e.category_key
|
||||
GROUP BY ec.key, ec.name, ec.pilates_type, ec.equipment_name
|
||||
ORDER BY ec.sort_order;
|
||||
@@ -1,64 +0,0 @@
|
||||
-- 普拉提数据库结构迁移脚本
|
||||
-- 此脚本用于将现有的数据库结构升级以支持新的普拉提分类和动作系统
|
||||
|
||||
-- 开始事务
|
||||
BEGIN;
|
||||
|
||||
-- 1. 为分类表添加新字段
|
||||
ALTER TABLE t_exercise_categories
|
||||
ADD COLUMN pilates_type ENUM('mat_pilates', 'equipment_pilates') NOT NULL DEFAULT 'mat_pilates' COMMENT '普拉提类型:垫上普拉提或器械普拉提';
|
||||
|
||||
ALTER TABLE t_exercise_categories
|
||||
ADD COLUMN equipment_name VARCHAR(255) NULL COMMENT '器械名称(仅器械普拉提需要)';
|
||||
|
||||
-- 2. 为动作表添加新字段
|
||||
ALTER TABLE t_exercises
|
||||
ADD COLUMN target_muscle_groups TEXT NOT NULL DEFAULT '' COMMENT '主要锻炼肌肉群';
|
||||
|
||||
ALTER TABLE t_exercises
|
||||
ADD COLUMN equipment_name VARCHAR(255) NULL COMMENT '器械名称(器械普拉提专用)';
|
||||
|
||||
ALTER TABLE t_exercises
|
||||
ADD COLUMN beginner_reps INTEGER NULL COMMENT '入门级别建议练习次数';
|
||||
|
||||
ALTER TABLE t_exercises
|
||||
ADD COLUMN beginner_sets INTEGER NULL COMMENT '入门级别建议组数';
|
||||
|
||||
ALTER TABLE t_exercises
|
||||
ADD COLUMN breathing_cycles INTEGER NULL COMMENT '呼吸循环次数(替代普通次数)';
|
||||
|
||||
ALTER TABLE t_exercises
|
||||
ADD COLUMN hold_duration INTEGER NULL COMMENT '保持时间(秒)';
|
||||
|
||||
ALTER TABLE t_exercises
|
||||
ADD COLUMN special_instructions VARCHAR(255) NULL COMMENT '特殊说明(如每侧、前后各等)';
|
||||
|
||||
-- 3. 修改现有字段属性
|
||||
ALTER TABLE t_exercises
|
||||
MODIFY COLUMN description TEXT NULL COMMENT '动作描述';
|
||||
|
||||
-- 提交事务
|
||||
COMMIT;
|
||||
|
||||
-- 验证表结构
|
||||
SELECT
|
||||
COLUMN_NAME,
|
||||
COLUMN_TYPE,
|
||||
IS_NULLABLE,
|
||||
COLUMN_DEFAULT,
|
||||
COLUMN_COMMENT
|
||||
FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE TABLE_NAME = 't_exercise_categories'
|
||||
AND TABLE_SCHEMA = DATABASE()
|
||||
ORDER BY ORDINAL_POSITION;
|
||||
|
||||
SELECT
|
||||
COLUMN_NAME,
|
||||
COLUMN_TYPE,
|
||||
IS_NULLABLE,
|
||||
COLUMN_DEFAULT,
|
||||
COLUMN_COMMENT
|
||||
FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE TABLE_NAME = 't_exercises'
|
||||
AND TABLE_SCHEMA = DATABASE()
|
||||
ORDER BY ORDINAL_POSITION;
|
||||
@@ -1,247 +0,0 @@
|
||||
-- 普拉提训练系统完整表结构创建脚本
|
||||
-- 执行前请确保删除旧表(注意删除顺序,避免外键约束错误)
|
||||
|
||||
-- 禁用外键检查(创建时)
|
||||
SET FOREIGN_KEY_CHECKS = 0;
|
||||
|
||||
-- 删除现有表(如果存在)
|
||||
DROP TABLE IF EXISTS `t_schedule_exercises`;
|
||||
DROP TABLE IF EXISTS `t_training_plans`;
|
||||
DROP TABLE IF EXISTS `t_exercises`;
|
||||
DROP TABLE IF EXISTS `t_exercise_categories`;
|
||||
|
||||
-- 重新启用外键检查
|
||||
SET FOREIGN_KEY_CHECKS = 1;
|
||||
|
||||
-- 创建分类表
|
||||
CREATE TABLE `t_exercise_categories` (
|
||||
`key` varchar(255) NOT NULL COMMENT '分类唯一键(英文/下划线)',
|
||||
`name` varchar(255) NOT NULL COMMENT '分类中文名称',
|
||||
`type` enum('mat_pilates','equipment_pilates') NOT NULL DEFAULT 'mat_pilates' COMMENT '普拉提类型:垫上普拉提或器械普拉提',
|
||||
`equipment_name` varchar(255) DEFAULT NULL COMMENT '器械名称(仅器械普拉提需要)',
|
||||
`sort_order` int NOT NULL DEFAULT '0' COMMENT '排序(升序)',
|
||||
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
PRIMARY KEY (`key`),
|
||||
KEY `idx_sort_order` (`sort_order`),
|
||||
KEY `idx_type` (`type`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='普拉提训练分类表';
|
||||
|
||||
-- 创建动作表
|
||||
CREATE TABLE `t_exercises` (
|
||||
`key` varchar(255) NOT NULL COMMENT '动作唯一键(英文/下划线)',
|
||||
`name` varchar(255) NOT NULL COMMENT '动作名称',
|
||||
`category_name` varchar(255) NOT NULL COMMENT '中文分类名(冗余,便于展示)',
|
||||
`description` text DEFAULT NULL COMMENT '动作描述',
|
||||
`target_muscle_groups` text NOT NULL COMMENT '主要锻炼肌肉群',
|
||||
`equipment_name` varchar(255) DEFAULT NULL COMMENT '器械名称(器械普拉提专用)',
|
||||
`beginner_reps` int DEFAULT NULL COMMENT '入门级别建议练习次数',
|
||||
`beginner_sets` int DEFAULT NULL COMMENT '入门级别建议组数',
|
||||
`breathing_cycles` int DEFAULT NULL COMMENT '呼吸循环次数(替代普通次数)',
|
||||
`hold_duration` int DEFAULT NULL COMMENT '保持时间(秒)',
|
||||
`special_instructions` varchar(255) DEFAULT NULL COMMENT '特殊说明(如每侧、前后各等)',
|
||||
`category_key` varchar(255) NOT NULL COMMENT '分类键',
|
||||
`sort_order` int NOT NULL DEFAULT '0' COMMENT '排序(分类内)',
|
||||
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
PRIMARY KEY (`key`),
|
||||
KEY `idx_category_key` (`category_key`),
|
||||
KEY `idx_sort_order` (`sort_order`),
|
||||
KEY `idx_category_sort` (`category_key`, `sort_order`),
|
||||
KEY `idx_equipment_name` (`equipment_name`),
|
||||
CONSTRAINT `fk_exercises_category` FOREIGN KEY (`category_key`) REFERENCES `t_exercise_categories` (`key`) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='普拉提训练动作表';
|
||||
|
||||
-- 创建训练计划表
|
||||
CREATE TABLE `t_training_plans` (
|
||||
`id` char(36) NOT NULL COMMENT '训练计划唯一ID',
|
||||
`is_active` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否激活',
|
||||
`user_id` varchar(255) NOT NULL COMMENT '用户ID',
|
||||
`name` varchar(255) DEFAULT NULL COMMENT '计划名称',
|
||||
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`start_date` datetime NOT NULL COMMENT '开始日期',
|
||||
`mode` enum('daysOfWeek','sessionsPerWeek') NOT NULL COMMENT '计划模式',
|
||||
`days_of_week` json NOT NULL COMMENT '周几训练(0-6)',
|
||||
`sessions_per_week` int NOT NULL COMMENT '每周训练次数',
|
||||
`goal` enum('postpartum_recovery','fat_loss','posture_correction','core_strength','flexibility','rehab','stress_relief','') NOT NULL COMMENT '训练目标',
|
||||
`start_weight_kg` float DEFAULT NULL COMMENT '起始体重(公斤)',
|
||||
`preferred_time_of_day` enum('morning','noon','evening','') NOT NULL DEFAULT '' COMMENT '偏好训练时间',
|
||||
`updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`deleted` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否已删除',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_user_id` (`user_id`),
|
||||
KEY `idx_is_active` (`is_active`),
|
||||
KEY `idx_deleted` (`deleted`),
|
||||
KEY `idx_user_active` (`user_id`, `is_active`, `deleted`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='训练计划表';
|
||||
|
||||
-- 创建训练计划动作表
|
||||
CREATE TABLE `t_schedule_exercises` (
|
||||
`id` char(36) NOT NULL COMMENT '计划动作唯一ID',
|
||||
`training_plan_id` char(36) NOT NULL COMMENT '训练计划ID',
|
||||
`user_id` varchar(255) NOT NULL COMMENT '用户ID',
|
||||
`exercise_key` varchar(255) DEFAULT NULL COMMENT '关联的动作key(仅exercise类型)',
|
||||
`name` varchar(255) NOT NULL COMMENT '项目名称',
|
||||
`sets` int DEFAULT NULL COMMENT '组数',
|
||||
`reps` int DEFAULT NULL COMMENT '重复次数',
|
||||
`duration_sec` int DEFAULT NULL COMMENT '持续时长(秒)',
|
||||
`rest_sec` int DEFAULT NULL COMMENT '休息时长(秒)',
|
||||
`note` text DEFAULT NULL COMMENT '备注',
|
||||
`item_type` enum('exercise','rest','note') NOT NULL DEFAULT 'exercise' COMMENT '项目类型',
|
||||
`completed` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否已完成',
|
||||
`sort_order` int NOT NULL COMMENT '排序顺序',
|
||||
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`deleted` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否已删除',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_training_plan_id` (`training_plan_id`),
|
||||
KEY `idx_exercise_key` (`exercise_key`),
|
||||
KEY `idx_user_id` (`user_id`),
|
||||
KEY `idx_sort_order` (`sort_order`),
|
||||
KEY `idx_item_type` (`item_type`),
|
||||
KEY `idx_plan_sort` (`training_plan_id`, `sort_order`),
|
||||
CONSTRAINT `fk_schedule_exercises_training_plan` FOREIGN KEY (`training_plan_id`) REFERENCES `t_training_plans` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
CONSTRAINT `fk_schedule_exercises_exercise` FOREIGN KEY (`exercise_key`) REFERENCES `t_exercises` (`key`) ON DELETE SET NULL ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='训练计划动作表';
|
||||
|
||||
-- 创建索引以优化查询性能
|
||||
-- 分类表索引已在建表时创建
|
||||
|
||||
-- 动作表额外索引
|
||||
CREATE INDEX `idx_target_muscle_groups` ON `t_exercises` (`target_muscle_groups`(100));
|
||||
|
||||
-- 插入初始数据
|
||||
-- 插入普拉提分类数据
|
||||
INSERT INTO `t_exercise_categories` (`key`, `name`, `type`, `equipment_name`, `sort_order`, `created_at`, `updated_at`) VALUES
|
||||
-- 垫上普拉提
|
||||
('mat_pilates', '垫上普拉提', 'mat_pilates', NULL, 1, NOW(), NOW()),
|
||||
|
||||
-- 器械普拉提
|
||||
('reformer', '核心床', 'equipment_pilates', '核心床', 2, NOW(), NOW()),
|
||||
('cadillac', '凯迪拉克', 'equipment_pilates', '凯迪拉克', 3, NOW(), NOW()),
|
||||
('chair', '普拉提椅', 'equipment_pilates', '普拉提椅', 4, NOW(), NOW()),
|
||||
('barrel', '普拉提桶', 'equipment_pilates', '普拉提桶', 5, NOW(), NOW());
|
||||
|
||||
-- 插入垫上普拉提动作数据
|
||||
INSERT INTO `t_exercises` (
|
||||
`key`, `name`, `category_name`, `description`, `target_muscle_groups`, `equipment_name`,
|
||||
`beginner_reps`, `beginner_sets`, `breathing_cycles`, `hold_duration`, `special_instructions`,
|
||||
`category_key`, `sort_order`, `created_at`, `updated_at`
|
||||
) VALUES
|
||||
('mat_hundred', '百次拍打', '垫上普拉提', '经典的普拉提动作,通过有节奏的手臂拍打配合呼吸来激活核心', '核心肌群、呼吸肌群、肩部稳定性', NULL, NULL, NULL, 10, NULL, '10个呼吸循环', 'mat_pilates', 1, NOW(), NOW()),
|
||||
|
||||
('mat_roll_up', '卷起', '垫上普拉提', '从仰卧位缓慢卷起至坐姿,锻炼脊柱逐节控制能力', '核心肌群、脊柱灵活性、腘绳肌柔韧性', NULL, 6, NULL, NULL, NULL, NULL, 'mat_pilates', 2, NOW(), NOW()),
|
||||
|
||||
('mat_single_leg_circle', '单腿画圈', '垫上普拉提', '单腿做圆周运动,保持骨盆稳定', '核心稳定性、髋关节灵活性、股四头肌、腘绳肌、臀肌', NULL, 5, NULL, NULL, NULL, '每条腿每个方向5次', 'mat_pilates', 3, NOW(), NOW()),
|
||||
|
||||
('mat_rolling_like_ball', '滚球', '垫上普拉提', '保持紧凑姿势前后滚动,挑战平衡和控制', '核心肌群、脊柱柔韧性、平衡感', NULL, 8, NULL, NULL, NULL, '6-8次', 'mat_pilates', 4, NOW(), NOW()),
|
||||
|
||||
('mat_single_leg_stretch', '单腿伸展', '垫上普拉提', '交替单腿伸展,保持上身抬起', '核心肌群、髋屈肌、股四头肌', NULL, 10, NULL, NULL, NULL, '每侧8-10次', 'mat_pilates', 5, NOW(), NOW()),
|
||||
|
||||
('mat_double_leg_stretch', '双腿伸展', '垫上普拉提', '双腿和手臂同时伸展,回到起始位置', '核心肌群、髋屈肌、股四头肌、肩部稳定性', NULL, 10, NULL, NULL, NULL, '6-10次', 'mat_pilates', 6, NOW(), NOW()),
|
||||
|
||||
('mat_spine_stretch', '脊柱伸展', '垫上普拉提', '坐姿前屈,逐节伸展脊柱', '脊柱柔韧性、腘绳肌伸展、核心控制', NULL, 6, NULL, NULL, NULL, NULL, 'mat_pilates', 7, NOW(), NOW()),
|
||||
|
||||
('mat_saw', '锯式', '垫上普拉提', '坐姿扭转配合前屈,增强脊柱旋转能力', '腹斜肌、背部伸肌、脊柱旋转灵活性', NULL, 6, NULL, NULL, NULL, '每侧6次', 'mat_pilates', 8, NOW(), NOW()),
|
||||
|
||||
('mat_swan', '天鹅式', '垫上普拉提', '俯卧位脊柱后伸,强化背部肌群', '背部伸肌、臀肌、腘绳肌', NULL, 6, NULL, NULL, NULL, NULL, 'mat_pilates', 9, NOW(), NOW()),
|
||||
|
||||
('mat_shoulder_bridge', '肩桥', '垫上普拉提', '仰卧抬臀,激活后链肌群', '臀肌、腘绳肌、下背部、脊柱灵活性', NULL, 6, NULL, NULL, NULL, NULL, 'mat_pilates', 10, NOW(), NOW());
|
||||
|
||||
-- 插入核心床(Reformer)动作数据
|
||||
INSERT INTO `t_exercises` (
|
||||
`key`, `name`, `category_name`, `description`, `target_muscle_groups`, `equipment_name`,
|
||||
`beginner_reps`, `beginner_sets`, `breathing_cycles`, `hold_duration`, `special_instructions`,
|
||||
`category_key`, `sort_order`, `created_at`, `updated_at`
|
||||
) VALUES
|
||||
('reformer_footwork', '脚部练习系列', '核心床', '在核心床上进行各种脚部位置的推蹬练习', '腿部、足部、核心稳定性', '核心床', 10, NULL, NULL, NULL, NULL, 'reformer', 1, NOW(), NOW()),
|
||||
|
||||
('reformer_hundred', '百次拍打', '核心床', '在核心床上进行百次拍打,增加阻力挑战', '核心肌群、呼吸肌群、上身耐力', '核心床', NULL, NULL, 10, NULL, '10个呼吸循环', 'reformer', 2, NOW(), NOW()),
|
||||
|
||||
('reformer_bridge', '桥式', '核心床', '在核心床上进行桥式动作,利用弹簧阻力', '臀肌、腘绳肌、脊柱关节', '核心床', 10, NULL, NULL, NULL, '6-10次', 'reformer', 3, NOW(), NOW()),
|
||||
|
||||
('reformer_straps', '脚套带练习', '核心床', '使用脚套带进行各种腿部和髋部练习', '髋部灵活性、骨盆稳定性、身体控制、内收肌', '核心床', 10, NULL, NULL, NULL, '8-10次', 'reformer', 4, NOW(), NOW()),
|
||||
|
||||
('reformer_elephant', '象式', '核心床', '四点跪撑位置进行推拉练习', '核心肌群、腘绳肌、背部伸肌、肩部稳定性', '核心床', 10, NULL, NULL, NULL, '8-10次', 'reformer', 5, NOW(), NOW()),
|
||||
|
||||
('reformer_knee_stretch', '跪姿伸展系列', '核心床', '跪姿位置进行多种伸展动作', '核心肌群、髋部灵活性、肩部控制', '核心床', 10, NULL, NULL, NULL, NULL, 'reformer', 6, NOW(), NOW());
|
||||
|
||||
-- 插入凯迪拉克(Cadillac)动作数据
|
||||
INSERT INTO `t_exercises` (
|
||||
`key`, `name`, `category_name`, `description`, `target_muscle_groups`, `equipment_name`,
|
||||
`beginner_reps`, `beginner_sets`, `breathing_cycles`, `hold_duration`, `special_instructions`,
|
||||
`category_key`, `sort_order`, `created_at`, `updated_at`
|
||||
) VALUES
|
||||
('cadillac_leg_springs', '腿部弹簧系列', '凯迪拉克', '使用腿部弹簧进行各种腿部强化练习', '腘绳肌、股四头肌、臀肌、髋屈肌、内收肌', '凯迪拉克', 20, NULL, NULL, NULL, '10-20次', 'cadillac', 1, NOW(), NOW()),
|
||||
|
||||
('cadillac_arm_springs', '手臂弹簧系列', '凯迪拉克', '使用手臂弹簧进行上身力量训练', '胸部、肩部、上背部、手臂', '凯迪拉克', 15, NULL, NULL, NULL, '10-15次', 'cadillac', 2, NOW(), NOW()),
|
||||
|
||||
('cadillac_roll_down_bar', '滚背杆卷下', '凯迪拉克', '使用滚背杆进行脊柱逐节控制练习', '腹部肌肉、脊柱灵活性', '凯迪拉克', 12, NULL, NULL, NULL, '8-12次', 'cadillac', 3, NOW(), NOW()),
|
||||
|
||||
('cadillac_push_through_bar', '推杆', '凯迪拉克', '推拉横杆进行全身协调练习', '肩部、核心、背部', '凯迪拉克', 12, NULL, NULL, NULL, '8-12次', 'cadillac', 4, NOW(), NOW());
|
||||
|
||||
-- 插入普拉提椅(Chair)动作数据
|
||||
INSERT INTO `t_exercises` (
|
||||
`key`, `name`, `category_name`, `description`, `target_muscle_groups`, `equipment_name`,
|
||||
`beginner_reps`, `beginner_sets`, `breathing_cycles`, `hold_duration`, `special_instructions`,
|
||||
`category_key`, `sort_order`, `created_at`, `updated_at`
|
||||
) VALUES
|
||||
('chair_seated_march', '坐姿行进', '普拉提椅', '坐在椅子上进行交替抬腿练习', '核心肌群、髋屈肌', '普拉提椅', 12, NULL, NULL, NULL, '每侧10-12次', 'chair', 1, NOW(), NOW()),
|
||||
|
||||
('chair_seated_leg_lift', '坐姿抬腿', '普拉提椅', '坐姿单腿伸展练习', '股四头肌、核心肌群', '普拉提椅', 12, NULL, NULL, NULL, '每侧10-12次', 'chair', 2, NOW(), NOW()),
|
||||
|
||||
('chair_seated_arm_circles', '坐姿手臂画圈', '普拉提椅', '坐姿手臂做圆周运动', '肩部、上背部、手臂', '普拉提椅', 12, NULL, NULL, NULL, '前后各10-12次', 'chair', 3, NOW(), NOW()),
|
||||
|
||||
('chair_spine_twist', '脊柱扭转', '普拉提椅', '坐姿脊柱旋转练习', '腹斜肌、脊柱旋转肌', '普拉提椅', 10, NULL, NULL, NULL, '每侧8-10次', 'chair', 4, NOW(), NOW()),
|
||||
|
||||
('chair_squat', '椅子深蹲', '普拉提椅', '使用椅子进行深蹲练习', '臀肌、股四头肌、腘绳肌、核心', '普拉提椅', 12, NULL, NULL, NULL, '10-12次', 'chair', 5, NOW(), NOW());
|
||||
|
||||
-- 插入普拉提桶(Barrel)动作数据
|
||||
INSERT INTO `t_exercises` (
|
||||
`key`, `name`, `category_name`, `description`, `target_muscle_groups`, `equipment_name`,
|
||||
`beginner_reps`, `beginner_sets`, `breathing_cycles`, `hold_duration`, `special_instructions`,
|
||||
`category_key`, `sort_order`, `created_at`, `updated_at`
|
||||
) VALUES
|
||||
('barrel_spine_stretch', '脊柱伸展', '普拉提桶', '在桶上进行脊柱后伸练习', '核心肌群、脊柱伸肌、背部肌肉', '普拉提桶', 12, 3, NULL, NULL, '10-12次,2-3组', 'barrel', 1, NOW(), NOW()),
|
||||
|
||||
('barrel_mermaid', '美人鱼伸展', '普拉提桶', '侧坐在桶上进行侧向伸展', '核心肌群、腹斜肌、侧向柔韧性', '普拉提桶', 10, 3, NULL, NULL, '每侧8-10次,2-3组', 'barrel', 2, NOW(), NOW()),
|
||||
|
||||
('barrel_side_bend', '侧弯', '普拉提桶', '侧卧在桶上进行侧向弯曲练习', '腹斜肌、腰部塑形、平衡感、核心稳定性', '普拉提桶', 10, 3, NULL, NULL, '每侧8-10次,2-3组', 'barrel', 3, NOW(), NOW()),
|
||||
|
||||
('barrel_teaser_prep', '预备式Teaser', '普拉提桶', '在桶上进行Teaser动作的预备练习', '核心肌群、平衡感、本体感受', '普拉提桶', 5, 2, NULL, 3, '5次,2组,保持3秒', 'barrel', 4, NOW(), NOW()),
|
||||
|
||||
('barrel_swan_dive_prep', '预备式Swan Dive', '普拉提桶', '在桶上进行Swan Dive的预备练习', '背部伸肌、脊柱伸展、平衡感', '普拉提桶', 5, 2, NULL, 3, '5次,2组,保持3秒', 'barrel', 5, NOW(), NOW());
|
||||
|
||||
-- 验证数据插入结果
|
||||
SELECT
|
||||
ec.name as category_name,
|
||||
ec.type,
|
||||
ec.equipment_name,
|
||||
COUNT(e.key) as exercise_count
|
||||
FROM t_exercise_categories ec
|
||||
LEFT JOIN t_exercises e ON ec.key = e.category_key
|
||||
GROUP BY ec.key, ec.name, ec.type, ec.equipment_name
|
||||
ORDER BY ec.sort_order;
|
||||
|
||||
-- 验证表结构
|
||||
SELECT
|
||||
TABLE_NAME,
|
||||
TABLE_COMMENT,
|
||||
TABLE_ROWS
|
||||
FROM INFORMATION_SCHEMA.TABLES
|
||||
WHERE TABLE_SCHEMA = DATABASE()
|
||||
AND TABLE_NAME IN ('t_exercise_categories', 't_exercises', 't_training_plans', 't_schedule_exercises')
|
||||
ORDER BY TABLE_NAME;
|
||||
|
||||
-- 验证外键约束
|
||||
SELECT
|
||||
CONSTRAINT_NAME,
|
||||
TABLE_NAME,
|
||||
COLUMN_NAME,
|
||||
REFERENCED_TABLE_NAME,
|
||||
REFERENCED_COLUMN_NAME
|
||||
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
|
||||
WHERE TABLE_SCHEMA = DATABASE()
|
||||
AND REFERENCED_TABLE_NAME IS NOT NULL
|
||||
AND TABLE_NAME IN ('t_exercises', 't_schedule_exercises')
|
||||
ORDER BY TABLE_NAME, CONSTRAINT_NAME;
|
||||
@@ -1,138 +0,0 @@
|
||||
-- 训练计划相关表单独创建脚本
|
||||
-- 此脚本仅创建训练计划相关的表,前提是动作表已经存在
|
||||
|
||||
-- 禁用外键检查
|
||||
SET FOREIGN_KEY_CHECKS = 0;
|
||||
|
||||
-- 删除训练计划相关表(如果存在)
|
||||
DROP TABLE IF EXISTS `t_schedule_exercises`;
|
||||
DROP TABLE IF EXISTS `t_training_plans`;
|
||||
|
||||
-- 重新启用外键检查
|
||||
SET FOREIGN_KEY_CHECKS = 1;
|
||||
|
||||
-- 创建训练计划表
|
||||
CREATE TABLE `t_training_plans` (
|
||||
`id` char(36) NOT NULL COMMENT '训练计划唯一ID',
|
||||
`is_active` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否激活',
|
||||
`user_id` varchar(255) NOT NULL COMMENT '用户ID',
|
||||
`name` varchar(255) DEFAULT NULL COMMENT '计划名称',
|
||||
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`start_date` datetime NOT NULL COMMENT '开始日期',
|
||||
`mode` enum('daysOfWeek','sessionsPerWeek') NOT NULL COMMENT '计划模式',
|
||||
`days_of_week` json NOT NULL COMMENT '周几训练(0-6)',
|
||||
`sessions_per_week` int NOT NULL COMMENT '每周训练次数',
|
||||
`goal` enum('postpartum_recovery','fat_loss','posture_correction','core_strength','flexibility','rehab','stress_relief','') NOT NULL COMMENT '训练目标',
|
||||
`start_weight_kg` float DEFAULT NULL COMMENT '起始体重(公斤)',
|
||||
`preferred_time_of_day` enum('morning','noon','evening','') NOT NULL DEFAULT '' COMMENT '偏好训练时间',
|
||||
`updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`deleted` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否已删除',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_user_id` (`user_id`),
|
||||
KEY `idx_is_active` (`is_active`),
|
||||
KEY `idx_deleted` (`deleted`),
|
||||
KEY `idx_user_active` (`user_id`, `is_active`, `deleted`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='训练计划表';
|
||||
|
||||
-- 创建训练计划动作表
|
||||
CREATE TABLE `t_schedule_exercises` (
|
||||
`id` char(36) NOT NULL COMMENT '计划动作唯一ID',
|
||||
`training_plan_id` char(36) NOT NULL COMMENT '训练计划ID',
|
||||
`user_id` varchar(255) NOT NULL COMMENT '用户ID',
|
||||
`exercise_key` varchar(255) DEFAULT NULL COMMENT '关联的动作key(仅exercise类型)',
|
||||
`name` varchar(255) NOT NULL COMMENT '项目名称',
|
||||
`sets` int DEFAULT NULL COMMENT '组数',
|
||||
`reps` int DEFAULT NULL COMMENT '重复次数',
|
||||
`duration_sec` int DEFAULT NULL COMMENT '持续时长(秒)',
|
||||
`rest_sec` int DEFAULT NULL COMMENT '休息时长(秒)',
|
||||
`note` text DEFAULT NULL COMMENT '备注',
|
||||
`item_type` enum('exercise','rest','note') NOT NULL DEFAULT 'exercise' COMMENT '项目类型',
|
||||
`completed` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否已完成',
|
||||
`sort_order` int NOT NULL COMMENT '排序顺序',
|
||||
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`deleted` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否已删除',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_training_plan_id` (`training_plan_id`),
|
||||
KEY `idx_exercise_key` (`exercise_key`),
|
||||
KEY `idx_user_id` (`user_id`),
|
||||
KEY `idx_sort_order` (`sort_order`),
|
||||
KEY `idx_item_type` (`item_type`),
|
||||
KEY `idx_plan_sort` (`training_plan_id`, `sort_order`),
|
||||
CONSTRAINT `fk_schedule_exercises_training_plan` FOREIGN KEY (`training_plan_id`) REFERENCES `t_training_plans` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
CONSTRAINT `fk_schedule_exercises_exercise` FOREIGN KEY (`exercise_key`) REFERENCES `t_exercises` (`key`) ON DELETE SET NULL ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='训练计划动作表';
|
||||
|
||||
-- 验证表创建
|
||||
SELECT
|
||||
TABLE_NAME,
|
||||
TABLE_COMMENT,
|
||||
ENGINE
|
||||
FROM INFORMATION_SCHEMA.TABLES
|
||||
WHERE TABLE_SCHEMA = DATABASE()
|
||||
AND TABLE_NAME IN ('t_training_plans', 't_schedule_exercises')
|
||||
ORDER BY TABLE_NAME;
|
||||
|
||||
-- 验证外键约束
|
||||
SELECT
|
||||
CONSTRAINT_NAME,
|
||||
TABLE_NAME,
|
||||
COLUMN_NAME,
|
||||
REFERENCED_TABLE_NAME,
|
||||
REFERENCED_COLUMN_NAME
|
||||
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
|
||||
WHERE TABLE_SCHEMA = DATABASE()
|
||||
AND REFERENCED_TABLE_NAME IS NOT NULL
|
||||
AND TABLE_NAME = 't_schedule_exercises'
|
||||
ORDER BY CONSTRAINT_NAME;
|
||||
|
||||
-- 测试外键约束(插入测试数据)
|
||||
-- 注意:这需要先有有效的 exercise_key 数据
|
||||
|
||||
/*
|
||||
示例测试(请根据实际数据调整):
|
||||
|
||||
-- 插入测试训练计划
|
||||
INSERT INTO t_training_plans (
|
||||
id, user_id, name, start_date, mode, days_of_week, sessions_per_week, goal
|
||||
) VALUES (
|
||||
'550e8400-e29b-41d4-a716-446655440000',
|
||||
'test_user_123',
|
||||
'测试训练计划',
|
||||
NOW(),
|
||||
'daysOfWeek',
|
||||
'[1,3,5]',
|
||||
3,
|
||||
'core_strength'
|
||||
);
|
||||
|
||||
-- 插入测试动作
|
||||
INSERT INTO t_schedule_exercises (
|
||||
id, training_plan_id, user_id, exercise_key, name, sets, reps, item_type, sort_order
|
||||
) VALUES (
|
||||
'550e8400-e29b-41d4-a716-446655440001',
|
||||
'550e8400-e29b-41d4-a716-446655440000',
|
||||
'test_user_123',
|
||||
'mat_hundred',
|
||||
'百次拍打',
|
||||
3,
|
||||
10,
|
||||
'exercise',
|
||||
1
|
||||
);
|
||||
|
||||
-- 验证数据
|
||||
SELECT
|
||||
tp.name as plan_name,
|
||||
se.name as exercise_name,
|
||||
se.exercise_key,
|
||||
e.target_muscle_groups
|
||||
FROM t_training_plans tp
|
||||
JOIN t_schedule_exercises se ON tp.id = se.training_plan_id
|
||||
LEFT JOIN t_exercises e ON se.exercise_key = e.key
|
||||
WHERE tp.user_id = 'test_user_123';
|
||||
|
||||
-- 清理测试数据
|
||||
DELETE FROM t_schedule_exercises WHERE user_id = 'test_user_123';
|
||||
DELETE FROM t_training_plans WHERE user_id = 'test_user_123';
|
||||
*/
|
||||
@@ -1,31 +0,0 @@
|
||||
-- 创建训练会话表
|
||||
CREATE TABLE t_workout_sessions (
|
||||
id VARCHAR(36) PRIMARY KEY DEFAULT (UUID()),
|
||||
user_id VARCHAR(255) NOT NULL COMMENT '用户ID',
|
||||
training_plan_id VARCHAR(36) NOT NULL COMMENT '关联的训练计划模板',
|
||||
name VARCHAR(255) NOT NULL COMMENT '训练会话名称',
|
||||
scheduled_date DATETIME NOT NULL COMMENT '计划训练日期',
|
||||
started_at DATETIME NULL COMMENT '实际开始时间',
|
||||
completed_at DATETIME NULL COMMENT '实际结束时间',
|
||||
status ENUM('planned', 'in_progress', 'completed', 'skipped') NOT NULL DEFAULT 'planned' COMMENT '训练状态',
|
||||
total_duration_sec INT NULL COMMENT '总时长(秒)',
|
||||
summary TEXT NULL COMMENT '训练总结/备注',
|
||||
calories_burned INT NULL COMMENT '消耗卡路里(估算)',
|
||||
stats JSON NULL COMMENT '训练统计数据',
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
deleted BOOLEAN DEFAULT FALSE COMMENT '是否已删除',
|
||||
|
||||
-- 外键约束
|
||||
FOREIGN KEY (training_plan_id) REFERENCES t_training_plans(id),
|
||||
|
||||
-- 索引
|
||||
INDEX idx_user_id (user_id),
|
||||
INDEX idx_training_plan_id (training_plan_id),
|
||||
INDEX idx_scheduled_date (scheduled_date),
|
||||
INDEX idx_status (status),
|
||||
INDEX idx_deleted (deleted)
|
||||
);
|
||||
|
||||
-- 添加表注释
|
||||
ALTER TABLE t_workout_sessions COMMENT = '训练会话表';
|
||||
@@ -1,85 +0,0 @@
|
||||
-- 训练会话相关表创建脚本
|
||||
-- 用于支持每日训练实例功能
|
||||
|
||||
-- 禁用外键检查
|
||||
SET FOREIGN_KEY_CHECKS = 0;
|
||||
|
||||
-- 删除训练会话相关表(如果存在)
|
||||
DROP TABLE IF EXISTS `t_workout_exercises`;
|
||||
DROP TABLE IF EXISTS `t_workout_sessions`;
|
||||
|
||||
-- 重新启用外键检查
|
||||
SET FOREIGN_KEY_CHECKS = 1;
|
||||
|
||||
-- 创建训练会话表
|
||||
CREATE TABLE `t_workout_sessions` (
|
||||
`id` char(36) NOT NULL COMMENT '训练会话唯一ID',
|
||||
`user_id` varchar(255) NOT NULL COMMENT '用户ID',
|
||||
`training_plan_id` char(36) NOT NULL COMMENT '关联的训练计划模板',
|
||||
`name` varchar(255) NOT NULL COMMENT '训练会话名称',
|
||||
`scheduled_date` datetime NOT NULL COMMENT '计划训练日期',
|
||||
`started_at` datetime DEFAULT NULL COMMENT '实际开始时间',
|
||||
`completed_at` datetime DEFAULT NULL COMMENT '实际结束时间',
|
||||
`status` enum('planned','in_progress','completed','skipped') NOT NULL DEFAULT 'planned' COMMENT '训练状态',
|
||||
`total_duration_sec` int DEFAULT NULL COMMENT '总时长(秒)',
|
||||
`summary` text COMMENT '训练总结/备注',
|
||||
`calories_burned` int DEFAULT NULL COMMENT '消耗卡路里(估算)',
|
||||
`stats` json DEFAULT NULL COMMENT '训练统计数据',
|
||||
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`deleted` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否已删除',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_user_id` (`user_id`),
|
||||
KEY `idx_training_plan_id` (`training_plan_id`),
|
||||
KEY `idx_scheduled_date` (`scheduled_date`),
|
||||
KEY `idx_status` (`status`),
|
||||
KEY `idx_deleted` (`deleted`),
|
||||
KEY `idx_user_date` (`user_id`, `scheduled_date`, `deleted`),
|
||||
CONSTRAINT `fk_workout_sessions_training_plan` FOREIGN KEY (`training_plan_id`) REFERENCES `t_training_plans` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='训练会话表(每日训练实例)';
|
||||
|
||||
-- 创建训练会话动作表
|
||||
CREATE TABLE `t_workout_exercises` (
|
||||
`id` char(36) NOT NULL COMMENT '训练动作唯一ID',
|
||||
`workout_session_id` char(36) NOT NULL COMMENT '所属训练会话ID',
|
||||
`user_id` varchar(255) NOT NULL COMMENT '用户ID',
|
||||
`exercise_key` varchar(255) DEFAULT NULL COMMENT '关联的动作key(仅exercise类型)',
|
||||
`name` varchar(255) NOT NULL COMMENT '项目名称',
|
||||
`planned_sets` int DEFAULT NULL COMMENT '计划组数',
|
||||
`completed_sets` int DEFAULT NULL COMMENT '实际完成组数',
|
||||
`planned_reps` int DEFAULT NULL COMMENT '计划重复次数',
|
||||
`completed_reps` int DEFAULT NULL COMMENT '实际完成重复次数',
|
||||
`planned_duration_sec` int DEFAULT NULL COMMENT '计划持续时长(秒)',
|
||||
`actual_duration_sec` int DEFAULT NULL COMMENT '实际持续时长(秒)',
|
||||
`rest_sec` int DEFAULT NULL COMMENT '休息时长(秒)',
|
||||
`note` text COMMENT '备注',
|
||||
`item_type` enum('exercise','rest','note') NOT NULL DEFAULT 'exercise' COMMENT '项目类型',
|
||||
`status` enum('pending','in_progress','completed','skipped') NOT NULL DEFAULT 'pending' COMMENT '动作状态',
|
||||
`sort_order` int NOT NULL COMMENT '排序顺序',
|
||||
`started_at` datetime DEFAULT NULL COMMENT '开始时间',
|
||||
`completed_at` datetime DEFAULT NULL COMMENT '完成时间',
|
||||
`performance_data` json DEFAULT NULL COMMENT '详细执行数据',
|
||||
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`deleted` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否已删除',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_workout_session_id` (`workout_session_id`),
|
||||
KEY `idx_user_id` (`user_id`),
|
||||
KEY `idx_exercise_key` (`exercise_key`),
|
||||
KEY `idx_sort_order` (`sort_order`),
|
||||
KEY `idx_status` (`status`),
|
||||
KEY `idx_deleted` (`deleted`),
|
||||
KEY `idx_session_order` (`workout_session_id`, `sort_order`, `deleted`),
|
||||
CONSTRAINT `fk_workout_exercises_session` FOREIGN KEY (`workout_session_id`) REFERENCES `t_workout_sessions` (`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `fk_workout_exercises_exercise` FOREIGN KEY (`exercise_key`) REFERENCES `t_exercises` (`key`) ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='训练会话动作表(每日训练实例动作)';
|
||||
|
||||
-- 为 t_schedule_exercises 表添加注释,澄清其用途
|
||||
ALTER TABLE `t_schedule_exercises` COMMENT = '训练计划动作表(训练计划模板的动作配置)';
|
||||
|
||||
-- 创建一些有用的索引
|
||||
CREATE INDEX `idx_workout_sessions_user_status` ON `t_workout_sessions` (`user_id`, `status`, `deleted`);
|
||||
CREATE INDEX `idx_workout_exercises_session_type` ON `t_workout_exercises` (`workout_session_id`, `item_type`, `deleted`);
|
||||
|
||||
-- 插入一些示例数据来测试
|
||||
-- 注意:实际使用时应该通过API来创建数据
|
||||
Reference in New Issue
Block a user