Files
rxthinkcmf-wiki/RXThinkCMF_Laravel13_NaiveVue/zh/architecture/overview.md
T
2026-10-08 17:50:29 +08:00

21 KiB
Raw Blame History

4.1 整体架构概览

:::tip 概述 本章从全局视角阐述系统的整体技术架构,涵盖前端、后端、数据库及基础设施等核心组成部分,旨在帮助开发者快速建立对系统全貌的清晰认知。 :::

架构总览

┌─────────────────────────────────────────────────────────────────┐
│                        浏览器(Vue3 + ElementPlus)              │
│                    Axios HTTP 请求 / Vite 开发代理               │
└──────────────────────────────┬──────────────────────────────────┘
                               │
                               ▼
┌─────────────────────────────────────────────────────────────────┐
│                        Nginx(反向代理)                         │
│              静态资源托管 / SSL 终止 / gzip 压缩 / 仅放行入口PHP  │
└──────────────────────────────┬──────────────────────────────────┘
                               │
                               ▼
┌─────────────────────────────────────────────────────────────────┐
│                     Laravel 13 Application                      │
│                                                                 │
│  ┌───────────────────────────────────────────────────────────┐  │
│  │              中间件链(按注册顺序执行)                     │  │
│  │  ┌───────┐ ┌──────┐ ┌───────────┐ ┌──────────┐            │  │
│  │  │ Proxy │→│ Cors │→│ForceJson  │→│ auth.jwt │            │  │
│  │  │真实IP │ │ 跨域  │ │ 强制JSON  │ │JWT+权限  │            │  │
│  │  └───────┘ └──────┘ └───────────┘ └──────────┘            │  │
│  │       全局组(api prepend)          路由组                  │  │
│  │                                    ┌────────┐ ┌─────────┐  │  │
│  │                                    │ tenant │→│log.oper.│  │  │
│  │                                    │租户上下文│ │操作日志 │  │  │
│  │                                    └────────┘ └─────────┘  │  │
│  │  另有 DemoMiddleware(演示拦截,按路由别名启用)              │  │
│  └───────────────────────────────┬───────────────────────────┘  │
│                                  ▼                              │
│  ┌───────────────────────────────────────────────────────────┐  │
│  │                 控制器层(Controller)                      │  │
│  │  Controller 基类 → success/fail/paginate · _page/_add 等   │  │
│  │  #[Permission] 权限注解 · #[OperationLog] 日志注解           │  │
│  │  FormRequest 类型注入 → 参数格式校验                        │  │
│  └───────────────────────────────┬───────────────────────────┘  │
│                                  ▼                              │
│  ┌───────────────────────────────────────────────────────────┐  │
│  │                 服务层(Service)                           │  │
│  │  BaseService / BaseTenantService                          │  │
│  │  属性配置 · 生命周期钩子 · 6 个 Concerns Trait 组合          │  │
│  │  文件处理 · 字典翻译 · 唯一性校验 · 数据权限 · 租户隔离       │  │
│  │  DB::transaction 事务管理 · BizException 业务异常            │  │
│  └───────────────────────────────┬───────────────────────────┘  │
│                                  ▼                              │
│  ┌───────────────────────────────────────────────────────────┐  │
│  │                 模型层(Eloquent Model)                    │  │
│  │  SoftDeletesByFlag(is_delete 软删除)· HasAuditColumns     │  │
│  └───────────────────────────────┬───────────────────────────┘  │
│                                  ▼                              │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────────────┐  │
│  │  MySQL 等    │  │   Redis     │  │   文件系统               │  │
│  │  五种数据库  │  │ 会话/缓存/队列│  │   public/uploads/       │  │
│  └─────────────┘  └─────────────┘  └─────────────────────────┘  │
└─────────────────────────────────────────────────────────────────┘

架构特征

:::tip 核心设计原则 遵循以下架构设计原则,确保系统在长期演进中保持高质量和可维护性: :::

1. 前后端分离

前端 Vue3 应用通过 HTTP API 调用后端 Laravel 服务,两者独立开发、独立部署。前端开发阶段通过 Vite 的 proxy 配置将 /api 请求代理到后端 http://localhost:8000,生产环境由 Nginx 统一反向代理。

2. 分层架构

后端严格分为三层,每层职责单一、依赖单向:

层次 目录 职责
控制器层 app/Http/Controllers/Api/ 路由入口、权限注解、参数注入、响应返回
服务层 app/Services/ 业务逻辑、属性配置、生命周期钩子、横切处理
模型层 app/Models/ 数据库表映射、软删除、审计字段

验证职责分层:FormRequest 只做格式验证,Service 只做业务规则(唯一性、状态依赖)。

3. 模板方法模式(声明式 CRUD)

通过 BaseService 基类,将通用 CRUD 流程固化为模板方法。子类只需声明差异点(过滤字段、排序规则、唯一性校验等),即可获得完整的增删改查能力,极大减少重复代码。

// 子类只需声明差异点,即可获得完整 CRUD 能力
class ExampleService extends BaseService
{
    use HasCrudOperations, HasQueryScopes, HasSerializeMaps, HasUniqueCheck;

    /**
     * 绑定的模型类
     */
    protected string $modelClass = Example::class;

    /**
     * LIKE 模糊匹配字段
     *
     * @var array<int, string>
     */
    protected array $pageLikeFields = ['name'];

    /**
     * 精确匹配字段
     *
     * @var array<int, string>
     */
    protected array $pageEqFields = ['status'];

    /**
     * 唯一性校验字段
     *
     * @var array<int, string>
     */
    protected array $uniqueFields = ['name'];

    /**
     * 枚举显示名映射
     *
     * @var array<string, string>
     */
    protected array $serializeMaps = ['status' => 'example_status'];
}

4. 中间件链式处理

请求处理采用中间件链,在 bootstrap/app.php 中注册别名与分组:

请求进入 → Proxy → Cors → ForceJson → auth.jwt → tenant → log.operation → 控制器
           └────────── 全局 api 组 ─────────┘└──────── 路由中间件组 ────────┘
                                                   │
响应返回 ←────────────(逆向穿过)──────────────────┘
(log.operation 在响应后 terminable 阶段落库)
中间件 别名 作用域 职责
ProxyMiddleware proxy 全局(api prepend) 受信代理真实 IP 提取
Cors cors 全局 跨域处理(config/cors.php)
ForceJsonResponse force.json 全局 强制 JSON Accept 头
Authenticate auth.jwt 路由组 JWT 认证 + #[Permission] 反射鉴权
ResolveTenant tenant 路由组 租户上下文解析注入
LogOperation log.operation 路由组 操作日志采集(terminable 落库)
DemoMiddleware demo 路由别名 演示环境写操作拦截(#[DemoAllow] 放行)

5. 全局异常处理

App\Exceptions\Handler 统一捕获 api/* 请求的异常并返回标准 JSON 响应:

来源 异常类型 触发场景 响应
Handler BizException 业务规则失败(Service 抛出) {code:异常code(默认1), msg:"业务提示"}
Handler ValidationException 代码内手动校验失败 {code:422, msg:"参数验证失败", data:{错误明细}}
Handler AuthenticationException 未登录 / 令牌失效 {code:401, msg:"未授权,请先登录"}
Handler NotFoundHttpException 路由不存在 {code:404, msg:"数据不存在"}
Handler 其它异常 未捕获异常 {code:500, msg:调试模式为原文,生产为"操作失败"}
FormRequest HttpResponseException 表单格式校验失败 {code:1, msg:"参数验证失败", data:{字段=>错误数组}}
auth.jwt 中间件 — Token 缺失/过期/无权限 {code:401/403, ...}(到达控制器前拦截)

6. 统一响应格式

所有 API 端点返回统一的 JSON 结构:

{
    "code": 0,
    "ok": true,
    "msg": "操作成功",
    "data": {}
}

成功响应 code=0,失败响应 code=1。HTTP 状态码默认 200,仅 403 同时设置对应 HTTP 状态码(便于网关处理),code=401 由前端跳转登录。前端无需针对不同接口做差异化解析。见 5.16 统一响应与异常抛出。

7. 软删除策略

:::warning 禁止物理删除 所有业务数据必须使用软删除(is_delete 字段),禁止物理删除。物理删除仅用于日志清理等特殊场景。 :::

所有业务表通过 is_delete 字段实现软删除(0=正常,1=已删除)。SoftDeleteFlagScope 全局查询范围自动追加 is_delete=0 过滤,业务代码无需关心已删除数据。

// 自动过滤已删除数据
$users = User::query()->get();            // WHERE is_delete = 0

// 查询已删除数据
$deleted = User::withoutGlobalScope(SoftDeleteFlagScope::class)->get();

// 软删除
$user->softDelete();                      // UPDATE SET is_delete = 1

// 批量软删除
User::batchSoftDelete([1, 2, 3]);

8. 审计字段自动写入

通过 HasAuditColumns Trait 的模型事件自动填充审计字段:

// 创建时自动填充(已赋值则保留原值)
static::creating(function ($model) {
    $model->create_user = $model->create_user ?? Auth::username();
    $model->create_time = $model->create_time ?? now();
});

// 更新时自动填充(强制覆盖)
static::updating(function ($model) {
    $model->update_user = Auth::username();
    $model->update_time = now();
});

9. 多数据库支持

通过 DB_CONNECTION 环境变量切换数据库驱动(MySQL / PostgreSQL / SQL Server / Oracle / SQLite),document/ 下提供五套初始化脚本;Oracle 通过自定义 oci 驱动接入(AppServiceProvider 注册,配套 OracleGrammar / OracleProcessor)。业务代码无需修改。

10. 两级缓存架构

请求级缓存(static 变量)     ← 同一请求内不重复查库
        │ 未命中
        ▼
持久缓存(Cache 门面/Redis)  ← 跨请求复用,1小时过期
        │ 未命中
        ▼
数据库查询                    ← 查询后写入两级缓存

DictCacheService 采用此架构,配合 Observer(DictItemObserver / MenuObserver / RoleMenuObserver)在数据变更时自动失效缓存。详见 4.8 缓存架构设计。

技术分层图

┌──────────────────────────────────────────────────────────────┐
│                    前端(Vue3 + ElementPlus)                  │
│         Pinia · Vue Router · Axios · TinyMce · ECharts       │
└──────────────────────────┬───────────────────────────────────┘
                           │ HTTP / JSON
┌──────────────────────────┴───────────────────────────────────┐
│                    Laravel 13 Application                     │
│                                                              │
│  ┌─────────────┐ ┌─────────────┐ ┌──────────────────────┐   │
│  │  中间件      │ │  路由        │ │  异常处理器           │   │
│  │  ─────────  │ │  ─────────  │ │  ─────────────────   │   │
│  │  Proxy      │ │  routes/    │ │  BizException        │   │
│  │  Cors       │ │  api.php    │ │  ValidationException │   │
│  │  ForceJson  │ │  web.php    │ │  Authentication      │   │
│  │  auth.jwt   │ │  console.php│ │  NotFoundHttp        │   │
│  │  tenant     │ │             │ │  Exception(500)      │   │
│  │  log.oper.  │ │             │ │                      │   │
│  │  demo       │ │             │ │                      │   │
│  └─────────────┘ └─────────────┘ └──────────────────────┘   │
│                                                              │
│  ┌────────────────────────────────────────────────────────┐  │
│  │  控制器层(app/Http/Controllers/Api/)28 个              │  │
│  │  Controller 基类 · #[Permission] · #[OperationLog]      │  │
│  │  FormRequest 注入(24 个)                              │  │
│  └────────────────────────────────────────────────────────┘  │
│                           │                                  │
│  ┌────────────────────────────────────────────────────────┐  │
│  │  服务层(app/Services/)36 个                            │  │
│  │  BaseService / BaseTenantService                       │  │
│  │  6 Trait:CRUD · 查询 · 文件 · 数据权限 · 字典 · 唯一    │  │
│  └────────────────────────────────────────────────────────┘  │
│                           │                                  │
│  ┌────────────────────────────────────────────────────────┐  │
│  │  模型层(app/Models/)25 个                              │  │
│  │  SoftDeletesByFlag · HasAuditColumns                   │  │
│  └────────────────────────────────────────────────────────┘  │
│                                                              │
│  ┌──────────────────┐ ┌─────────────┐ ┌──────────────────┐   │
│  │  横切服务          │ │ FormRequest │ │  注解(Attributes)│   │
│  │  ──────────────  │ │ ──────────  │ │  ──────────────  │   │
│  │  JwtService      │ │ BaseRequest │ │  Permission      │   │
│  │  PasswordService │ │  24 个       │ │  OperationLog    │   │
│  │  DictCacheService     │ │             │ │  DemoAllow       │   │
│  │  CaptchaService  │ │             │ │                  │   │
│  │  ExcelService    │ │             │ │                  │   │
│  │  GeneratorService│ │             │ │                  │   │
│  │  DbMigrateService│ │             │ │                  │   │
│  │  RequestInfo...  │ │             │ │                  │   │
│  └──────────────────┘ └─────────────┘ └──────────────────┘   │
└──────────────────────────┬───────────────────────────────────┘
                           │
              ┌────────────┴────────────┐
              ▼                         ▼
     ┌─────────────┐           ┌─────────────┐
     │   MySQL     │           │   Redis     │
     │  PostgreSQL │           │ 会话/缓存/队列│
     │  SQL Server │           └─────────────┘
     │  Oracle     │
     │  SQLite     │
     └─────────────┘

模块化设计

每个业务模块遵循统一的文件结构:

app/Http/Controllers/Api/UserController.php   # HTTP 入口
app/Http/Requests/UserRequest.php             # 参数验证
app/Services/UserService.php                  # 业务逻辑
app/Models/User.php                           # 数据模型
文件 职责 基类
Controller 接收请求、调用 Service、返回响应 App\Http\Controllers\Controller
Request 参数格式校验 BaseRequest
Service 业务逻辑、属性配置、钩子处理 BaseService / BaseTenantService
Model 数据库表映射 Eloquent Model + Concerns Trait

关键设计决策

决策 选择 原因
认证方案 JWT 双令牌(Redis 有状态) 无状态便于水平扩展,有状态支持踢下线/改密全端失效
删除策略 软删除(is_delete) 数据可恢复,唯一性校验可排除已删数据
字段命名 数据库 snake_case / 响应 camelCase API_CAMEL_SNAKE_CONVERT 自动转换,各端遵循各自惯例
缓存策略 两级缓存(请求级 + Redis) 减少数据库查询,Observer 保证一致性
数据库 五种数据库 + 五套脚本 适配不同客户需求
权限模型 RBAC(用户→角色→菜单,菜单即权限) 灵活的权限配置,注解声明即生效
安全基线 JWT_SECRET fail-close、生产 APP_DEBUG=false 敏感信息不泄露、弱密钥不启动