# 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 | 关联的社区内容ID(v2_community_posts.post_id,如果是从社区内容生成) | | check_in_record_id | INT | 否 | NULL | 关联的打卡记录ID(eb_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_conversations(AI营养师对话表) **表说明**:存储用户与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_messages(AI营养师消息表) **表说明**:存储对话中的每条消息。 | 字段名 | 类型 | 是否必填 | 默认值 | 说明 | |--------|------|---------|--------|------| | 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 | 关联的打卡记录ID(eb_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 | 父评论ID,NULL为一级评论 | | 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_json(AI识别食物) ```json [ { "name": "牛奶", "weight": 120, "unit": "ml", "confidence": 0.95 } ] ``` #### ai_comments_json(AI点评) ```json { "strengths": ["蛋白质达标", "能量充足"], "suggestions": ["可以增加蔬菜摄入"], "next_meal_advice": "午餐建议选择低磷食物" } ``` --- **文档结束**