13 KiB
13 KiB
name, overview, design
| name | overview | design | ||||||
|---|---|---|---|---|---|---|---|---|
| 智能衣橱管理后台前端 | 基于 Vue3 + TypeScript + Vite 从零搭建「智能衣橱」管理后台前端,对接 Go 后端 /api/v1 全部接口,覆盖登录鉴权、仪表盘、用户/商品/订单退款/内容审核/通知/管理员管理 8 大模块。 |
|
产品概述
基于 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 代理联调。
架构设计
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。