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

826 lines
33 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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": "午餐建议选择低磷食物"
}
```
---
**文档结束**