# admin-vue **Repository Path**: xiak/admin-vue ## Basic Information - **Project Name**: admin-vue - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-07-22 - **Last Updated**: 2026-08-17 ## Categories & Tags **Categories**: Uncategorized **Tags**: UI ## README # 后台框架 · 管理系统 基于 **Vue 3 + Vite + TypeScript + Element Plus** 的后台管理系统基础框架。当前版本 **v1.16.0**。 内置完整布局、主题色、**24+ 组件演示页**、**10 个业务模块共 70+ 页面**、**10 个总览仪表盘**、系统管理示例,覆盖几乎全部 Element Plus 组件,可作为后续做后台系统的脚手架。 > **v1.15.3 更新**:完成全业务模块(10 个)+ 系统管理 + 数据大屏 + 组件演示页 + 共享组件 + 布局 + 基础设施的深度审计修复,消灭占位 stub,统一数据真实化与类型安全,补充单测至 246 个,`type-check / lint / test / build` 全链路通过。 ## 技术栈 - Vue 3 + ` ``` **两种数据模式**(自动判定): ```ts // 客户端模式(mock 阶段):传 source + filter useCrud({ source: () => rows.value, filter: (r, q) => ..., fields, create, update, remove }) // 服务端模式(接后端):传 fetch,模板零改动 useCrud({ fetch: async ({ page, size, query }) => { const { data } = await request.get('/artist', { params: { page, size, ...query } }) return { list: data.list, total: data.total } }, fields, create: (f) => request.post('/artist', f), update: (f, row) => request.put(`/artist/${row.id}`, f), remove: (row) => request.delete(`/artist/${row.id}`) }) ``` **FieldDef 字段类型**: | type | 控件 | 默认值 | | ----------- | ----------------- | ------- | | `input` | el-input | `''` | | `textarea` | el-input textarea | `''` | | `number` | el-input-number | `0` | | `select` | el-select | `''` | | `switch` | el-switch | `false` | | `radio` | el-radio-group | `''` | | `date` | el-date-picker | `null` | | `datetime` | el-date-picker | `null` | | `daterange` | el-date-picker | `[]` | **三类自定义插槽**: - `#col-{prop}="{ row }"` — SchemaTable 单元格自定义渲染(el-tag / el-switch / 图片预览) - `#field-{prop}="{ form, mode }"` — SchemaDialog 表单控件替换(MdEditor / Upload / 自定义组件) - `#search-{prop}="{ query }"` — SchemaSearch 搜索控件替换 **内置约束**(迁移时不需要每个页面各自实现): - `reset()` 自动重新搜索(避免「重置后没刷新」bug),`reset({ refetch: false })` 逃生舱 - `page.size` 变化自动回第一页(旧代码普遍漏掉) - `submitting` 期间 `openAdd` / `openEdit` 被拦截,防双创建 - 客户端模式有 200ms loading 延迟,让用户感知「加载」 - 服务端模式用 seq 计数器忽略过期响应(搜索连点 / 快速翻页不会闪内容) **和 FSM 的关系**:FSM 状态流转类页面(Order / Refund / Copyright)useCrud 只托管搜索 / 分页 / 行选择,状态流转仍走 ApprovalDialog。`#actions` slot 是 CRUD 与 FSM 的接缝,详见 `views/business/ecommerce/Order.vue`。 ### 接入真实后端 **5 分钟接入清单**(详见 [`docs/BACKEND_INTEGRATION.md`](docs/BACKEND_INTEGRATION.md)): 1. `cp .env.example .env.development`,按需修改 `VITE_API_BASE_URL` 2. 在 `vite.config.ts` 的 `server.proxy` 配置后端地址(默认 `/api -> http://localhost:8080`) 3. 在 `src/utils/auth.ts` 删除 `MOCK_ACCOUNTS`,把 `loginApi` / `fetchProfileApi` / `logoutApi` 改为真实接口;`refreshApi` 必须使用不带刷新拦截器的独立 axios 实例 4. 若需角色权限持久化:把 `utils/rolePermissions.ts` 中的 `saveRolePermissions` 改为 `PUT /role/:id/permissions`,`loadRolePermissions` 改为登录接口直接返回权限数组 5. 路由守卫、Pinia store、登录页、Role.vue 都无需改动 **边界说明**:路由表(`router/modules/`)是前端静态的,后端菜单接口只驱动导航展示与权限过滤——新增页面仍需前端发版,菜单数据从后端下发也无法动态挂载新组件。 **Mock 模式**:`npm run dev:mock` 启动内置 Mock,无需后端服务即可跑通登录 → 列表 → 详情 → 登出闭环。property/news/drama/aiservice/survey/alarm/music 六个模块的业务 CRUD 列表页已接入 mock 工厂(服务端分页 + 关键字/状态筛选),可直接在浏览器验证搜索 / 新增 / 编辑 / 删除 / 翻页;music 模块为全模块迁移模板(Genre 树形页除外)。未命中的请求仍走真实后端,方便渐进式接入。 ### 生产部署约束 - `.env.production` 默认使用同源 `/api`;CI/CD 可覆盖为真实 HTTPS 地址。生产构建会拒绝 `example.com`、localhost、127.0.0.1 或空地址。 - 路由使用 History 模式,Web 服务器必须把不存在的前端路径回退到 `index.html`。Nginx 根路径部署示例:`try_files $uri $uri/ /index.html;`。 - 子路径部署时同时设置 Vite `base`,路由与登录恢复逻辑会使用 `import.meta.env.BASE_URL`。 - 发布新版本后建议保留上一版本静态资源一段时间;即使旧 Chunk 已删除,客户端也只会自动刷新一次,随后进入可恢复错误页,不会无限刷新。 **请求层能力**(`src/utils/request.ts`): - 自动拆 envelope `{ code, data, message }`,调用方直接拿 `data` - 自动注入 `Authorization` 头 + `X-Request-Id`(后端日志联查) - 错误归一化为 `ApiError`,含 `code` / `status` / `isNetworkError` / `isTimeout` / `isUnauthorized` - 文件上传 `request.upload()` 支持 multipart + 进度回调 - 文件下载 `request.download()` 自动解析 `Content-Disposition` 文件名 - 全局 `ElMessage` 错误提示,调用方无需重复处理 ### 单元测试 基于 **Vitest 4 + happy-dom + @vue/test-utils**,覆盖工具函数、Pinia store、关键组件: ```bash npm run test # 一次性跑全部用例 npm run test:watch # 监听模式(开发期即时反馈) npm run test:coverage # v8 覆盖率报告(输出到 coverage/ 目录) ``` 测试文件与源码同目录命名 `*.test.ts`,配置在 `vitest.config.ts`。已覆盖: - `utils/stateMachine.test.ts` — FSM 多源转换 / requireComment / before-after 钩子 / shortestPath - `utils/rolePermissions.test.ts` — 角色权限的 save/load/clear 与损坏数据兜底 - `utils/export.test.ts` — CSV BOM / 逗号 / 引号 / 换行转义、DOM 下载触发 - `utils/mock/handlers.test.ts` — Mock 路由匹配、用户增删改查、登录闭环、业务 CRUD 工厂(property/news/drama/aiservice/survey/alarm/music,含服务端分页) ### 端到端测试(E2E) 基于 **Playwright**(`@playwright/test`,真实浏览器 chromium),用例在 `e2e/` 目录,配置在 `playwright.config.ts`: ```bash npm run test:e2e # 全部 E2E(自动拉起 dev server,已运行则复用) npx playwright show-report # 查看 HTML 报告 ``` 约定:`e2e/auth.setup.ts` 预登录管理员并保存 storageState,业务用例直接以登录态启动;登录类用例自行清空 storageState。当前覆盖登录流程(成功/失败/访客权限/重定向回跳)、核心页面冒烟(工作台 / Schema 列表 / 富文本 / 图片裁剪,含 pageerror 与 console.error 收集断言)、菜单导航与 SchemaSearch 下拉回归、Schema CRUD 全旅程(搜索/重置/新增/编辑/删除)。CI(`.github/workflows/ci.yml`)在 push / PR 时自动跑 type-check / lint / test / build 与 E2E。 - `stores/user.test.ts` — `hasPermission` 三类语义(精确 / `*` / 前缀通配)+ login/logout/fetchProfile - `components/ApprovalDialog.test.ts` — 转换查找、requireComment 校验、onConfirm 异步等待、cancel - `views/business/**/*.test.ts` — 代表性 useCrud 列表页(Owner/Article/Channel/Series/List)初始化拉取与搜索触发 约定:纯函数工具用 `describe` + 多 `it`,组件测试用 `mount` + `attachTo: document.body`(Element Plus dialog teleport 到 body)。新增工具函数时强烈建议同步补单测,CI 阶段 `npm run test` 可一次性回归。 ## License MIT