签入版本

This commit is contained in:
2026-10-08 17:50:29 +08:00
parent 809750b47e
commit e213a9b31d
444 changed files with 39366 additions and 37533 deletions
@@ -1,14 +1,14 @@
# 4.4 前端分层架构
:::tip 概述
前端采用 Vue 3 + TypeScript 组件化架构,分为 View(视图)→ API(接口)→ Store(状态)→ HTTP(请求)四层。辅以 Router(路由)、Directives(指令)、Hooks(组合式函数)、Utils(工具)等支撑模块。
前端采用 Vue 3 + TypeScript 组件化架构,分为 View(视图)→ API(接口)→ Store(状态)→ HTTP(请求)四层。辅以 Router(路由)、Directives(指令)、Hooks(组合式函数)、Utils(工具)等支撑模块。前端为本仓库 `ui/` 目录内的 EleVue 管理后台。
:::
## 架构全景
```text
┌─────────────────────────────────────────────────────────────────────┐
│ 支撑模块 │
│ 支撑模块 │
│ │
│ Router(路由) Directives(指令) Hooks(组合式函数) │
│ src/router/ src/directives/ src/hooks/ │
@@ -19,7 +19,7 @@
│ 被主干层引用
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 主干链路 │
│ 主干链路 │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ View(视图层) │ │
@@ -40,10 +40,9 @@
│ │ Axios 封装:拦截器、Token 携带、错误处理 │ │
│ │ 文件:src/utils/http/axios/ │ │
│ └──────────────────────────┬──────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 后端 API(RESTful JSON) │ │
│ │ 后端 API(RESTful JSON,{code, ok, msg, data}) │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
@@ -72,7 +71,7 @@ src/views/
├── content/ 内容管理
│ ├── article/ 文章管理
│ └── category/ 分类管理
├── login.vue 登录页
├── login/ 登录页
├── dashboard/ 仪表盘
└── ...
```
@@ -107,7 +106,7 @@ src/views/
</el-table-column>
</el-table>
<!-- 分页 -->
<!-- 分页(后端固定返回 records / total / current / size / pages) -->
<el-pagination v-model:current-page="pageNo" v-model:page-size="pageSize"
:total="total" @change="fetchData" />
</template>
@@ -145,44 +144,48 @@ onMounted(() => fetchData());
| 新增 | `{module}Add` | POST | `data` |
| 修改 | `{module}Update` | PUT | `data` |
| 删除 | `{module}Delete` | DELETE | URL 参数 |
| 批量删除 | `{module}BatchDelete` | DELETE | `data` |
| 批量删除 | `{module}BatchDelete` | **DELETE**(带 body) | `data`(`{ids:[]}`) |
| 导入 | `{module}Import` | POST | FormData |
| 导出 | `{module}Export` | GET | `params` |
:::warning 批量删除方法为 DELETE
本项目 `batchDelete` 路由为 **DELETE**(请求体仍传 `ids` 数组——DELETE 方法携带 body),见 [3.7 路由注册](/zh/guide/route.html)。
:::
**完整示例:**
```typescript
// src/api/system/user.ts
// src/api/tool/example.ts
import { http } from '@/utils/http/axios';
// 分页查询
export function getUserPage(params?) {
return http.request({ url: '/user/page', method: 'GET', params });
export function getExamplePage(params?) {
return http.request({ url: '/example/page', method: 'GET', params });
}
// 详情
export function getUserDetail(id) {
return http.request({ url: '/user/detail/' + id, method: 'GET' });
export function getExampleDetail(id) {
return http.request({ url: '/example/detail/' + id, method: 'GET' });
}
// 新增
export function userAdd(data: any) {
return http.request({ url: '/user/add', method: 'POST', data });
export function exampleAdd(data: any) {
return http.request({ url: '/example/add', method: 'POST', data });
}
// 修改
export function userUpdate(data: any) {
return http.request({ url: '/user/update', method: 'PUT', data });
export function exampleUpdate(data: any) {
return http.request({ url: '/example/update', method: 'PUT', data });
}
// 删除
export function userDelete(id) {
return http.request({ url: '/user/delete/' + id, method: 'DELETE' });
export function exampleDelete(id) {
return http.request({ url: '/example/delete/' + id, method: 'DELETE' });
}
// 批量删除
export function userBatchDelete(data: any) {
return http.request({ url: '/user/batchDelete', method: 'DELETE', data });
// 批量删除(DELETE + 请求体 ids 数组)
export function exampleBatchDelete(data: any) {
return http.request({ url: '/example/batchDelete', method: 'DELETE', data });
}
```
@@ -239,15 +242,18 @@ src/utils/http/axios/
```text
登录:
userStore.login(userInfo)
→ POST /login → 获取 access_token
→ POST /login(含 key/code 验证码参数)
→ 获取 access_token
→ Storage.set(ACCESS_TOKEN, token)
→ this.setToken(token)
获取用户信息:
userStore.GetInfo()
→ GET /index/getUserInfo
→ this.setPermissions(res.permissions)
→ this.setUserInfo(res)
→ GET /index/getUser
→ setPermissions(res.permissions)
→ setUserInfo(res)
获取菜单(动态路由):
→ GET /index/getMenus
登出:
userStore.logout()
@@ -280,7 +286,7 @@ src/utils/http/axios/
```text
1. 用户登录 → 获取 Token → 存入 Store
2. 路由守卫(router.beforeEach)检测到 Token
3. 调用 GET /index/getMenus 获取菜单树
3. 调用 GET /index/getMenus 获取菜单树(后端按用户权限过滤)
4. generator-routers.ts 将菜单树转换为路由表
5. router.addRoute() 动态注入路由
6. 渲染侧边栏菜单
@@ -324,6 +330,10 @@ src/utils/http/axios/
用户权限列表包含 `*:*:*` 时,表示超级管理员,拥有所有权限,`v-perm`/`v-perms` 指令始终放行。
:::
:::warning 前端权限不是安全防线
`v-perm` 只是体验层(隐藏按钮);真正的安全校验在后端 `#[Permission]` 注解 + `auth.jwt` 中间件(见 [3.8 权限节点配置](/zh/guide/permission.html))。
:::
## 支撑模块
### Hooks(组合式函数)
@@ -366,8 +376,8 @@ API: getExamplePage(params)
HTTP: 请求拦截器添加 Token
│ 发送 GET /example/page?pageNo=1&pageSize=20
▼
后端: Controller → Logic → Model → Database
│
后端: Controller → Service → Model → Database
│(响应 {code, ok, msg, data},snake→camel 已在后端完成)
▼
HTTP: 响应拦截器判断 code
│ code === 0 → 返回 data
@@ -387,8 +397,8 @@ Vue 响应式 → 表格自动刷新
登录成功
│
▼
userStore.setToken(token) → 响应式更新
userStore.setUserInfo(info) → 响应式更新
userStore.setToken(token) → 响应式更新
userStore.setUserInfo(info) → 响应式更新
userStore.setPermissions(perm) → 响应式更新
│
▼
@@ -402,14 +412,14 @@ v-perm 指令读取 permissions 列表 → 控制元素显隐
| 后端 | 前端 | 说明 |
|------|------|------|
| `app/controller/UserController.php` | `src/api/system/user.ts` | API 函数映射 |
| `app/logic/UserLogic.php` | `src/views/system/user/` | 业务页面 |
| `app/model/User.php` | — | 前端不直接操作模型 |
| `app/validate/UserValidate.php` | — | 前端校验由表单组件处理 |
| `app/validate/*Validate.php` 的场景 | 表单 `rules` | 前端表单校验规则 |
| `route/app.php` | `src/api/**/*.ts` | 路由 ↔ API 函数 |
| 后端字典 `DictService` | `src/enums/` + 字典 Store | 枚举常量 |
| 后端 `#[Permission]` 注解 | `v-perm` 指令 | 权限码对应 |
| `Http/Controllers/Api/UserController.php` | `src/api/system/user.ts` | API 函数映射 |
| `Services/UserService.php` | `src/views/system/user/` | 业务页面 |
| `Http/Requests/UserRequest.php` 的 rules | 表单 `rules` | 前端表单校验规则(体验层) |
| `Models/User.php` | — | 前端不直接操作模型 |
| `routes/api.php` | `src/api/**/*.ts` | 路由 ↔ API 函数 |
| 字典数据(`dict` 表) | `src/enums/` + 字典 Store | 枚举常量 |
| `#[Permission]` 注解 | `v-perm` 指令 | 权限码对应 |
| 分页 `records/total/current/size/pages` | el-pagination 绑定 | 固定分页结构 |
## 层间通信规范