217 lines
15 KiB
Markdown
217 lines
15 KiB
Markdown
# 整体架构图
|
||
|
||
本章从全局视角阐述系统的整体技术架构,涵盖前端、后端、数据库及基础设施等核心组成部分。
|
||
|
||
## 架构总览
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────────────────┐
|
||
│ Browser (Vue3 + AntDesign) │
|
||
│ Axios HTTP Request / Vite Dev Proxy │
|
||
└──────────────────────────────┬──────────────────────────────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────────────────────────────────────────────────────┐
|
||
│ Nginx (反向代理) │
|
||
│ 静态资源 / SSL 终止 / 负载均衡 / gzip 压缩 │
|
||
└──────────────────────────────┬──────────────────────────────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────────────────────────────────────────────────────┐
|
||
│ Tornado Application │
|
||
│ │
|
||
│ ┌───────────────────────────────────────────────────────────────────┐ │
|
||
│ │ Handler 生命周期 │ │
|
||
│ │ set_default_headers() → prepare() → handler_method() → on_finish()│ │
|
||
│ │ CORS + trace_id JWT 认证 权限+日志+业务逻辑 释放DB会话 │ │
|
||
│ └───────────────────────────────┬───────────────────────────────────┘ │
|
||
│ ▼ │
|
||
│ ┌───────────────────────────────────────────────────────────────────┐ │
|
||
│ │ Service Layer (业务逻辑层) │ │
|
||
│ │ BaseService / 自定义 Service │ │
|
||
│ │ 唯一性校验 · 字段组装 · 序列化 · 文件处理 │ │
|
||
│ └───────────────────────────────┬───────────────────────────────────┘ │
|
||
│ ▼ │
|
||
│ ┌───────────────────────────────────────────────────────────────────┐ │
|
||
│ │ Repository Layer (数据访问层) │ │
|
||
│ │ BaseRepository │ │
|
||
│ │ CRUD · 软删除 · 分页 · 等值查询 · 原始条件查询 │ │
|
||
│ └───────────────────────────────┬───────────────────────────────────┘ │
|
||
│ ▼ │
|
||
│ ┌─────────────────────┐ ┌──────────────────────────────────────────┐ │
|
||
│ │ SQLAlchemy 2.0 │ │ Redis (同步客户端) │ │
|
||
│ │ ORM → SQL 生成 │ │ Token 黑名单 · 登录锁 · 字典缓存 · 权限缓存│ │
|
||
│ └──────────┬──────────┘ └──────────────────────────────────────────┘ │
|
||
└─────────────┼───────────────────────────────────────────────────────────┘
|
||
▼
|
||
┌─────────────────────────────────────────────────────────────────────────┐
|
||
│ Database (MySQL / PostgreSQL / SQL Server / SQLite / Oracle)│
|
||
│ 表前缀: tornado_ · 软删除: is_delete │
|
||
└─────────────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
## 架构特征
|
||
|
||
### 1. 前后端分离
|
||
|
||
前端 Vue3 应用通过 HTTP API 调用后端 Tornado 服务,两者独立开发、独立部署。前端开发阶段通过 Vite 的 `proxy` 配置将 `/api` 请求代理到后端 `http://127.0.0.1:8041`,生产环境由 Nginx 统一反向代理。
|
||
|
||
### 2. 分层架构
|
||
|
||
后端严格分为四层,每层职责单一、依赖单向:
|
||
|
||
| 层次 | 目录 | 职责 |
|
||
|:---:|:---:|:---|
|
||
| HTTP 层 | `modules/{module}/handlers.py` | 路由定义、权限装饰器、操作日志、响应返回 |
|
||
| 业务层 | `modules/{module}/service.py` | 业务逻辑、校验规则、序列化加工 |
|
||
| 数据层 | `modules/{module}/repository.py` | 数据库 CRUD、查询条件组装 |
|
||
| 模型层 | `modules/{module}/models.py` | 表结构定义、字段映射 |
|
||
|
||
### 3. 模板方法模式
|
||
|
||
通过 `BaseRepository` 和 `BaseService` 基类,将通用 CRUD 流程固化为模板方法。子类只需声明差异点(过滤字段、排序规则、唯一性校验等),即可获得完整的增删改查能力。
|
||
|
||
### 4. Handler 生命周期
|
||
|
||
Tornado 通过 Handler 生命周期方法实现横切关注点:
|
||
|
||
```python
|
||
# src/core/base_handler.py
|
||
class BaseHandler(tornado.web.RequestHandler):
|
||
def set_default_headers(self):
|
||
"""① 设置 CORS 头 + trace_id"""
|
||
cros_required(self)
|
||
apply_trace_id(self)
|
||
|
||
@login_required
|
||
def prepare(self):
|
||
"""② JWT 认证(白名单 URL 跳过)"""
|
||
pass
|
||
|
||
def on_finish(self):
|
||
"""④ 请求结束后释放数据库会话"""
|
||
db.close()
|
||
|
||
def write_error(self, status_code, **kwargs):
|
||
"""⑤ 异常统一响应"""
|
||
...
|
||
```
|
||
|
||
Handler 方法中通过装饰器实现权限/演示模式/操作日志:
|
||
|
||
```python
|
||
class PositionAddHandler(BaseHandler):
|
||
@permission_required("sys:position:add") # RBAC 权限校验
|
||
@check_demo # 演示模式拦截
|
||
@operation_log("岗位管理", "添加") # 操作日志记录
|
||
async def post(self):
|
||
return await position_service.add(self)
|
||
```
|
||
|
||
### 5. 全局异常处理
|
||
|
||
`BaseHandler.write_error()` 统一捕获异常并返回标准响应:
|
||
|
||
| 异常类型 | 触发场景 | 响应 |
|
||
|:---|:---|:---|
|
||
| `AuthError` | JWT 过期 / 未登录 | `{"code": 401, "msg": "登录过期"}` |
|
||
| `PermissionDeniedError` | 权限不足 | `{"code": 403, "msg": "权限不足"}` |
|
||
| `BusinessError` | 业务逻辑错误 | `{"code": 1, "msg": "..."}` |
|
||
| `ValidationError` | Pydantic 校验失败 | `{"code": 1, "msg": "field: message"}` |
|
||
| `NotFoundError` | 记录不存在 | `{"code": 404, "msg": "记录不存在"}` |
|
||
| `Exception` | 未捕获异常 | `{"code": 500, "msg": "服务器内部错误"}` |
|
||
|
||
### 6. 统一响应格式
|
||
|
||
所有 API 端点返回统一的 JSON 结构:
|
||
|
||
```json
|
||
{
|
||
"code": 0,
|
||
"data": {},
|
||
"msg": "操作成功",
|
||
"ok": true
|
||
}
|
||
```
|
||
|
||
成功响应 `code=0`,失败响应 `code=1`(或其他业务码),前端无需针对不同接口做差异化解析。
|
||
|
||
### 7. 软删除策略
|
||
|
||
所有业务表通过 `is_delete` 字段实现软删除(0=正常,1=已删除)。`BaseRepository` 的等值查询方法自动追加 `is_delete=0` 过滤,业务代码无需关心已删除数据。
|
||
|
||
### 8. 事务管理
|
||
|
||
数据库事务由 Repository 层的 `create()` / `update()` / `batch_delete()` 方法内部 `db.commit()` 管理。Service 层的 `try/finally` 块确保 `repo.close()` 释放会话。`BaseHandler.on_finish()` 兜底关闭会话,避免长连接泄漏。
|
||
|
||
### 9. 多数据库驱动
|
||
|
||
通过 `DB_DRIVER` 环境变量切换数据库驱动(MySQL / PostgreSQL / SQL Server / SQLite / Oracle),SQLAlchemy 的方言层屏蔽了底层差异,业务代码无需修改。
|
||
|
||
### 10. 应用启动流程
|
||
|
||
```python
|
||
# app.py(入口)→ bootstrap.py(启动引导)→ src/app.py(应用工厂)
|
||
# 启动流程:
|
||
# 1. bootstrap.main() 解析 --port 参数
|
||
# 2. create_app() 构建 Application(路由、模板、静态目录)
|
||
# 3. register_extensions() 初始化扩展(SQLAlchemy、Redis)
|
||
# 4. HTTPServer.listen(port) 开始监听
|
||
# 5. init_scheduler() 启动定时任务调度器
|
||
# 6. 注册 SIGINT/SIGTERM 信号实现优雅关闭
|
||
# 7. ioloop.start() 启动事件循环
|
||
```
|
||
|
||
## 技术分层图
|
||
|
||
```
|
||
┌──────────────────────────────────────────────────────────────┐
|
||
│ Frontend (Vue3) │
|
||
│ AntDesign · Pinia · Vue Router · Axios │
|
||
└──────────────────────────┬───────────────────────────────────┘
|
||
│ HTTP / JSON
|
||
┌──────────────────────────┴───────────────────────────────────┐
|
||
│ Tornado Application │
|
||
│ │
|
||
│ ┌─────────────┐ ┌─────────────┐ ┌──────────────────────┐ │
|
||
│ │ Handler │ │ Router │ │ Exception Handler │ │
|
||
│ │ ───────── │ │ ───────── │ │ ───────────────── │ │
|
||
│ │ CORS │ │ auth │ │ BaseAppError │ │
|
||
│ │ trace_id │ │ v1 (login │ │ write_error() │ │
|
||
│ │ login_ │ │ required) │ │ 统一 {code,data,msg} │ │
|
||
│ │ required │ │ │ │ │ │
|
||
│ └─────────────┘ └─────────────┘ └──────────────────────┘ │
|
||
│ │
|
||
│ ┌──────────────────────────────────────────────────────────┐ │
|
||
│ │ Handlers (modules/{module}/handlers.py) │ │
|
||
│ │ @permission_required · @check_demo · @operation_log │ │
|
||
│ └──────────────────────────────────────────────────────────┘ │
|
||
│ │ │
|
||
│ ┌──────────────────────────────────────────────────────────┐ │
|
||
│ │ Services (modules/{module}/service.py) │ │
|
||
│ │ BaseService · 自定义 Service │ │
|
||
│ └──────────────────────────────────────────────────────────┘ │
|
||
│ │ │
|
||
│ ┌──────────────────────────────────────────────────────────┐ │
|
||
│ │ Repositories (modules/{module}/repository.py) │ │
|
||
│ │ BaseRepository · 自定义 Repository │ │
|
||
│ └──────────────────────────────────────────────────────────┘ │
|
||
│ │ │
|
||
│ ┌──────────────────────────────────────────────────────────┐ │
|
||
│ │ Models (modules/{module}/models.py) │ │
|
||
│ │ BaseModel → SQLAlchemy ORM │ │
|
||
│ └──────────────────────────────────────────────────────────┘ │
|
||
└──────────────────────────┬───────────────────────────────────┘
|
||
│
|
||
┌────────────┴────────────┐
|
||
▼ ▼
|
||
┌────────────┐ ┌─────────────┐
|
||
│ Database │ │ Redis │
|
||
│ (MySQL等) │ │ (同步客户端) │
|
||
└────────────┘ └─────────────┘
|
||
```
|
||
|
||
## 总结
|
||
|
||
系统采用经典的前后端分离 + 分层架构设计,通过 Handler 生命周期方法和装饰器实现横切关注点(认证、权限、日志),通过基类模板方法消除重复 CRUD 代码,通过 Pydantic 实现请求参数的声明式校验。整体架构在保持简洁的同时,具备良好的可扩展性和可维护性。
|