# 数据库设计文档 ## 1. 数据库概览 - **类型**: SQLite - **文件**: `backend/cms.db` - **ORM**: SQLAlchemy 2.0 ## 2. 数据表设计 ### 2.1 admins - 管理员表 | 字段 | 类型 | 约束 | 说明 | |------|------|------|------| | id | INTEGER | PK, AI | 主键 | | username | VARCHAR(50) | UNIQUE, NOT NULL | 用户名 | | password_hash | VARCHAR(255) | NOT NULL | 密码哈希 (bcrypt) | | created_at | DATETIME | DEFAULT NOW | 创建时间 | | updated_at | DATETIME | DEFAULT NOW | 更新时间 | ```sql CREATE TABLE admins ( id INTEGER PRIMARY KEY AUTOINCREMENT, username VARCHAR(50) UNIQUE NOT NULL, password_hash VARCHAR(255) NOT NULL, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ); ``` ### 2.2 home_modules - 首页模块表 首页模块化设计的核心表,每个模块代表首页的一个区块。 | 字段 | 类型 | 约束 | 说明 | |------|------|------|------| | id | INTEGER | PK, AI | 主键 | | name | VARCHAR(50) | NOT NULL | 模块名称(显示用) | | code | VARCHAR(30) | UNIQUE, NOT NULL | 模块标识(程序用) | | type | VARCHAR(20) | NOT NULL | 模块类型 | | sort_order | INTEGER | DEFAULT 0 | 排序权重(越小越靠前) | | is_enabled | BOOLEAN | DEFAULT 1 | 是否启用 | | is_fixed | BOOLEAN | DEFAULT 0 | 是否固定(不可删除) | | title | VARCHAR(100) | NULL | 模块标题 | | subtitle | VARCHAR(200) | NULL | 副标题 | | content | TEXT | NULL | 内容数据(JSON格式) | | style_config | TEXT | NULL | 样式配置(JSON格式) | | created_at | DATETIME | DEFAULT NOW | 创建时间 | | updated_at | DATETIME | DEFAULT NOW | 更新时间 | ```sql CREATE TABLE home_modules ( id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(50) NOT NULL, code VARCHAR(30) UNIQUE NOT NULL, type VARCHAR(20) NOT NULL, sort_order INTEGER DEFAULT 0, is_enabled BOOLEAN DEFAULT 1, is_fixed BOOLEAN DEFAULT 0, title VARCHAR(100), subtitle VARCHAR(200), content TEXT, style_config TEXT, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ); ``` #### 模块类型 (type) | 类型 | 说明 | 内容格式 | |------|------|----------| | banner | 轮播图 | `{"slides": [{"image": "url", "link": "", "title": ""}]}` | | features | 产品优势 | `{"items": [{"icon": "", "title": "", "desc": ""}]}` | | news | 新闻动态 | `{"count": 4, "category": "news"}` | | partners | 合作伙伴 | `{"logos": [{"name": "", "image": "", "link": ""}]}` | | links | 友情链接 | `{"links": [{"name": "", "url": ""}]}` | | downloads | APP下载 | `{"apps": [{"name": "", "icon": "", "qr_code": "", "url": ""}]}` | | contact | 联系方式 | `{"phone": "", "email": "", "address": "", "map_url": ""}` | | faq | 常见问题 | `{"items": [{"q": "", "a": ""}]}` | | products | 产品介绍 | `{"count": 3, "ids": [1,2,3]}` | | html | 自定义HTML | `{"html": ""}` | #### 样式配置 (style_config) 格式 ```json { "backgroundColor": "#FEF9E7", "textColor": "#000000", "paddingTop": "60px", "paddingBottom": "60px", "layout": "grid", "maxWidth": "1200px" } ``` ### 2.3 nav_menus - 导航菜单表 | 字段 | 类型 | 约束 | 说明 | |------|------|------|------| | id | INTEGER | PK, AI | 主键 | | name | VARCHAR(50) | NOT NULL | 菜单名称 | | link | VARCHAR(255) | NOT NULL | 跳转链接 | | sort_order | INTEGER | DEFAULT 0 | 排序权重 | | is_enabled | BOOLEAN | DEFAULT 1 | 是否启用 | | is_external | BOOLEAN | DEFAULT 0 | 是否外部链接 | | parent_id | INTEGER | FK -> nav_menus | 父菜单ID(用于二级菜单) | | created_at | DATETIME | DEFAULT NOW | 创建时间 | | updated_at | DATETIME | DEFAULT NOW | 更新时间 | ```sql CREATE TABLE nav_menus ( id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(50) NOT NULL, link VARCHAR(255) NOT NULL, sort_order INTEGER DEFAULT 0, is_enabled BOOLEAN DEFAULT 1, is_external BOOLEAN DEFAULT 0, parent_id INTEGER, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (parent_id) REFERENCES nav_menus(id) ); ``` ### 2.4 settings - 系统设置表 | 字段 | 类型 | 约束 | 说明 | |------|------|------|------| | id | INTEGER | PK, AI | 主键 | | key | VARCHAR(50) | UNIQUE, NOT NULL | 配置键 | | value | TEXT | NULL | 配置值 | | group | VARCHAR(20) | DEFAULT 'general' | 分组 | | description | VARCHAR(200) | NULL | 说明 | | created_at | DATETIME | DEFAULT NOW | 创建时间 | | updated_at | DATETIME | DEFAULT NOW | 更新时间 | ### 2.5 images - 图片资源表 | 字段 | 类型 | 约束 | 说明 | |------|------|------|------| | id | INTEGER | PK, AI | 主键 | | filename | VARCHAR(255) | NOT NULL | 存储文件名(唯一标识) | | original_name | VARCHAR(255) | NULL | 原始文件名 | | file_path | VARCHAR(500) | NOT NULL | 原图访问路径(如 `/storage/admin/images/xxx.jpg`) | | thumb_path | VARCHAR(500) | NULL | 缩略图访问路径(如 `/storage/admin/images/thumbnails/xxx.jpg`) | | description | VARCHAR(500) | NULL | 图片描述 | | file_size | INTEGER | NULL | 文件大小(字节) | | width | INTEGER | NULL | 图片宽度 | | height | INTEGER | NULL | 图片高度 | | module | VARCHAR(20) | DEFAULT 'news' | 所属模块(news/product/page) | | created_at | DATETIME | DEFAULT NOW | 创建时间 | **存储规则:** - 文件实际存储在 `storage/admin/images/` 目录下 - 缩略图存储在 `storage/admin/images/thumbnails/` 目录下 - 缩略图与原图同名,但扩展名统一为 `.jpg` - 文件名格式:`YYYYMMDD_HHMMSS_xxxxxxxx.ext` ```sql CREATE TABLE images ( id INTEGER PRIMARY KEY AUTOINCREMENT, filename VARCHAR(255) NOT NULL, original_name VARCHAR(255), file_path VARCHAR(500) NOT NULL, thumb_path VARCHAR(500), description VARCHAR(500), file_size INTEGER, width INTEGER, height INTEGER, module VARCHAR(20) DEFAULT 'news', created_at DATETIME DEFAULT CURRENT_TIMESTAMP ); ``` ### 2.6 news_categories - 新闻栏目表 | 字段 | 类型 | 约束 | 说明 | |------|------|------|------| | id | INTEGER | PK, AI | 主键 | | name | VARCHAR(50) | NOT NULL | 栏目名称 | | slug | VARCHAR(50) | UNIQUE, NOT NULL | 栏目标识(URL用) | | description | VARCHAR(200) | NULL | 栏目描述 | | sort_order | INTEGER | DEFAULT 0 | 排序权重 | | is_enabled | BOOLEAN | DEFAULT 1 | 是否启用 | | created_at | DATETIME | DEFAULT NOW | 创建时间 | | updated_at | DATETIME | DEFAULT NOW | 更新时间 | ```sql CREATE TABLE news_categories ( id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(50) NOT NULL, slug VARCHAR(50) UNIQUE NOT NULL, description VARCHAR(200), sort_order INTEGER DEFAULT 0, is_enabled BOOLEAN DEFAULT 1, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ); ``` ### 2.7 news_posts - 新闻资讯表 | 字段 | 类型 | 约束 | 说明 | |------|------|------|------| | id | INTEGER | PK, AI | 主键 | | title | VARCHAR(200) | NOT NULL | 标题 | | slug | VARCHAR(200) | UNIQUE, NOT NULL | 文章标识(URL用) | | content | TEXT | NOT NULL | 内容(Markdown/HTML) | | content_type | VARCHAR(20) | DEFAULT 'markdown' | 内容类型(markdown/html) | | summary | VARCHAR(500) | NULL | 摘要 | | cover_image | VARCHAR(500) | NULL | 封面图路径 | | category_id | INTEGER | FK -> news_categories | 栏目ID | | is_draft | BOOLEAN | DEFAULT 1 | 是否为草稿 | | is_published | BOOLEAN | DEFAULT 0 | 是否已发布 | | view_count | INTEGER | DEFAULT 0 | 浏览次数 | | created_at | DATETIME | DEFAULT NOW | 创建时间 | | updated_at | DATETIME | DEFAULT NOW | 更新时间 | ```sql CREATE TABLE news_posts ( id INTEGER PRIMARY KEY AUTOINCREMENT, title VARCHAR(200) NOT NULL, slug VARCHAR(200) UNIQUE NOT NULL, content TEXT NOT NULL, content_type VARCHAR(20) DEFAULT 'markdown', summary VARCHAR(500), cover_image VARCHAR(500), category_id INTEGER, is_draft BOOLEAN DEFAULT 1, is_published BOOLEAN DEFAULT 0, view_count INTEGER DEFAULT 0, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (category_id) REFERENCES news_categories(id) ); ``` ```sql CREATE TABLE settings ( id INTEGER PRIMARY KEY AUTOINCREMENT, key VARCHAR(50) UNIQUE NOT NULL, value TEXT, group VARCHAR(20) DEFAULT 'general', description VARCHAR(200), created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ); ``` #### 预设配置项 | key | 说明 | 默认值 | |-----|------|--------| | site_name | 网站名称 | 飞点健康 | | site_logo | Logo URL | /logo.png | | site_favicon | 图标 URL | /favicon.ico | | company_name | 公司名称 | 深圳飞点健康科技有限公司 | | company_address | 公司地址 | - | | company_phone | 联系电话 | - | | company_email | 邮箱 | - | | icp | 备案号 | - | | seo_title | SEO标题 | 飞点健康官网-尿大夫-手机就能做尿检 | | seo_description | SEO描述 | ... | | seo_keywords | SEO关键词 | 尿检,体检,糖尿病,肾病... | | copyright | 版权信息 | © 2024 飞点健康 版权所有 | ## 3. 初始化数据 ### 3.1 默认管理员 ```sql INSERT INTO admins (username, password_hash) VALUES ('admin', '$2b$12$...'); -- 密码: admin123 ``` ### 3.2 默认首页模块 ```sql INSERT INTO home_modules (name, code, type, sort_order, is_enabled, is_fixed, title, content, style_config) VALUES ('轮播图', 'banner', 'banner', 1, 1, 1, '', '{"slides": []}', '{"backgroundColor": "#ffffff"}'), ('产品优势', 'features', 'features', 2, 1, 0, '为什么选择我们', '{"items": []}', '{"backgroundColor": "#FEF9E7"}'), ('新闻动态', 'news', 'news', 3, 1, 0, '新闻动态', '{"count": 4}', '{"backgroundColor": "#ffffff"}'), ('合作伙伴', 'partners', 'partners', 4, 1, 0, '合作伙伴', '{"logos": []}', '{"backgroundColor": "#FEF9E7"}'), ('APP下载', 'downloads', 'downloads', 5, 1, 0, '下载我们的APP', '{"apps": []}', '{"backgroundColor": "#ffffff"}'), ('联系我们', 'contact', 'contact', 6, 1, 0, '联系我们', '{"phone": "", "email": "", "address": ""}', '{"backgroundColor": "#FEF9E7"}'); ``` ### 3.3 默认导航菜单 ```sql INSERT INTO nav_menus (name, link, sort_order, is_enabled) VALUES ('首页', '/', 1, 1), ('产品介绍', '/product', 2, 1), ('新闻动态', '/news', 3, 1), ('关于我们', '/about', 4, 1), ('联系我们', '/contact', 5, 1); ``` ## 4. ER 图 ``` ┌─────────────┐ ┌─────────────────┐ ┌─────────────┐ │ admins │ │ home_modules │ │ nav_menus │ ├─────────────┤ ├─────────────────┤ ├─────────────┤ │ id (PK) │ │ id (PK) │ │ id (PK) │ │ username │ │ name │ │ name │ │ password_...│ │ code (UQ) │ │ link │ │ created_at │ │ type │ │ sort_order │ │ updated_at │ │ sort_order │◄──────┤ is_enabled │ └─────────────┘ │ is_enabled │ │ parent_id │ │ is_fixed │ │ created_at │ │ title │ │ updated_at │ │ subtitle │ └─────────────┘ │ content (JSON) │ │ style_config │ ┌─────────────┐ │ created_at │ │ images │ │ updated_at │ ├─────────────┤ └─────────────────┘ │ id (PK) │ │ │ filename │ │ │ file_path │ ┌─────────────────┐ │ thumb_path │ │ settings │ │ module │ ├─────────────────┤ │ file_size │ │ id (PK) │ │ created_at │ │ key (UQ) │ └─────────────┘ │ value │ │ group │ ┌─────────────────┐ │ description │ │ news_categories │ │ created_at │ ├─────────────────┤ │ updated_at │ │ id (PK) │ └─────────────────┘ │ name │ │ slug (UQ) │ │ sort_order │ │ is_enabled │ └─────────────────┘ │ │ ┌─────────────────┐ │ news_posts │ ├─────────────────┤ │ id (PK) │ │ title │ │ slug (UQ) │ │ content │ │ content_type │ │ cover_image │ │ category_id(FK) │ │ is_draft │ │ is_published │ │ view_count │ └─────────────────┘ ```