354 lines
15 KiB
Markdown
354 lines
15 KiB
Markdown
# 数据库设计文档
|
||
|
||
## 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 │
|
||
└─────────────────┘
|
||
```
|