first commit
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
---
|
||||
name: 智能衣橱管理后台前端
|
||||
overview: 基于 Vue3 + TypeScript + Vite 从零搭建「智能衣橱」管理后台前端,对接 Go 后端 /api/v1 全部接口,覆盖登录鉴权、仪表盘、用户/商品/订单退款/内容审核/通知/管理员管理 8 大模块。
|
||||
design:
|
||||
architecture:
|
||||
framework: react
|
||||
component: mui
|
||||
---
|
||||
|
||||
## 产品概述
|
||||
|
||||
基于 zt-closet-manage-backend 后端 API 契约,从零构建「智能衣橱」管理后台前端系统(Vue 3 + TypeScript + Element Plus)。系统覆盖管理员登录鉴权(JWT 双 token 自动刷新)、仪表盘统计、用户管理、商品管理、订单与退款审核、内容审核(穿搭/衣物/衣柜分享)、通知推送,以及超级管理员专属的管理员账号管理,共 9 大功能模块。
|
||||
|
||||
## 核心功能
|
||||
|
||||
- **登录与鉴权**:账号密码登录,access/refresh 双 token 管理;access 过期自动用 refresh 换新并重放原请求;登出、修改密码;按 role 区分超管/普通管理员菜单与路由权限
|
||||
- **仪表盘**:统计卡片展示用户总数/今日新增/状态分布、订单状态分布、累计与今日营收/累计退款、待办事项(待处理退款、待审核穿搭、上架商品数),金额以元展示
|
||||
- **用户管理**:分页搜索(昵称/手机号/OpenID/状态)、详情查看(含四类额度)、封禁/解封(临时按天/永久)、额度人工调整、VIP 人工调整,均带原因填写与二次确认
|
||||
- **商品管理**:分页筛选(类型/状态/关键字)、新增、编辑、上下架、软删除;商品类型含会员包/上传包/AI 包/衣柜分享包/搭配分享包,金额按分输入、按元展示
|
||||
- **订单与退款**:订单列表筛选/详情抽屉;退款单列表(状态 0-3 可显式筛选待处理)、审核通过/驳回(必填备注原因)
|
||||
- **内容审核**:穿搭列表筛选/详情(含衣物明细)、审核通过/驳回、封禁/解封;衣物列表/详情;衣柜分享列表/封禁/解封
|
||||
- **通知推送**:单用户系统通知、全量广播(返回发送人数),表单带字数限制校验
|
||||
- **管理员管理(超管专属)**:管理员列表、创建、编辑(昵称/密码/角色/状态)、删除;普通管理员无权限(后端 403,前端同时隐藏入口)
|
||||
- **统一交互规范**:所有业务错误以 body.code 判断并提示;金额统一 `分→元` 格式化;时间戳统一格式化展示;列表统一分页(page/page_size 1~50)
|
||||
|
||||
## 视觉要求
|
||||
|
||||
深色侧边栏 + 浅色内容区的经典管理后台布局;侧边栏按业务域分组菜单并支持折叠;顶部栏含面包屑、管理员信息、修改密码、登出;状态使用彩色 Tag 标签、操作按钮使用文字链接风格;表格斑马纹、hover 高亮;统计卡片带渐变图标底;弹窗表单统一 Element Plus 风格,操作均带确认与结果反馈。
|
||||
|
||||
## 技术栈
|
||||
|
||||
- **框架**:Vue 3.5(`<script setup lang="ts">` 组合式 API)+ TypeScript 6.0
|
||||
- **UI 组件库**:Element Plus(表格/表单/分页/对话框/抽屉/消息提示全覆盖)
|
||||
- **路由**:vue-router 4(含全局前置守卫鉴权与角色权限)
|
||||
- **状态管理**:Pinia(auth store 持久化 token/admin_info)
|
||||
- **HTTP**:axios 实例封装(请求拦截注入 Bearer、响应拦截统一 code 处理、11002 自动刷新重放、防并发刷新)
|
||||
- **开发代理**:Vite `server.proxy` 将 `/api` 转发 `http://localhost:8080`,规避 CORS
|
||||
- **格式化**:手写 `formatMoney`(分→元)、`formatDate`(Unix 秒→字符串)工具函数,不引入额外依赖
|
||||
|
||||
## 实现方案
|
||||
|
||||
### 总体策略
|
||||
|
||||
按「基础骨架 → API 契约层 → 布局与鉴权 → 业务模块页」四阶段推进。所有 API 类型严格对齐后端 DTO 的 json tag;枚举以常量映射表集中管理(数值→文案→Tag 颜色);复用一套「筛选表单 + 表格 + 分页」的页面组织模式,保证 9 个列表页风格与交互一致。
|
||||
|
||||
### 关键技术决策
|
||||
|
||||
- **axios 拦截器设计**:响应 code 非 0 时统一 ElMessage 报错并 reject;HTTP 401 且 code=11002 时,以单例 Promise 防并发调用 refresh 接口(携带旧 access + refresh),成功后更新 token 并重放原请求队列;刷新失败清空会话跳转登录页。其余 401/403/500 直接提示并跳转/返回。
|
||||
- **路由权限**:静态定义全部路由,meta 标记 `requiresAuth`/`superOnly`;守卫中校验 token 与 admin_info.role,超管专属路由对普通管理员重定向到仪表盘并提示无权限。
|
||||
- **金额与时间**:所有金额字段后端为分(int64),输入框以「元」为单位编辑、提交时乘 100 取整,列表用 `formatMoney` 展示;时间戳为 Unix 秒,统一 `formatDate` 输出 `YYYY-MM-DD HH:mm:ss`,0/空值显示「—」。
|
||||
- **枚举映射**:constants.ts 集中维护 status/vip/quota/goods/order/refund/outfit/share/image 等全部枚举的 `{value,label,tagType}` 映射表,组件通过辅助函数取文案与颜色,避免散落魔法数字。
|
||||
- **页面组织模式**:列表页统一「筛选卡片区 + 表格卡片区 + 分页」三段式;写操作(封禁/调整额度/审核等)统一对话框表单 + 提交确认 + 成功后刷新当前页。
|
||||
- **性能**:列表接口后端已分页(每页最多 50 条),前端不做全量拉取;表格列数多时用固定关键列 + 详情抽屉承载次要信息;组件按路由懒加载切分 chunk。
|
||||
|
||||
## 实施细节
|
||||
|
||||
- **依赖安装**:`npm i element-plus vue-router@4 pinia axios` 及 `@element-plus/icons-vue`;main.ts 全量引入 Element Plus(管理后台规模,按需引入收益有限)并注册图标。
|
||||
- **主色定制**:通过 Element Plus CSS 变量(`--el-color-primary` 系列)覆盖为靛蓝色系,与深色侧边栏协调。
|
||||
- **退款状态筛选注意**:`/refunds?status=0` 须显式传 0(待处理),前端下拉用「-1=全部」占位转换,防止丢失。
|
||||
- **refresh-token 注意**:body 必须同时携带 `refresh_token` 与旧 `access_token`(后端强制校验)。
|
||||
- **noUncheckedIndexedAccess 已开启**:数组/对象索引访问需判空处理。
|
||||
- **业务错误提示**:后端多数业务错误 HTTP 仍为 200,必须读取 body.code 分支提示 msg;避免仅按 HTTP 状态判断。
|
||||
- **安全**:token 仅存 localStorage(本场景无 SSR);密码字段不落日志;请求日志不打印 Authorization。
|
||||
- **开发联调**:后端未启动时前端可正常渲染空态;启动后端(`go run .`,默认 8080)后经 Vite 代理联调。
|
||||
|
||||
## 架构设计
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph 前端
|
||||
A[Login 登录页] --> B[AdminLayout 主布局]
|
||||
B --> C[Router 路由 + 守卫]
|
||||
C --> D[业务页面 views]
|
||||
D --> E[api 模块层]
|
||||
E --> F[axios 实例 + 拦截器]
|
||||
F --> G[Pinia auth store]
|
||||
end
|
||||
F -->|/api 经 Vite proxy| H[Go 后端 :8080/api/v1]
|
||||
```
|
||||
|
||||
- **分层**:views(页面)→ api(接口封装,纯函数)→ request(axios 拦截器)→ store(token/管理员信息);类型集中在 types/,枚举与格式化工具在 utils/,与后端契约一一对应。
|
||||
- **数据流**:用户操作 → 页面调用 api → axios 注入 token 发请求 → 响应拦截统一处理 code/401 → 页面更新表格数据/提示结果 → auth store 变更触发路由守卫响应。
|
||||
|
||||
## 目录结构
|
||||
|
||||
```
|
||||
zt-closet-manage-frontend/
|
||||
├── package.json # [MODIFY] 新增 element-plus/vue-router/pinia/axios/@element-plus/icons-vue 依赖
|
||||
├── vite.config.ts # [MODIFY] 增加 server.proxy:/api → http://localhost:8080
|
||||
├── index.html # [MODIFY] 标题改为「智能衣橱管理后台」
|
||||
├── src/
|
||||
│ ├── main.ts # [MODIFY] 挂载 router/pinia、全量引入 Element Plus 与图标、引入全局样式
|
||||
│ ├── App.vue # [MODIFY] 替换为 <router-view/> 根组件
|
||||
│ ├── assets/
|
||||
│ │ ├── main.css # [MODIFY] 全局样式:布局背景、卡片圆角阴影、滚动条、通用工具类
|
||||
│ │ └── element-theme.css # [NEW] Element Plus 主色变量覆盖(靛蓝系)+ 深色侧边栏配色变量
|
||||
│ ├── router/index.ts # [NEW] 路由表 + 全局守卫(登录态校验、superOnly 角色校验、页面标题)
|
||||
│ ├── stores/auth.ts # [NEW] Pinia auth store:token/refreshToken/adminInfo 持久化、login/logout/refresh 动作
|
||||
│ ├── utils/
|
||||
│ │ ├── request.ts # [NEW] axios 实例:注入 Bearer、code≠0 统一报错、11002 单例刷新+请求队列重放、401/403/500 处理
|
||||
│ │ ├── format.ts # [NEW] formatMoney(分→元)、formatDate(秒→YYYY-MM-DD HH:mm:ss)、formatDateTimeRange 等
|
||||
│ │ └── constants.ts # [NEW] 全量枚举映射:用户状态/VIP/额度/商品/订单/退款/穿搭/分享/图片处理/管理员角色等 → {label,tagType}
|
||||
│ ├── types/
|
||||
│ │ ├── common.ts # [NEW] ApiResponse{code,msg,data,details}、PageQuery、PageResult{total,page,page_size,list} 泛型
|
||||
│ │ ├── auth.ts # [NEW] AdminInfo、AdminLoginResponse、RefreshTokenResponse、改密请求类型
|
||||
│ │ ├── user.ts # [NEW] UserListItem/UserDetailResponse/QuotaItem/封禁/额度/VIP 调整请求类型
|
||||
│ │ ├── goods.ts # [NEW] GoodsItem/GoodsCreateRequest/GoodsUpdateRequest/状态请求类型
|
||||
│ │ ├── order.ts # [NEW] OrderItem/RefundItem/审核请求类型
|
||||
│ │ ├── content.ts # [NEW] OutfitListItem/OutfitDetailResponse/OutfitClothesItem/ClothesItem/ClosetShareItem 及审核/封禁请求
|
||||
│ │ ├── notification.ts # [NEW] 单发/广播请求与响应类型
|
||||
│ │ └── dashboard.ts # [NEW] 仪表盘聚合响应嵌套结构类型
|
||||
│ ├── api/
|
||||
│ │ ├── auth.ts # [NEW] login/refreshToken/logout/changePassword
|
||||
│ │ ├── dashboard.ts # [NEW] getSummary
|
||||
│ │ ├── user.ts # [NEW] 列表/详情/封禁/解封/额度调整/VIP 调整
|
||||
│ │ ├── goods.ts # [NEW] 列表/创建/更新/上下架/软删
|
||||
│ │ ├── order.ts # [NEW] 订单列表/详情、退款列表/通过/驳回
|
||||
│ │ ├── content.ts # [NEW] 穿搭列表/详情/审核/封禁解封、衣物列表/详情、分享列表/封禁解封
|
||||
│ │ ├── notification.ts # [NEW] 单发/广播
|
||||
│ │ └── admin.ts # [NEW] 管理员列表/创建/更新/删除
|
||||
│ ├── components/
|
||||
│ │ ├── PaginationBar.vue # [NEW] 通用分页条:v-model 页码/每页条数,联动 emit 刷新,封装 total 显示
|
||||
│ │ └── SearchFormCard.vue # [NEW] 通用筛选卡片:插槽承载筛选控件,查询/重置按钮触发 emit
|
||||
│ ├── layout/
|
||||
│ │ ├── AdminLayout.vue # [NEW] 整体布局:深色可折叠侧边栏(分组菜单、按 role 过滤超管菜单)+ 顶栏 + 内容区
|
||||
│ │ ├── SidebarMenu.vue # [NEW] 侧边栏菜单组件:递归渲染分组路由、折叠态图标提示、active 高亮
|
||||
│ │ └── HeaderBar.vue # [NEW] 顶栏:面包屑、管理员昵称下拉(修改密码对话框/登出)
|
||||
│ └── views/
|
||||
│ ├── login/LoginView.vue # [NEW] 登录页:渐变背景居中卡片、账号密码表单校验、登录后按 role 跳转
|
||||
│ ├── dashboard/DashboardView.vue # [NEW] 仪表盘:四组统计卡片(用户/订单/营收/待办)、金额元格式化、空态处理
|
||||
│ ├── user/UserListView.vue # [NEW] 用户列表:筛选/表格(状态 Tag)/详情抽屉(额度表)/封禁、解封、额度调整、VIP 调整对话框
|
||||
│ ├── goods/GoodsListView.vue # [NEW] 商品列表:筛选/表格/新增编辑对话框(分元输入转换)/上下架/软删确认
|
||||
│ ├── order/OrderListView.vue # [NEW] 订单列表:筛选/表格/详情抽屉(金额与配额快照)
|
||||
│ ├── order/RefundListView.vue # [NEW] 退款列表:状态筛选(含显式待处理)/通过、驳回对话框(必填原因)
|
||||
│ ├── review/OutfitListView.vue # [NEW] 穿搭列表:多条件筛选/审核通过驳回(驳回必填原因)/封禁解封/详情抽屉(衣物明细)
|
||||
│ ├── review/ClothesListView.vue # [NEW] 衣物列表:筛选/详情抽屉(属性字段分栏展示)
|
||||
│ ├── review/ShareListView.vue # [NEW] 衣柜分享列表:筛选/封禁解封
|
||||
│ ├── notification/NotifyView.vue # [NEW] 通知推送:单用户通知与全量广播两个表单卡片、字数限制、广播返回 sent_count 提示
|
||||
│ └── admin/AdminListView.vue # [NEW] 管理员列表(超管):筛选/表格/创建编辑对话框/删除确认/状态禁用提示
|
||||
```
|
||||
|
||||
删除模板遗留文件:`src/components/HelloWorld.vue`、`TheWelcome.vue`、`WelcomeItem.vue`、`src/assets/logo.svg`。
|
||||
Reference in New Issue
Block a user