Files
zt-closet-manage-frontend/.codebuddy/plans/智能衣橱管理后台前端_c7c50b5f.md
T
2026-09-11 01:46:36 +08:00

142 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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`。