Files
msh-system/msh_single_uniapp/documents/数据库字典_tool模块.md

826 lines
33 KiB
Markdown
Raw Normal View History

# Tool模块数据库字典文档
> 慢生活智能营养专家 v2.0
> 文档版本v1.0
> 更新时间2025-01-XX
---
## 目录
1. [概述](#概述)
2. [表结构说明](#表结构说明)
- [0. 现有表扩展字段](#0-现有表扩展字段)
- [1. 食谱计算器相关](#1-食谱计算器相关)
- [2. 营养计划相关](#2-营养计划相关)
- [3. 饮食打卡相关](#3-饮食打卡相关)
- [4. 积分系统相关](#4-积分系统相关)
- [5. AI营养师相关](#5-ai营养师相关)
- [6. 营养师咨询相关](#6-营养师咨询相关)
- [7. 食物百科相关](#7-食物百科相关)
- [8. 营养知识相关](#8-营养知识相关)
- [9. 食谱相关](#9-食谱相关)
- [10. 打卡社区相关](#10-打卡社区相关)
- [11. AI视频相关](#11-ai视频相关)
- [12. 一键打卡相关](#12-一键打卡相关)
3. [表关系图](#表关系图)
4. [索引说明](#索引说明)
---
## 概述
本文档详细说明了Tool模块的所有数据库表结构包括字段定义、数据类型、约束条件、索引等信息。
**命名规范**
- 新建表统一使用 `v2_` 前缀
- 现有表通过扩展字段支持新功能(`eb_user_sign``eb_article``eb_user_integral_record`
- 字段名使用下划线命名snake_case
- 主键统一使用 `表名_id` 格式(如 `result_id``plan_id`
**表分类**
- **现有表扩展**`eb_user_sign`(打卡)、`eb_article`AI视频`eb_user_integral_record`(积分流水)
- **新建表**:所有 `v2_` 前缀的表
**数据类型说明**
- `BIGINT`大整数用于ID字段
- `INT`:整数,用于计数、状态码等
- `DECIMAL(M,N)`:精确小数,用于金额、重量等
- `VARCHAR(N)`:可变字符串
- `TEXT`:长文本
- `TIMESTAMP`:时间戳
- `DATE`:日期
- `TINYINT(1)`布尔值0/1
---
## 表结构说明
### 0. 现有表扩展字段
#### 0.1 eb_user_sign用户签到表 - 扩展字段用于打卡功能)
**表说明**:使用现有 `eb_user_sign` 表,通过扩展字段支持饮食打卡功能。打卡记录使用 `type=3` 标识。
**扩展字段**用于打卡功能type=3时
| 字段名 | 类型 | 是否必填 | 默认值 | 说明 |
|--------|------|---------|--------|------|
| plan_id | BIGINT | 否 | NULL | 关联的营养计划ID |
| meal_type | VARCHAR(20) | 否 | NULL | 餐次breakfast(早餐)/lunch(午餐)/dinner(晚餐)/snack(加餐),打卡时必填 |
| photos_json | TEXT | 否 | NULL | 饮食照片URL数组1-3张JSON格式 |
| notes | TEXT | 否 | NULL | 备注说明(支持语音转文字) |
| voice_url | VARCHAR(500) | 否 | NULL | 语音备注原始文件URL |
| ai_recognized_foods_json | TEXT | 否 | NULL | AI识别的食物列表JSON格式[{name, weight, unit, confidence}] |
| ai_recognition_status | VARCHAR(20) | 否 | 'pending' | AI识别状态pending(待识别)/success(成功)/failed(失败) |
| ai_recognition_time | TIMESTAMP | 否 | NULL | AI识别完成时间 |
| is_manually_corrected | TINYINT(1) | 否 | 0 | 用户是否手动修正了AI识别结果0=否1=是 |
| recommended_dishes_json | TEXT | 否 | NULL | 推荐菜品来自营养计划JSON格式 |
| actual_dishes_json | TEXT | 否 | NULL | 实际食用由AI识别结果生成JSON格式 |
| actual_protein | DECIMAL(5,1) | 否 | NULL | 实际蛋白质摄入(g) |
| actual_energy | INT | 否 | NULL | 实际能量摄入(kcal) |
| actual_potassium | INT | 否 | NULL | 实际钾摄入(mg) |
| actual_phosphorus | INT | 否 | NULL | 实际磷摄入(mg) |
| actual_sodium | INT | 否 | NULL | 实际钠摄入(mg) |
| target_protein | DECIMAL(5,1) | 否 | NULL | 目标蛋白质摄入(g) |
| target_energy | INT | 否 | NULL | 目标能量摄入(kcal) |
| compliance_rate | INT | 否 | NULL | 整体达标率(%) |
| report_id | VARCHAR(50) | 否 | NULL | 报告编号R20251120081501 |
| report_pdf_url | VARCHAR(500) | 否 | NULL | PDF报告下载链接 |
| report_generated_at | TIMESTAMP | 否 | NULL | 报告生成时间 |
| report_download_count | INT | 否 | 0 | 报告下载次数 |
| report_share_count | INT | 否 | 0 | 报告分享次数 |
| ai_comments_json | TEXT | 否 | NULL | AI生成的点评JSON格式 |
| nutrition_score | INT | 否 | NULL | 营养评分0-100 |
| copied_from_sign_id | INT | 否 | NULL | 复制自哪条签到记录ID关联eb_user_sign.id |
| is_copied | TINYINT(1) | 否 | 0 | 是否为复制的打卡0=否1=是 |
**索引**
- UNIQUE KEY `uk_uid_date_meal` (`uid`, `create_day`, `meal_type`, `type`)
- INDEX `idx_plan_id` (`plan_id`)
- INDEX `idx_meal_type` (`meal_type`)
- INDEX `idx_report_id` (`report_id`)
- INDEX `idx_nutrition_score` (`nutrition_score`)
- INDEX `idx_copied_from` (`copied_from_sign_id`)
**业务说明**
- 打卡记录使用 `type=3` 标识
- 同一用户同一天同一餐次只能打卡一次(唯一约束)
- `create_day` 字段用于打卡日期
---
#### 0.2 eb_article文章内容表 - 扩展字段用于AI视频功能
**表说明**:使用现有 `eb_article`通过扩展字段支持AI视频功能。视频类型使用 `type=2` 标识。
**扩展字段**用于AI视频功能type=2时
| 字段名 | 类型 | 是否必填 | 默认值 | 说明 |
|--------|------|---------|--------|------|
| post_id | BIGINT | 否 | NULL | 关联的社区内容IDv2_community_posts.post_id如果是从社区内容生成 |
| check_in_record_id | INT | 否 | NULL | 关联的打卡记录IDeb_user_sign.id当type=2时 |
| thumbnail_url | VARCHAR(500) | 否 | NULL | 视频缩略图URL当type=2时可用image_input代替 |
| duration | INT | 否 | NULL | 视频时长(秒) |
| file_size | BIGINT | 否 | NULL | 视频文件大小(字节) |
| script_json | TEXT | 否 | NULL | 视频脚本JSON场景、文字、时长当type=2时使用 |
| dishes_json | TEXT | 否 | NULL | 菜品清单JSON当type=2时使用 |
| nutrition_json | TEXT | 否 | NULL | 营养数据JSON当type=2时使用 |
| generation_method | VARCHAR(20) | 否 | 'ai' | 生成方式ai(AI生成)/template(模板)当type=2时使用 |
| ai_provider | VARCHAR(50) | 否 | NULL | AI提供商runway/heygen/d-id/jianyng等当type=2时使用 |
| generation_cost | DECIMAL(10,4) | 否 | NULL | 生成成本美元当type=2时使用 |
| generation_time | INT | 否 | NULL | 生成耗时当type=2时使用 |
| download_count | INT | 否 | 0 | 下载次数当type=2时使用view_count用visit字段代替 |
| share_count | INT | 否 | 0 | 分享次数当type=2时使用 |
**已有字段说明**用于AI视频
- `video_url` - 视频地址(已有字段)
- `status_task` - 视频状态0=已创建(对应generating)1=任务完成(对应completed)2=任务失败(对应failed)
- `remark` - 失败原因可用remark字段代替error_message
- `update_time` - 生成完成时间可用update_time字段代替completed_at
- `visit` - 观看次数可用visit字段代替view_count
**索引**
- INDEX `idx_post_id` (`post_id`)
- INDEX `idx_check_in_record_id` (`check_in_record_id`)
- INDEX `idx_type_status_task` (`type`, `status_task`)
**业务说明**
- AI视频使用 `type=2` 标识
- `status_task` 字段表示视频生成状态
- 视频URL存储在 `video_url` 字段
---
#### 0.3 eb_user_integral_record用户积分记录表 - 扩展字段)
**表说明**:使用现有 `eb_user_integral_record` 表,通过扩展字段支持更详细的积分来源记录。
**扩展字段**
| 字段名 | 类型 | 是否必填 | 默认值 | 说明 |
|--------|------|---------|--------|------|
| source_detail | VARCHAR(50) | 否 | NULL | 来源详情check_in(打卡)/photo(照片)/share(分享)/streak(连续打卡)/exchange(兑换)/consult(咨询)/order(订单)/sign(签到)/system(系统) |
**索引**
- INDEX `idx_source_detail` (`source_detail`)
**业务说明**
- `source_detail` 字段用于更详细地记录积分来源
-`link_type` 字段配合使用,提供更精确的积分来源信息
---
### 1. 食谱计算器相关
#### 1.1 v2_calculator_results食谱计算器结果表
**表说明**:存储用户使用食谱计算器计算后的营养方案结果。
| 字段名 | 类型 | 是否必填 | 默认值 | 说明 |
|--------|------|---------|--------|------|
| result_id | BIGINT | 是 | AUTO_INCREMENT | 计算结果ID主键 |
| user_id | BIGINT | 是 | - | 用户ID |
| gender | VARCHAR(10) | 否 | NULL | 性别male/female |
| age | INT | 否 | NULL | 年龄 |
| height | INT | 否 | NULL | 身高(cm) |
| weight | DECIMAL(5,2) | 否 | NULL | 体重(kg) |
| has_dialysis | TINYINT(1) | 否 | 0 | 是否透析0=否1=是 |
| dialysis_type | VARCHAR(20) | 否 | NULL | 透析类型hemodialysis(血液透析)/peritoneal(腹膜透析) |
| dry_weight | DECIMAL(5,2) | 否 | NULL | 干体重(kg) |
| creatinine | DECIMAL(8,2) | 否 | NULL | 血肌酐(μmol/L) |
| egfr | DECIMAL(5,2) | 否 | NULL | eGFR值 |
| standard_weight | DECIMAL(5,2) | 否 | NULL | 标准体重(kg) |
| bmi | DECIMAL(4,1) | 否 | NULL | BMI值 |
| ckd_stage | VARCHAR(50) | 否 | NULL | CKD分期 |
| protein_intake | DECIMAL(5,1) | 否 | NULL | 蛋白质摄入量(g/天) |
| energy_intake | INT | 否 | NULL | 能量摄入量(kcal/天) |
| meal_plan_json | TEXT | 否 | NULL | 配餐方案JSON包含早中晚三餐详情 |
| is_adopted | TINYINT(1) | 否 | 0 | 是否已采纳0=未采纳1=已采纳 |
| adopted_at | TIMESTAMP | 否 | NULL | 采纳时间 |
| created_at | TIMESTAMP | 否 | CURRENT_TIMESTAMP | 创建时间 |
| updated_at | TIMESTAMP | 否 | CURRENT_TIMESTAMP | 更新时间 |
**索引**
- PRIMARY KEY (`result_id`)
- INDEX `idx_user_id` (`user_id`)
- INDEX `idx_is_adopted` (`is_adopted`)
- INDEX `idx_created_at` (`created_at`)
**业务说明**
- 用户每次使用计算器都会生成一条记录
- `is_adopted=1` 时表示用户采纳了该方案会创建对应的营养计划v2_nutrition_plans
- `meal_plan_json` 格式示例:
```json
{
"breakfast": {
"dishes": [{"name": "牛奶", "amount": 120, "unit": "ml"}],
"total_protein": 18.8,
"total_energy": 452
},
"lunch": {...},
"dinner": {...}
}
```
---
### 2. 营养计划相关
#### 2.1 v2_nutrition_plans营养计划表
**表说明**存储用户采纳的营养计划通常为7天周期。
| 字段名 | 类型 | 是否必填 | 默认值 | 说明 |
|--------|------|---------|--------|------|
| plan_id | BIGINT | 是 | AUTO_INCREMENT | 营养计划ID主键 |
| user_id | BIGINT | 是 | - | 用户ID |
| result_id | BIGINT | 否 | NULL | 关联的计算结果ID |
| gender | VARCHAR(10) | 否 | NULL | 性别male/female |
| age | INT | 否 | NULL | 年龄 |
| height | INT | 否 | NULL | 身高(cm) |
| weight | DECIMAL(5,2) | 否 | NULL | 体重(kg) |
| has_dialysis | TINYINT(1) | 否 | 0 | 是否透析0=否1=是 |
| dialysis_type | VARCHAR(20) | 否 | NULL | 透析类型 |
| creatinine | DECIMAL(8,2) | 否 | NULL | 血肌酐(μmol/L) |
| egfr | DECIMAL(5,2) | 否 | NULL | eGFR值 |
| standard_weight | DECIMAL(5,2) | 否 | NULL | 标准体重(kg) |
| bmi | DECIMAL(4,1) | 否 | NULL | BMI值 |
| ckd_stage | VARCHAR(50) | 否 | NULL | CKD分期 |
| protein_intake | DECIMAL(5,1) | 否 | NULL | 蛋白质摄入量(g/天) |
| energy_intake | INT | 否 | NULL | 能量摄入量(kcal/天) |
| meal_plan_json | TEXT | 否 | NULL | 配餐方案JSON |
| status | VARCHAR(20) | 否 | 'active' | 状态active(进行中)/completed(已完成)/abandoned(已放弃) |
| start_date | DATE | 否 | NULL | 计划开始日期 |
| end_date | DATE | 否 | NULL | 计划结束日期通常为start_date + 7天 |
| created_at | TIMESTAMP | 否 | CURRENT_TIMESTAMP | 创建时间 |
| updated_at | TIMESTAMP | 否 | CURRENT_TIMESTAMP | 更新时间 |
**索引**
- PRIMARY KEY (`plan_id`)
- INDEX `idx_user_id` (`user_id`)
- INDEX `idx_status` (`status`)
- INDEX `idx_start_date` (`start_date`)
**业务说明**
- 用户采纳计算结果后创建营养计划
- 一个用户同时只能有一个 `status='active'` 的计划
- `end_date` 通常为 `start_date + 7天`
---
### 3. 饮食打卡相关
#### 3.1 eb_user_sign用户签到表 - 打卡功能)
**表说明**:使用现有 `eb_user_sign` 表,通过扩展字段支持饮食打卡功能。详细字段说明见 [0.1 eb_user_sign用户签到表 - 扩展字段用于打卡功能)](#01-eb_user_sign用户签到表---扩展字段用于打卡功能)。
**业务说明**
- 打卡记录使用 `type=3` 标识
- 同一用户同一天同一餐次只能打卡一次
- 支持AI智能识别食物
- 自动计算营养数据和达标率
- 生成营养分析报告
---
### 4. 积分系统相关
#### 4.1 v2_user_points用户积分表
**表说明**:存储用户积分统计信息。
| 字段名 | 类型 | 是否必填 | 默认值 | 说明 |
|--------|------|---------|--------|------|
| user_id | BIGINT | 是 | - | 用户ID主键 |
| total_points | INT | 否 | 0 | 累计总积分 |
| available_points | INT | 否 | 0 | 可用积分 |
| used_points | INT | 否 | 0 | 已使用积分 |
| total_check_ins | INT | 否 | 0 | 总打卡次数 |
| current_streak | INT | 否 | 0 | 当前连续打卡天数 |
| longest_streak | INT | 否 | 0 | 最长连续打卡天数 |
| last_check_in_date | DATE | 否 | NULL | 最后打卡日期 |
| free_consult_text_count | INT | 否 | 0 | 可用的图文咨询次数 |
| free_consult_voice_count | INT | 否 | 0 | 可用的语音/视频咨询次数 |
| ai_consult_unlimited_expire_at | TIMESTAMP | 否 | NULL | AI不限次咨询过期时间 |
| updated_at | TIMESTAMP | 否 | CURRENT_TIMESTAMP | 更新时间 |
**索引**
- PRIMARY KEY (`user_id`)
**业务说明**
- 每个用户只有一条记录
- `total_points` = `available_points` + `used_points`
- `current_streak` 用于计算连续打卡奖励
---
### 5. AI营养师相关
#### 5.1 v2_ai_conversationsAI营养师对话表
**表说明**存储用户与AI营养师的对话会话。
| 字段名 | 类型 | 是否必填 | 默认值 | 说明 |
|--------|------|---------|--------|------|
| conversation_id | BIGINT | 是 | AUTO_INCREMENT | 对话ID主键 |
| user_id | BIGINT | 是 | - | 用户ID |
| title | VARCHAR(100) | 否 | NULL | 对话标题(自动生成或用户自定义) |
| status | VARCHAR(20) | 否 | 'active' | 状态active(进行中)/archived(已归档)/deleted(已删除) |
| created_at | TIMESTAMP | 否 | CURRENT_TIMESTAMP | 创建时间 |
| updated_at | TIMESTAMP | 否 | CURRENT_TIMESTAMP | 更新时间 |
| last_message_at | TIMESTAMP | 否 | NULL | 最后消息时间 |
**索引**
- PRIMARY KEY (`conversation_id`)
- INDEX `idx_user_id` (`user_id`)
- INDEX `idx_status` (`status`)
- INDEX `idx_last_message_at` (`last_message_at`)
**业务说明**
- 一个用户可以有多个对话会话
- `title` 通常由第一条消息自动生成
---
#### 5.2 v2_ai_messagesAI营养师消息表
**表说明**:存储对话中的每条消息。
| 字段名 | 类型 | 是否必填 | 默认值 | 说明 |
|--------|------|---------|--------|------|
| message_id | BIGINT | 是 | AUTO_INCREMENT | 消息ID主键 |
| conversation_id | BIGINT | 是 | - | 对话ID |
| user_id | BIGINT | 是 | - | 用户ID |
| message_type | VARCHAR(20) | 是 | - | 消息类型text/image/voice |
| content | TEXT | 否 | NULL | 消息内容(文本内容或语音转文字) |
| image_url | VARCHAR(500) | 否 | NULL | 图片URL当type为image时 |
| voice_url | VARCHAR(500) | 否 | NULL | 语音URL当type为voice时 |
| sender | VARCHAR(20) | 是 | - | 发送者user(用户)/ai(AI营养师) |
| ai_response | TEXT | 否 | NULL | AI回复内容 |
| ai_response_status | VARCHAR(20) | 否 | 'pending' | AI回复状态pending/success/failed |
| ai_response_time | TIMESTAMP | 否 | NULL | AI回复时间 |
| created_at | TIMESTAMP | 否 | CURRENT_TIMESTAMP | 创建时间 |
**索引**
- PRIMARY KEY (`message_id`)
- INDEX `idx_conversation_id` (`conversation_id`)
- INDEX `idx_user_id` (`user_id`)
- INDEX `idx_created_at` (`created_at`)
**业务说明**
- 用户发送消息时,`sender='user'``ai_response_status='pending'`
- AI回复后更新 `ai_response``ai_response_status='success'``ai_response_time`
---
### 6. 营养师咨询相关
#### 6.1 v2_nutritionist_consultations营养师咨询记录表
**表说明**:存储用户与真人营养师的咨询记录。
| 字段名 | 类型 | 是否必填 | 默认值 | 说明 |
|--------|------|---------|--------|------|
| consultation_id | BIGINT | 是 | AUTO_INCREMENT | 咨询ID主键 |
| user_id | BIGINT | 是 | - | 用户ID |
| consult_type | VARCHAR(20) | 是 | - | 咨询类型text/voice/video |
| status | VARCHAR(20) | 是 | 'pending' | 状态pending/in_progress/completed/cancelled |
| question_text | TEXT | 否 | NULL | 用户提问 |
| question_images_json | TEXT | 否 | NULL | 问题相关图片URL数组JSON格式 |
| related_report_id | VARCHAR(50) | 否 | NULL | 关联的营养报告ID |
| related_check_in_id | INT | 否 | NULL | 关联的打卡记录ID关联eb_user_sign.id当type=3时 |
| nutritionist_id | BIGINT | 否 | NULL | 营养师ID |
| nutritionist_reply | TEXT | 否 | NULL | 营养师回复 |
| reply_images_json | TEXT | 否 | NULL | 回复相关图片JSON格式 |
| follow_up_count | INT | 否 | 0 | 追问次数 |
| follow_up_questions_json | TEXT | 否 | NULL | 追问和回复记录JSON格式 |
| call_start_time | TIMESTAMP | 否 | NULL | 通话开始时间 |
| call_end_time | TIMESTAMP | 否 | NULL | 通话结束时间 |
| call_duration | INT | 否 | NULL | 通话时长(秒) |
| call_recording_url | VARCHAR(500) | 否 | NULL | 通话录音URL可选 |
| points_cost | INT | 否 | 0 | 消耗积分 |
| cash_cost | DECIMAL(10,2) | 否 | 0 | 现金支付(元) |
| user_rating | INT | 否 | NULL | 用户评分1-5星 |
| user_feedback | TEXT | 否 | NULL | 用户反馈 |
| created_at | TIMESTAMP | 否 | CURRENT_TIMESTAMP | 创建时间 |
| updated_at | TIMESTAMP | 否 | CURRENT_TIMESTAMP | 更新时间 |
| replied_at | TIMESTAMP | 否 | NULL | 营养师回复时间 |
**索引**
- PRIMARY KEY (`consultation_id`)
- INDEX `idx_user_id` (`user_id`)
- INDEX `idx_nutritionist_id` (`nutritionist_id`)
- INDEX `idx_status` (`status`)
- INDEX `idx_created_at` (`created_at`)
**业务说明**
- `follow_up_count` 最多为3次
- `follow_up_questions_json` 格式:
```json
[
{
"question": "那我可以吃西瓜吗?",
"reply": "西瓜属于中等钾含量水果,建议少量食用",
"created_at": "2025-11-20 10:30:00"
}
]
```
---
### 7. 食物百科相关
#### 7.1 v2_foods食物百科表
**表说明**:存储食物百科数据,包含营养成分和适宜性信息。
| 字段名 | 类型 | 是否必填 | 默认值 | 说明 |
|--------|------|---------|--------|------|
| food_id | BIGINT | 是 | AUTO_INCREMENT | 食物ID主键 |
| name | VARCHAR(100) | 是 | - | 食物名称 |
| alias | VARCHAR(200) | 否 | NULL | 别名(多个用逗号分隔) |
| category | VARCHAR(50) | 否 | NULL | 分类grain(主食)/vegetable(蔬菜)/fruit(水果)/meat(肉类)/seafood(海鲜)/dairy(乳制品)/other(其他) |
| image | VARCHAR(500) | 否 | NULL | 食物图片URL |
| protein | DECIMAL(5,2) | 否 | NULL | 蛋白质(g) |
| fat | DECIMAL(5,2) | 否 | NULL | 脂肪(g) |
| carbohydrate | DECIMAL(5,2) | 否 | NULL | 碳水化合物(g) |
| energy | INT | 否 | NULL | 能量(kcal) |
| potassium | INT | 否 | NULL | 钾(mg) |
| phosphorus | INT | 否 | NULL | 磷(mg) |
| sodium | INT | 否 | NULL | 钠(mg) |
| calcium | INT | 否 | NULL | 钙(mg) |
| iron | DECIMAL(5,2) | 否 | NULL | 铁(mg) |
| vitamin_c | DECIMAL(5,2) | 否 | NULL | 维生素C(mg) |
| nutrients_json | TEXT | 否 | NULL | 其他营养成分JSON格式 |
| suitability_level | VARCHAR(20) | 否 | NULL | 适宜性等级suitable(适宜)/moderate(适量)/restricted(限制)/forbidden(禁止) |
| suitability_desc | TEXT | 否 | NULL | 适宜性说明 |
| caution_level | INT | 否 | 0 | 注意事项等级0=无1=低2=中3=高 |
| caution_desc | TEXT | 否 | NULL | 注意事项说明 |
| recommended_amount | VARCHAR(50) | 否 | NULL | 推荐用量50-100g/天 |
| cooking_tips | TEXT | 否 | NULL | 烹饪建议 |
| status | VARCHAR(20) | 否 | 'active' | 状态active/inactive |
| sort_order | INT | 否 | 0 | 排序 |
| view_count | INT | 否 | 0 | 查看次数 |
| created_at | TIMESTAMP | 否 | CURRENT_TIMESTAMP | 创建时间 |
| updated_at | TIMESTAMP | 否 | CURRENT_TIMESTAMP | 更新时间 |
**索引**
- PRIMARY KEY (`food_id`)
- INDEX `idx_name` (`name`)
- INDEX `idx_category` (`category`)
- INDEX `idx_suitability_level` (`suitability_level`)
- INDEX `idx_status` (`status`)
**业务说明**
- 营养成分数据基于《中国食物成分表》第6版
- `suitability_level` 用于快速筛选适宜食物
---
### 8. 营养知识相关
#### 8.1 v2_knowledge营养知识表
**表说明**:存储营养知识文章、指南等内容。
| 字段名 | 类型 | 是否必填 | 默认值 | 说明 |
|--------|------|---------|--------|------|
| knowledge_id | BIGINT | 是 | AUTO_INCREMENT | 知识ID主键 |
| title | VARCHAR(200) | 是 | - | 标题 |
| content | TEXT | 是 | - | 内容 |
| summary | VARCHAR(500) | 否 | NULL | 摘要 |
| cover_image | VARCHAR(500) | 否 | NULL | 封面图URL |
| images_json | TEXT | 否 | NULL | 内容图片数组JSON格式 |
| type | VARCHAR(50) | 否 | NULL | 类型nutrients/guide/article/recipe |
| category | VARCHAR(50) | 否 | NULL | 分类 |
| tags_json | TEXT | 否 | NULL | 标签数组JSON格式 |
| nutrient_name | VARCHAR(50) | 否 | NULL | 关联的营养素名称当type为nutrients时 |
| view_count | INT | 否 | 0 | 查看次数 |
| like_count | INT | 否 | 0 | 点赞次数 |
| collect_count | INT | 否 | 0 | 收藏次数 |
| share_count | INT | 否 | 0 | 分享次数 |
| status | VARCHAR(20) | 否 | 'published' | 状态draft/published/deleted |
| is_recommend | TINYINT(1) | 否 | 0 | 是否推荐0=否1=是 |
| sort_order | INT | 否 | 0 | 排序 |
| created_at | TIMESTAMP | 否 | CURRENT_TIMESTAMP | 创建时间 |
| updated_at | TIMESTAMP | 否 | CURRENT_TIMESTAMP | 更新时间 |
| published_at | TIMESTAMP | 否 | NULL | 发布时间 |
**索引**
- PRIMARY KEY (`knowledge_id`)
- INDEX `idx_type` (`type`)
- INDEX `idx_category` (`category`)
- INDEX `idx_nutrient_name` (`nutrient_name`)
- INDEX `idx_status` (`status`)
- INDEX `idx_is_recommend` (`is_recommend`)
- INDEX `idx_created_at` (`created_at`)
---
### 9. 食谱相关
#### 9.1 v2_recipes食谱表
**表说明**:存储食谱信息,包括官方食谱和用户自定义食谱。
| 字段名 | 类型 | 是否必填 | 默认值 | 说明 |
|--------|------|---------|--------|------|
| recipe_id | BIGINT | 是 | AUTO_INCREMENT | 食谱ID主键 |
| user_id | BIGINT | 否 | NULL | 用户ID用户自定义食谱时 |
| name | VARCHAR(100) | 是 | - | 食谱名称 |
| description | TEXT | 否 | NULL | 食谱描述 |
| cover_image | VARCHAR(500) | 否 | NULL | 封面图URL |
| images_json | TEXT | 否 | NULL | 食谱图片数组JSON格式 |
| meal_type | VARCHAR(20) | 否 | NULL | 餐次breakfast/lunch/dinner/snack |
| category | VARCHAR(50) | 否 | NULL | 分类 |
| tags_json | TEXT | 否 | NULL | 标签数组JSON格式 |
| ingredients_json | TEXT | 否 | NULL | 食材清单JSON格式 |
| steps_json | TEXT | 否 | NULL | 制作步骤JSON格式 |
| total_protein | DECIMAL(5,1) | 否 | NULL | 总蛋白质(g) |
| total_energy | INT | 否 | NULL | 总能量(kcal) |
| total_potassium | INT | 否 | NULL | 总钾(mg) |
| total_phosphorus | INT | 否 | NULL | 总磷(mg) |
| total_sodium | INT | 否 | NULL | 总钠(mg) |
| nutrition_json | TEXT | 否 | NULL | 其他营养成分JSON格式 |
| suitable_stages_json | TEXT | 否 | NULL | 适宜的CKD分期JSON格式 |
| suitable_dialysis | TINYINT(1) | 否 | NULL | 是否适合透析患者0=否1=是 |
| view_count | INT | 否 | 0 | 查看次数 |
| like_count | INT | 否 | 0 | 点赞次数 |
| collect_count | INT | 否 | 0 | 收藏次数 |
| cook_count | INT | 否 | 0 | 制作次数 |
| status | VARCHAR(20) | 否 | 'published' | 状态draft/published/deleted |
| is_recommend | TINYINT(1) | 否 | 0 | 是否推荐0=否1=是 |
| is_official | TINYINT(1) | 否 | 0 | 是否官方食谱0=否1=是 |
| sort_order | INT | 否 | 0 | 排序 |
| created_at | TIMESTAMP | 否 | CURRENT_TIMESTAMP | 创建时间 |
| updated_at | TIMESTAMP | 否 | CURRENT_TIMESTAMP | 更新时间 |
**索引**
- PRIMARY KEY (`recipe_id`)
- INDEX `idx_user_id` (`user_id`)
- INDEX `idx_meal_type` (`meal_type`)
- INDEX `idx_category` (`category`)
- INDEX `idx_status` (`status`)
- INDEX `idx_is_recommend` (`is_recommend`)
- INDEX `idx_created_at` (`created_at`)
**业务说明**
- `ingredients_json` 格式:
```json
[
{"name": "鸡蛋", "amount": 2, "unit": "个"},
{"name": "面条", "amount": 100, "unit": "g"}
]
```
- `steps_json` 格式:
```json
[
{"step": 1, "description": "将鸡蛋打散", "image": "url1"},
{"step": 2, "description": "煮面条", "image": "url2"}
]
```
---
### 10. 打卡社区相关
#### 10.1 v2_community_posts社区内容表
**表说明**:存储用户发布的社区内容(打卡分享)。
| 字段名 | 类型 | 是否必填 | 默认值 | 说明 |
|--------|------|---------|--------|------|
| post_id | BIGINT | 是 | AUTO_INCREMENT | 内容ID主键 |
| user_id | BIGINT | 是 | - | 用户ID |
| check_in_record_id | INT | 否 | NULL | 关联的打卡记录IDeb_user_sign.id当type=3时 |
| title | VARCHAR(100) | 是 | - | 标题 |
| content | TEXT | 否 | NULL | 内容 |
| cover_image | VARCHAR(255) | 否 | NULL | 封面图URL |
| images_json | TEXT | 否 | NULL | 图片数组JSON格式 |
| nutrition_data_json | TEXT | 否 | NULL | 营养数据快照JSON格式 |
| tags_json | TEXT | 否 | NULL | 标签数组JSON格式 |
| like_count | INT | 否 | 0 | 点赞数 |
| comment_count | INT | 否 | 0 | 评论数 |
| collect_count | INT | 否 | 0 | 收藏数 |
| share_count | INT | 否 | 0 | 分享数 |
| view_count | INT | 否 | 0 | 查看数 |
| quick_checkin_count | INT | 否 | 0 | 被一键打卡次数 |
| ai_video_count | INT | 否 | 0 | 生成AI视频次数关联eb_article表type=2时 |
| recommend_score | DECIMAL(10,2) | 否 | 0 | 推荐分数 |
| hot_score | DECIMAL(10,2) | 否 | 0 | 热门分数 |
| status | VARCHAR(20) | 否 | 'published' | 状态draft/published/deleted/banned |
| privacy | VARCHAR(20) | 否 | 'public' | 隐私设置public/followers_only/private |
| audit_status | VARCHAR(20) | 否 | 'pending' | 审核状态pending/approved/rejected |
| audit_time | TIMESTAMP | 否 | NULL | 审核时间 |
| created_at | TIMESTAMP | 否 | CURRENT_TIMESTAMP | 创建时间 |
| updated_at | TIMESTAMP | 否 | CURRENT_TIMESTAMP | 更新时间 |
**索引**
- PRIMARY KEY (`post_id`)
- INDEX `idx_user_id` (`user_id`)
- INDEX `idx_status` (`status`)
- INDEX `idx_created_at` (`created_at`)
- INDEX `idx_recommend_score` (`recommend_score`)
- INDEX `idx_hot_score` (`hot_score`)
---
#### 10.2 v2_community_interactions社区互动表
**表说明**:存储用户对内容的互动记录(点赞、收藏、分享、查看)。
| 字段名 | 类型 | 是否必填 | 默认值 | 说明 |
|--------|------|---------|--------|------|
| interaction_id | BIGINT | 是 | AUTO_INCREMENT | 互动ID主键 |
| user_id | BIGINT | 是 | - | 用户ID |
| post_id | BIGINT | 是 | - | 内容ID |
| interaction_type | VARCHAR(20) | 是 | - | 互动类型like/collect/share/view |
| created_at | TIMESTAMP | 否 | CURRENT_TIMESTAMP | 创建时间 |
**索引**
- PRIMARY KEY (`interaction_id`)
- UNIQUE KEY `uk_user_post_type` (`user_id`, `post_id`, `interaction_type`)
- INDEX `idx_post_id` (`post_id`)
- INDEX `idx_user_id` (`user_id`)
**业务说明**
- 一个用户对一条内容只能有一种类型的互动(唯一约束)
- `view` 类型可以重复记录(用于统计)
---
#### 10.3 v2_community_comments社区评论表
**表说明**:存储社区内容的评论。
| 字段名 | 类型 | 是否必填 | 默认值 | 说明 |
|--------|------|---------|--------|------|
| comment_id | BIGINT | 是 | AUTO_INCREMENT | 评论ID主键 |
| post_id | BIGINT | 是 | - | 内容ID |
| user_id | BIGINT | 是 | - | 用户ID |
| content | TEXT | 是 | - | 评论内容 |
| parent_comment_id | BIGINT | 否 | NULL | 父评论IDNULL为一级评论 |
| reply_to_user_id | BIGINT | 否 | NULL | @的用户ID |
| like_count | INT | 否 | 0 | 点赞数 |
| status | VARCHAR(20) | 否 | 'published' | 状态published/deleted/banned |
| created_at | TIMESTAMP | 否 | CURRENT_TIMESTAMP | 创建时间 |
**索引**
- PRIMARY KEY (`comment_id`)
- INDEX `idx_post_id` (`post_id`)
- INDEX `idx_user_id` (`user_id`)
- INDEX `idx_parent_comment_id` (`parent_comment_id`)
**业务说明**
- 支持二级评论(回复)
- `parent_comment_id` 为 NULL 表示一级评论
---
#### 10.4 v2_community_follows关注关系表
**表说明**:存储用户之间的关注关系。
| 字段名 | 类型 | 是否必填 | 默认值 | 说明 |
|--------|------|---------|--------|------|
| follow_id | BIGINT | 是 | AUTO_INCREMENT | 关注ID主键 |
| follower_id | BIGINT | 是 | - | 关注者ID |
| followee_id | BIGINT | 是 | - | 被关注者ID |
| created_at | TIMESTAMP | 否 | CURRENT_TIMESTAMP | 创建时间 |
**索引**
- PRIMARY KEY (`follow_id`)
- UNIQUE KEY `uk_follower_followee` (`follower_id`, `followee_id`)
- INDEX `idx_follower_id` (`follower_id`)
- INDEX `idx_followee_id` (`followee_id`)
**业务说明**
- 一个用户不能重复关注同一个用户(唯一约束)
---
### 12. 一键打卡相关
#### 12.1 v2_quick_checkin_records一键打卡记录表
**表说明**:存储用户从社区内容一键打卡的记录。
| 字段名 | 类型 | 是否必填 | 默认值 | 说明 |
|--------|------|---------|--------|------|
| quick_checkin_id | BIGINT | 是 | AUTO_INCREMENT | 一键打卡ID主键 |
| user_id | BIGINT | 是 | - | 借鉴者ID |
| source_post_id | BIGINT | 是 | - | 借鉴的社区内容ID |
| source_user_id | BIGINT | 是 | - | 原创者ID |
| dishes_json | TEXT | 否 | NULL | 借鉴的菜品清单可能有修改JSON格式 |
| nutrition_json | TEXT | 否 | NULL | 营养数据JSON格式 |
| is_modified | TINYINT(1) | 否 | 0 | 是否修改了菜品清单0=否1=是 |
| checkin_date | DATE | 是 | - | 打卡日期 |
| meal_type | VARCHAR(20) | 是 | - | 餐次breakfast/lunch/dinner |
| check_in_record_id | INT | 否 | NULL | 生成的打卡记录ID关联eb_user_sign.id当type=3时 |
| article_id | INT | 否 | NULL | 生成的AI视频文章ID关联eb_article.id当type=2时 |
| video_generated | TINYINT(1) | 否 | 0 | 是否生成了AI视频0=否1=是 |
| points_earned | INT | 否 | 0 | 借鉴者获得的积分 |
| points_to_author | INT | 否 | 0 | 原创者获得的积分 |
| created_at | TIMESTAMP | 否 | CURRENT_TIMESTAMP | 创建时间 |
| completed_at | TIMESTAMP | 否 | NULL | 打卡完成时间 |
**索引**
- PRIMARY KEY (`quick_checkin_id`)
- INDEX `idx_user_id` (`user_id`)
- INDEX `idx_source_post_id` (`source_post_id`)
- INDEX `idx_source_user_id` (`source_user_id`)
- INDEX `idx_checkin_date` (`checkin_date`)
- INDEX `idx_article_id` (`article_id`)
**业务说明**
- 用户从社区内容一键打卡时创建记录
- 打卡完成后更新 `check_in_record_id``completed_at`
- 原创者获得积分奖励
- AI视频存储在 `eb_article` 表中type=2通过 `article_id` 关联
---
### 11. AI视频相关
#### 11.1 eb_article文章内容表 - AI视频功能
**表说明**:使用现有 `eb_article`通过扩展字段支持AI视频功能。详细字段说明见 [0.2 eb_article文章内容表 - 扩展字段用于AI视频功能](#02-eb_article文章内容表---扩展字段用于ai视频功能)。
**业务说明**
- AI视频使用 `type=2` 标识
- `status_task` 字段表示视频生成状态0=已创建1=任务完成2=任务失败
- 视频URL存储在 `video_url` 字段
- 视频相关信息存储在扩展字段中
---
## 索引说明
### 索引命名规范
- 主键:`PRIMARY KEY`
- 唯一索引:`uk_` 前缀
- 普通索引:`idx_` 前缀
### 常用查询场景索引
1. **用户相关查询**:所有表都有 `idx_user_id`
2. **时间相关查询**:创建时间、更新时间索引
3. **状态查询**`status` 字段索引
4. **关联查询**:外键字段索引
### 性能优化建议
1. 定期分析慢查询,优化索引
2. 对于大表(如打卡记录),考虑分区
3. JSON字段如需查询考虑使用虚拟列+索引
4. 定期清理归档数据
---
## 附录
### JSON字段格式说明
#### meal_plan_json配餐方案
```json
{
"breakfast": {
"dishes": [
{"name": "牛奶", "amount": 120, "unit": "ml"},
{"name": "鸡蛋", "amount": 1, "unit": "个"}
],
"total_protein": 18.8,
"total_energy": 452
},
"lunch": {...},
"dinner": {...}
}
```
#### ai_recognized_foods_jsonAI识别食物
```json
[
{
"name": "牛奶",
"weight": 120,
"unit": "ml",
"confidence": 0.95
}
]
```
#### ai_comments_jsonAI点评
```json
{
"strengths": ["蛋白质达标", "能量充足"],
"suggestions": ["可以增加蔬菜摄入"],
"next_meal_advice": "午餐建议选择低磷食物"
}
```
---
**文档结束**