This commit is contained in:
Ubuntu
2026-07-03 16:58:28 +08:00
commit 32b43f85bd
6240 changed files with 1987678 additions and 0 deletions
@@ -0,0 +1,353 @@
# 数据库设计文档
## 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 │
└─────────────────┘
```