329 lines
19 KiB
Markdown
329 lines
19 KiB
Markdown
# 4.1 整体架构概览
|
||
|
||
:::tip 概述
|
||
本章从全局视角阐述系统的整体技术架构,涵盖前端、后端、数据库及基础设施等核心组成部分,旨在帮助开发者快速建立对系统全貌的清晰认知。
|
||
:::
|
||
|
||
## 架构总览
|
||
|
||
```text
|
||
┌─────────────────────────────────────────────────────────────────┐
|
||
│ 浏览器(Vue3 + ElementPlus) │
|
||
│ Axios HTTP 请求 / Vite 开发代理 │
|
||
└──────────────────────────────┬──────────────────────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────────────────────────────────────────────┐
|
||
│ Nginx(反向代理) │
|
||
│ 静态资源托管 / SSL 终止 / 负载均衡 / gzip 压缩 │
|
||
└──────────────────────────────┬──────────────────────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────────────────────────────────────────────┐
|
||
│ ThinkPHP 6.1 Application │
|
||
│ │
|
||
│ ┌───────────────────────────────────────────────────────────┐ │
|
||
│ │ 中间件链(按顺序执行) │ │
|
||
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌──────┐ ┌───────┐ │ │
|
||
│ │ │ CORS │→│ Auth │→│ Tenant │→│ Demo │→│ Log │ │ │
|
||
│ │ │ 跨域处理 │ │JWT+权限 │ │ 租户上下文│ │演示拦截│ │操作日志│ │ │
|
||
│ │ └─────────┘ └─────────┘ └─────────┘ └──────┘ └───────┘ │ │
|
||
│ └───────────────────────────────┬───────────────────────────┘ │
|
||
│ ▼ │
|
||
│ ┌───────────────────────────────────────────────────────────┐ │
|
||
│ │ 控制器层(Controller) │ │
|
||
│ │ BaseController → 统一响应 · 参数获取 · 通用 CRUD │ │
|
||
│ │ #[Permission] 权限注解 · #[Log] 日志注解 │ │
|
||
│ └───────────────────────────────┬───────────────────────────┘ │
|
||
│ ▼ │
|
||
│ ┌───────────────────────────────────────────────────────────┐ │
|
||
│ │ 逻辑层(Logic) │ │
|
||
│ │ BaseLogic / BaseTenantLogic │ │
|
||
│ │ 属性配置 · 生命周期钩子 · 文件处理 · 枚举翻译 │ │
|
||
│ │ 唯一性校验 · 数据权限 · 租户隔离 · 事务管理 │ │
|
||
│ └───────────────────────────────┬───────────────────────────┘ │
|
||
│ ▼ │
|
||
│ ┌───────────────────────────────────────────────────────────┐ │
|
||
│ │ 模型层(Model) │ │
|
||
│ │ BaseModel │ │
|
||
│ │ 软删除(is_delete)· 审计字段自动写入 │ │
|
||
│ └───────────────────────────────┬───────────────────────────┘ │
|
||
│ ▼ │
|
||
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────────┐ │
|
||
│ │ MySQL │ │ Redis │ │ 文件系统 │ │
|
||
│ │ 数据库 │ │ 缓存 │ │ uploads/ │ │
|
||
│ └─────────────┘ └─────────────┘ └─────────────────────────┘ │
|
||
└─────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
## 架构特征
|
||
|
||
:::tip 核心设计原则
|
||
遵循以下架构设计原则,确保系统在长期演进中保持高质量和可维护性:
|
||
:::
|
||
|
||
### 1. 前后端分离
|
||
|
||
前端 Vue3 应用通过 HTTP API 调用后端 ThinkPHP 服务,两者独立开发、独立部署。前端开发阶段通过 Vite 的 `proxy` 配置将 `/api` 请求代理到后端 `http://localhost:8000`,生产环境由 Nginx 统一反向代理。
|
||
|
||
### 2. 分层架构
|
||
|
||
后端严格分为三层,每层职责单一、依赖单向:
|
||
|
||
| 层次 | 目录 | 职责 |
|
||
|------|------|------|
|
||
| 控制器层 | `app/controller/` | 路由入口、权限注解、参数获取、响应返回 |
|
||
| 逻辑层 | `app/logic/` | 业务逻辑、属性配置、生命周期钩子、横切处理 |
|
||
| 模型层 | `app/model/` | 数据库表映射、软删除、审计字段 |
|
||
|
||
### 3. 模板方法模式(声明式 CRUD)
|
||
|
||
通过 `BaseLogic` 基类,将通用 CRUD 流程固化为模板方法。子类只需声明差异点(过滤字段、排序规则、唯一性校验等),即可获得完整的增删改查能力,极大减少重复代码。
|
||
|
||
```php
|
||
// 子类只需声明差异点,即可获得完整 CRUD 能力
|
||
class ExampleLogic extends BaseLogic
|
||
{
|
||
/**
|
||
* 关联的模型类
|
||
*
|
||
* @var string
|
||
*/
|
||
protected string $modelClass = Example::class;
|
||
|
||
/**
|
||
* LIKE 模糊匹配字段
|
||
*
|
||
* @var array
|
||
*/
|
||
protected array $pageLikeFields = ['name'];
|
||
|
||
/**
|
||
* 精确匹配字段
|
||
*
|
||
* @var array
|
||
*/
|
||
protected array $pageEqFields = ['status'];
|
||
|
||
/**
|
||
* 默认排序规则
|
||
*
|
||
* @var array
|
||
*/
|
||
protected array $pageOrderBy = ['field'=>'sort', 'type'=>'asc'];
|
||
|
||
/**
|
||
* 唯一性校验字段
|
||
*
|
||
* @var array
|
||
*/
|
||
protected array $uniqueFields = ['name'];
|
||
|
||
/**
|
||
* 枚举显示名映射
|
||
*
|
||
* @var array
|
||
*/
|
||
protected array $serializeMaps = ['status'=>'example_status'];
|
||
}
|
||
```
|
||
|
||
### 4. 中间件链式处理
|
||
|
||
请求处理采用中间件链,按注册顺序依次执行:
|
||
|
||
```text
|
||
请求进入 → CORS → Auth → Tenant → Demo → Log → 控制器
|
||
│
|
||
响应返回 ← CORS ← Auth ← Tenant ← Demo ← Log ←───┘
|
||
```
|
||
|
||
| 中间件 | 职责 | 配置方式 |
|
||
|--------|------|----------|
|
||
| CorsMiddleware | 跨域处理 | 全局,config/cors.php |
|
||
| AuthMiddleware | JWT 认证 + RBAC 鉴权 | 路由级,config/middleware.php |
|
||
| TenantMiddleware | 租户上下文注入 | 路由级 |
|
||
| DemoMiddleware | 演示环境拦截 | 路由级,.env [APP] DEMO |
|
||
| LogMiddleware | 操作日志记录 | 路由级,config/middleware.php |
|
||
|
||
### 5. 全局异常处理
|
||
|
||
`ExceptionHandle` 统一捕获所有异常并返回标准 JSON 响应:
|
||
|
||
| 来源 | 异常类型 | 触发场景 | 响应 |
|
||
|------|---------|---------|------|
|
||
| ExceptionHandle | ValidateException | 参数验证失败 | `{code:1, msg:"参数验证失败", data:{错误明细}}` |
|
||
| ExceptionHandle | ModelNotFoundException | 数据不存在 | `{code:1, msg:"数据不存在"}` |
|
||
| ExceptionHandle | HttpException | HTTP 错误 | `{code:1, msg:"请求错误"}` |
|
||
| ExceptionHandle | Exception | 未捕获异常 | `{code:1, msg:"操作失败"}` |
|
||
| AuthMiddleware | — | JWT 缺失/过期/无效、token 类型错误 | `{code:401, msg:"未提供认证令牌"}` 等 |
|
||
| PermissionMiddleware | — | 无接口权限 | `{code:403, msg:"没有权限"}` |
|
||
|
||
### 6. 统一响应格式
|
||
|
||
所有 API 端点返回统一的 JSON 结构:
|
||
|
||
```json
|
||
{
|
||
"code": 0,
|
||
"ok": true,
|
||
"msg": "操作成功",
|
||
"data": {}
|
||
}
|
||
```
|
||
|
||
成功响应 `code=0`,失败响应 `code=1`(ExceptionHandle 统一处理)。`code=401`(AuthMiddleware 直接返回)和 `code=403`(PermissionMiddleware 直接返回)由中间件在请求到达控制器之前拦截,不经过 ExceptionHandle。前端无需针对不同接口做差异化解析。
|
||
|
||
### 7. 软删除策略
|
||
|
||
:::warning 禁止物理删除
|
||
所有业务数据必须使用软删除(`is_delete` 字段),禁止物理删除。物理删除仅用于日志清理等特殊场景。
|
||
:::
|
||
|
||
所有业务表通过 `is_delete` 字段实现软删除(0=正常,1=已删除)。`BaseModel` 的全局查询范围自动追加 `is_delete=0` 过滤,业务代码无需关心已删除数据。
|
||
|
||
```php
|
||
// 自动过滤已删除数据
|
||
$users = User::select(); // WHERE is_delete = 0
|
||
|
||
// 查询已删除数据
|
||
$deleted = User::withoutGlobalScope(['soft_delete'])->select();
|
||
|
||
// 软删除
|
||
$user->softDelete(); // UPDATE SET is_delete = 1
|
||
|
||
// 批量软删除
|
||
User::batchSoftDelete([1, 2, 3]);
|
||
```
|
||
|
||
### 8. 审计字段自动写入
|
||
|
||
通过 BaseModel 的模型事件自动填充审计字段:
|
||
|
||
```php
|
||
// 创建前自动填充
|
||
public static function onBeforeInsert($model): void
|
||
{
|
||
$model->create_user = request()->userInfo->username ?? '';
|
||
$model->create_time = date('Y-m-d H:i:s');
|
||
}
|
||
|
||
// 更新前自动填充
|
||
public static function onBeforeUpdate($model): void
|
||
{
|
||
$model->update_user = request()->userInfo->username ?? '';
|
||
$model->update_time = date('Y-m-d H:i:s');
|
||
}
|
||
```
|
||
|
||
### 9. 多数据库支持
|
||
|
||
通过 `DATABASE.TYPE` 环境变量切换数据库驱动(MySQL / PostgreSQL / SQL Server / Oracle / SQLite),ThinkPHP ORM 的方言层屏蔽了底层差异,业务代码无需修改。
|
||
|
||
### 10. 两级缓存架构
|
||
|
||
```text
|
||
请求级缓存(static 变量) ← 同一请求内不重复查库
|
||
│ 未命中
|
||
▼
|
||
持久缓存(file / Redis) ← 跨请求复用,1小时过期
|
||
│ 未命中
|
||
▼
|
||
数据库查询 ← 查询后写入两级缓存
|
||
```
|
||
|
||
DictService 和 ParamService 均采用此架构,大幅减少数据库查询。
|
||
|
||
## 技术分层图
|
||
|
||
```text
|
||
┌──────────────────────────────────────────────────────────────┐
|
||
│ 前端(Vue3 + ElementPlus) │
|
||
│ Pinia · Vue Router · Axios · TinyMce · ECharts │
|
||
└──────────────────────────┬───────────────────────────────────┘
|
||
│ HTTP / JSON
|
||
┌──────────────────────────┴───────────────────────────────────┐
|
||
│ ThinkPHP 6.1 Application │
|
||
│ │
|
||
│ ┌─────────────┐ ┌─────────────┐ ┌──────────────────────┐ │
|
||
│ │ 中间件 │ │ 路由 │ │ 异常处理器 │ │
|
||
│ │ ───────── │ │ ───────── │ │ ───────────────── │ │
|
||
│ │ CORS │ │ route/ │ │ ValidateException │ │
|
||
│ │ Auth │ │ app.php │ │ ModelNotFound │ │
|
||
│ │ Tenant │ │ │ │ RuntimeException │ │
|
||
│ │ Demo │ │ │ │ HttpException │ │
|
||
│ │ Log │ │ │ │ Exception │ │
|
||
│ └─────────────┘ └─────────────┘ └──────────────────────┘ │
|
||
│ │
|
||
│ ┌────────────────────────────────────────────────────────┐ │
|
||
│ │ 控制器层(app/controller/) │ │
|
||
│ │ BaseController · #[Permission] · #[Log] │ │
|
||
│ └────────────────────────────────────────────────────────┘ │
|
||
│ │ │
|
||
│ ┌────────────────────────────────────────────────────────┐ │
|
||
│ │ 逻辑层(app/logic/) │ │
|
||
│ │ BaseLogic / BaseTenantLogic │ │
|
||
│ │ 属性配置 · 钩子 · 文件处理 · 枚举翻译 · 数据权限 │ │
|
||
│ └────────────────────────────────────────────────────────┘ │
|
||
│ │ │
|
||
│ ┌────────────────────────────────────────────────────────┐ │
|
||
│ │ 模型层(app/model/) │ │
|
||
│ │ BaseModel · 软删除 · 审计字段 │ │
|
||
│ └────────────────────────────────────────────────────────┘ │
|
||
│ │
|
||
│ ┌──────────────────┐ ┌─────────────┐ ┌──────────────────────┐ │
|
||
│ │ 服务层 │ │ 验证器 │ │ 注解 │ │
|
||
│ │ ────────────── │ │ ───────── │ │ ───────────────── │ │
|
||
│ │ JwtService │ │ Validate │ │ #[Log] │ │
|
||
│ │ PasswordService │ │ │ │ #[Permission] │ │
|
||
│ │ DictService │ │ │ │ #[DemoAllow] │ │
|
||
│ │ ParamService │ │ │ │ │ │
|
||
│ │ ExcelService │ │ │ │ │ │
|
||
│ │ CaptchaService │ │ │ │ │ │
|
||
│ │ GeneratorService│ │ │ │ │ │
|
||
│ │ AttributeService│ │ │ │ │ │
|
||
│ │ DbMigrateService│ │ │ │ │ │
|
||
│ │ DbSchemaBuilder │ │ │ │ │ │
|
||
│ │ RequestInfoServ │ │ │ │ │ │
|
||
│ └──────────────────┘ └─────────────┘ └──────────────────────┘ │
|
||
└──────────────────────────┬───────────────────────────────────┘
|
||
│
|
||
┌────────────┴────────────┐
|
||
▼ ▼
|
||
┌─────────────┐ ┌─────────────┐
|
||
│ MySQL │ │ Redis │
|
||
│ PostgreSQL │ │ 缓存 │
|
||
│ SQL Server │ └─────────────┘
|
||
│ Oracle │
|
||
│ SQLite │
|
||
└─────────────┘
|
||
```
|
||
|
||
## 模块化设计
|
||
|
||
每个业务模块遵循统一的文件结构:
|
||
|
||
```text
|
||
app/controller/UserController.php # HTTP 入口
|
||
app/logic/UserLogic.php # 业务逻辑
|
||
app/model/User.php # 数据模型
|
||
app/validate/UserValidate.php # 参数验证
|
||
```
|
||
|
||
| 文件 | 职责 | 基类 |
|
||
|------|------|------|
|
||
| Controller | 接收请求、调用 Logic、返回响应 | BaseController |
|
||
| Logic | 业务逻辑、属性配置、钩子处理 | BaseLogic / BaseTenantLogic |
|
||
| Model | 数据库表映射 | BaseModel |
|
||
| Validate | 参数校验规则 | ThinkPHP Validate |
|
||
|
||
## 关键设计决策
|
||
|
||
| 决策 | 选择 | 原因 |
|
||
|------|------|------|
|
||
| 认证方案 | JWT 双令牌 | 无状态,适合分布式部署 |
|
||
| 删除策略 | 软删除(is_delete) | 数据可恢复,避免误删 |
|
||
| 字段命名 | 数据库 snake_case / 前端 camelCase | 各端遵循各自惯例 |
|
||
| 缓存策略 | 两级缓存(请求级 + 持久缓存) | 减少数据库查询 |
|
||
| 数据库 | 多数据库支持 | 适配不同客户需求 |
|
||
| 权限模型 | RBAC(用户→角色→菜单) | 灵活的权限配置 | |