- 后端新增管理员、商品、分类聚合模型 - 实现积分规则、礼品、订单、会员等完整功能 - 添加管理员认证和权限管理 - 完善数据库迁移和实体配置 - 前端管理后台实现登录、仪表盘、积分规则、礼品、订单、会员等页面 - 集成shadcn-vue UI组件库 - 添加前后端功能文档和截图
383 lines
15 KiB
Markdown
383 lines
15 KiB
Markdown
## 前端管理后台功能概览
|
||
|
||
> 本文档说明管理后台前端(Fengling.Backend.Admin)的技术实现与功能模块,便于后续开发和前后端联调。
|
||
> 最后更新时间:2026-02-11
|
||
|
||
---
|
||
|
||
## 一、整体技术栈与架构
|
||
|
||
### 1.1 技术栈
|
||
- **Vue 3.5** - Composition API + `<script setup>` 语法
|
||
- **TypeScript 5.9** - 强类型,启用 `erasableSyntaxOnly`
|
||
- **Vite 7.3** - 构建工具,开发服务器端口 3000
|
||
- **pnpm** - 包管理器
|
||
- **shadcn-vue** - UI 组件库(基于 Radix Vue + Tailwind CSS v4)
|
||
- **Vue Router 4** - 路由管理,支持路由守卫
|
||
- **Pinia 3** - 状态管理
|
||
- **Axios** - HTTP 客户端,含拦截器
|
||
- **lucide-vue-next** - 图标库
|
||
- **vue-sonner** - Toast 消息提示
|
||
|
||
### 1.2 架构风格
|
||
- **模块化目录结构**:按功能模块组织页面、API、类型
|
||
- **API 服务层**:每个后端模块对应一个 `api/*.ts` 文件,统一解包 `ResponseData<T>`
|
||
- **类型安全**:所有后端 DTO 在 `types/` 中有对应 TypeScript 接口
|
||
- **路由懒加载**:所有页面组件使用 `() => import()` 动态导入
|
||
- **Mock 认证**:当前使用模拟 Token,后端 JWT 完善后可无缝切换
|
||
|
||
---
|
||
|
||
## 二、项目结构
|
||
|
||
```
|
||
Frontend/Fengling.Backend.Admin/
|
||
├── src/
|
||
│ ├── api/ # API 服务层
|
||
│ │ ├── client.ts # Axios 实例 + 请求/响应拦截器
|
||
│ │ ├── gifts.ts # 礼品管理 API(7 个函数)
|
||
│ │ ├── orders.ts # 订单管理 API(5 个函数)
|
||
│ │ ├── marketing-codes.ts # 营销码 API
|
||
│ │ ├── points-rules.ts # 积分规则 API
|
||
│ │ └── members.ts # 会员查询 API
|
||
│ ├── components/
|
||
│ │ ├── layout/ # 布局组件
|
||
│ │ │ ├── AdminLayout.vue # 主布局(侧边栏 + Header + 内容区)
|
||
│ │ │ ├── Sidebar.vue # 左侧导航菜单
|
||
│ │ │ └── Header.vue # 顶部面包屑导航
|
||
│ │ └── ui/ # shadcn-vue 组件(20+ 组件)
|
||
│ ├── lib/
|
||
│ │ ├── utils.ts # cn() class 合并工具
|
||
│ │ └── constants.ts # formatDate, truncateId, copyToClipboard 等工具函数
|
||
│ ├── pages/ # 页面组件(9 个页面)
|
||
│ │ ├── auth/Login.vue
|
||
│ │ ├── dashboard/Dashboard.vue
|
||
│ │ ├── gifts/GiftList.vue, GiftForm.vue
|
||
│ │ ├── orders/OrderList.vue, OrderDetail.vue
|
||
│ │ ├── marketing-codes/MarketingCodes.vue
|
||
│ │ ├── points-rules/PointsRules.vue
|
||
│ │ └── members/MemberSearch.vue
|
||
│ ├── router/index.ts # 路由配置 + 认证守卫
|
||
│ ├── stores/auth.ts # Pinia 认证状态管理
|
||
│ ├── types/ # TypeScript 类型定义(7 个文件)
|
||
│ │ ├── api.ts, enums.ts, gift.ts, order.ts
|
||
│ │ ├── member.ts, marketing-code.ts, points-rule.ts
|
||
│ ├── App.vue # 根组件(RouterView + Toaster)
|
||
│ ├── main.ts # 应用入口(Pinia + Router)
|
||
│ └── style.css # Tailwind CSS + CSS 变量主题
|
||
├── .env.development # 开发环境变量
|
||
├── .env.production # 生产环境变量
|
||
├── components.json # shadcn-vue 配置
|
||
├── vite.config.ts # Vite 配置(Tailwind 插件 + 路径别名 + API 代理)
|
||
└── tsconfig.json / tsconfig.app.json
|
||
```
|
||
|
||
---
|
||
|
||
## 三、环境配置
|
||
|
||
### 3.1 环境变量
|
||
|
||
| 变量 | 开发环境 | 说明 |
|
||
|------|---------|------|
|
||
| `VITE_API_BASE_URL` | `http://localhost:5511` | 后端 API 基础地址 |
|
||
| `VITE_APP_TITLE` | `Fengling 管理后台` | 应用标题 |
|
||
|
||
### 3.2 Vite 代理
|
||
|
||
开发模式下,所有 `/api` 请求通过 Vite proxy 代理到后端 `http://localhost:5511`,无需处理 CORS。
|
||
|
||
### 3.3 运行命令
|
||
|
||
```bash
|
||
cd Frontend/Fengling.Backend.Admin
|
||
pnpm install # 安装依赖
|
||
pnpm dev # 启动开发服务器 → http://localhost:3000
|
||
pnpm build # 生产构建(vue-tsc 类型检查 + vite build)
|
||
pnpm preview # 预览生产构建
|
||
```
|
||
|
||
---
|
||
|
||
## 四、认证与路由
|
||
|
||
### 4.1 认证机制(Mock)
|
||
|
||
当前后端 JWT 认证尚未完全实现,前端采用 Mock Token 方式:
|
||
|
||
- **登录**:输入任意用户名密码,生成 `mock-admin-token-{username}-{timestamp}` 存入 `localStorage`
|
||
- **Token 注入**:Axios 请求拦截器自动从 `localStorage` 读取 `admin_token` 并添加 `Authorization: Bearer {token}` 头
|
||
- **401 处理**:响应拦截器检测到 401 时自动清除 Token 并跳转登录页
|
||
- **切换真实认证**:修改 `stores/auth.ts` 的 `login()` 方法调用后端登录 API,返回真实 JWT 即可
|
||
|
||
### 4.2 路由结构
|
||
|
||
| 路径 | 页面 | 说明 | 认证 |
|
||
|------|------|------|------|
|
||
| `/login` | Login.vue | 管理员登录 | 否 |
|
||
| `/dashboard` | Dashboard.vue | 仪表盘 | 是 |
|
||
| `/marketing-codes` | MarketingCodes.vue | 营销码管理 | 是 |
|
||
| `/gifts` | GiftList.vue | 礼品列表 | 是 |
|
||
| `/gifts/create` | GiftForm.vue | 创建礼品 | 是 |
|
||
| `/gifts/edit/:id` | GiftForm.vue | 编辑礼品 | 是 |
|
||
| `/orders` | OrderList.vue | 兑换订单列表 | 是 |
|
||
| `/orders/:id` | OrderDetail.vue | 订单详情 | 是 |
|
||
| `/points-rules` | PointsRules.vue | 积分规则管理 | 是 |
|
||
| `/members` | MemberSearch.vue | 会员查询 | 是 |
|
||
|
||
### 4.3 路由守卫
|
||
|
||
```
|
||
beforeEach:
|
||
未登录 + 访问受保护路由 → 重定向 /login
|
||
已登录 + 访问 /login → 重定向 /dashboard
|
||
```
|
||
|
||
---
|
||
|
||
## 五、API 服务层
|
||
|
||
### 5.1 Axios 客户端配置 (`api/client.ts`)
|
||
|
||
- **baseURL**:从 `VITE_API_BASE_URL` 环境变量读取
|
||
- **超时**:15 秒
|
||
- **请求拦截器**:自动附加 Bearer Token
|
||
- **响应拦截器**:
|
||
- 检查 `ResponseData.success` 字段,失败时 Toast 提示并 reject
|
||
- 401 错误清除 Token 跳转登录
|
||
- 网络错误友好提示
|
||
|
||
### 5.2 API 模块与后端端点对照
|
||
|
||
#### 礼品管理 (`api/gifts.ts`)
|
||
|
||
| 前端函数 | HTTP 方法 | 后端端点 |
|
||
|---------|----------|---------|
|
||
| `getGifts()` | GET | `/api/admin/gifts` |
|
||
| `getGiftById(id)` | GET | `/api/admin/gifts/{GiftId}` |
|
||
| `createGift(data)` | POST | `/api/admin/gifts` |
|
||
| `updateGift(id, data)` | PUT | `/api/admin/gifts/{GiftId}` |
|
||
| `putOnShelf(id)` | POST | `/api/admin/gifts/{GiftId}/putonshelf` |
|
||
| `putOffShelf(id)` | POST | `/api/admin/gifts/{GiftId}/putoffshelf` |
|
||
| `addGiftStock(id, quantity)` | POST | `/api/admin/gifts/{GiftId}/addstock` |
|
||
|
||
#### 订单管理 (`api/orders.ts`)
|
||
|
||
| 前端函数 | HTTP 方法 | 后端端点 |
|
||
|---------|----------|---------|
|
||
| `getOrders()` | GET | `/api/admin/redemption-orders` |
|
||
| `getOrderById(id)` | GET | `/api/admin/redemption-orders/{OrderId}` |
|
||
| `dispatchOrder(data)` | POST | `/api/admin/redemption-orders/{OrderId}/dispatch` |
|
||
| `completeOrder(orderId)` | POST | `/api/admin/redemption-orders/{OrderId}/complete` |
|
||
| `cancelOrder(data)` | POST | `/api/admin/redemption-orders/{OrderId}/cancel` |
|
||
|
||
#### 营销码管理 (`api/marketing-codes.ts`)
|
||
|
||
| 前端函数 | HTTP 方法 | 后端端点 |
|
||
|---------|----------|---------|
|
||
| `generateMarketingCodes(data)` | POST | `/api/admin/marketing-codes/generate` |
|
||
|
||
#### 积分规则 (`api/points-rules.ts`)
|
||
|
||
| 前端函数 | HTTP 方法 | 后端端点 |
|
||
|---------|----------|---------|
|
||
| `createPointsRule(data)` | POST | `/api/admin/points-rules` |
|
||
|
||
#### 会员查询 (`api/members.ts`)
|
||
|
||
| 前端函数 | HTTP 方法 | 后端端点 |
|
||
|---------|----------|---------|
|
||
| `getMemberById(memberId)` | GET | `/api/members/{MemberId}` |
|
||
|
||
---
|
||
|
||
## 六、类型定义
|
||
|
||
### 6.1 统一响应格式 (`types/api.ts`)
|
||
|
||
```typescript
|
||
interface ResponseData<T> {
|
||
success: boolean
|
||
code: number
|
||
message: string
|
||
data: T
|
||
}
|
||
```
|
||
|
||
### 6.2 枚举常量 (`types/enums.ts`)
|
||
|
||
由于 TypeScript `erasableSyntaxOnly` 限制,使用 `const as const` 模式定义枚举:
|
||
|
||
```typescript
|
||
// 礼品类型
|
||
GiftType.Physical = 1 // 实物
|
||
GiftType.Virtual = 2 // 虚拟
|
||
GiftType.Product = 3 // 自有产品
|
||
|
||
// 订单状态
|
||
OrderStatus.Pending = 1 // 待处理
|
||
OrderStatus.Dispatched = 2 // 已发货
|
||
OrderStatus.Delivered = 3 // 已送达
|
||
OrderStatus.Completed = 4 // 已完成
|
||
OrderStatus.Cancelled = 5 // 已取消
|
||
|
||
// 积分规则类型
|
||
PointsRuleType.Product = 1 // 产品规则
|
||
PointsRuleType.Time = 2 // 时间规则
|
||
PointsRuleType.MemberLevel = 3 // 会员等级规则
|
||
```
|
||
|
||
### 6.3 核心 DTO 类型
|
||
|
||
| 文件 | 接口 | 对应后端 DTO |
|
||
|------|------|-------------|
|
||
| `gift.ts` | `GiftDto` | 礼品列表/详情数据 |
|
||
| `gift.ts` | `CreateGiftRequest` | 创建礼品请求体 |
|
||
| `gift.ts` | `UpdateGiftRequest` | 更新礼品请求体 |
|
||
| `order.ts` | `RedemptionOrderDto` | 订单列表/详情数据 |
|
||
| `order.ts` | `RedemptionOrderAddressDto` | 收货地址 |
|
||
| `order.ts` | `DispatchOrderRequest` | 发货请求体 |
|
||
| `order.ts` | `CancelOrderRequest` | 取消订单请求体 |
|
||
| `member.ts` | `MemberDto` | 会员信息 |
|
||
| `marketing-code.ts` | `GenerateMarketingCodesRequest/Response` | 生成营销码请求/响应 |
|
||
| `points-rule.ts` | `CreatePointsRuleRequest/Response` | 创建积分规则请求/响应 |
|
||
|
||
---
|
||
|
||
## 七、页面功能详情
|
||
|
||
### 7.1 登录页 (`/login`)
|
||
- 居中卡片式表单,用户名 + 密码
|
||
- Mock 认证,成功后跳转仪表盘
|
||
- 表单验证:用户名和密码不为空
|
||
|
||
### 7.2 仪表盘 (`/dashboard`)
|
||
- **统计卡片**(4 个):总礼品数 / 待处理订单 / 已上架礼品 / 已完成订单
|
||
- **近期订单表**:最新 5 条订单,显示订单号、礼品名、状态 Badge、时间
|
||
- **库存预警表**:可用库存 < 10 的上架礼品,低库存红色高亮
|
||
- 数据来源:并行调用 `getGifts()` + `getOrders()` 计算统计
|
||
|
||
### 7.3 礼品列表 (`/gifts`)
|
||
- **筛选栏**:礼品类型 Select(全部/实物/虚拟/产品)+ 上架状态 Select(全部/已上架/未上架)
|
||
- **数据表格**:名称、类型 Badge、所需积分、总库存、可用库存(低库存高亮)、上架 Switch、时间、操作列
|
||
- **操作**:
|
||
- 编辑按钮 → 跳转编辑页
|
||
- 上下架 Switch → 调用 `putOnShelf/putOffShelf` + Toast 反馈
|
||
- 增加库存按钮 → Dialog 输入数量 → 调用 `addGiftStock`
|
||
- **创建礼品按钮** → 跳转创建页
|
||
|
||
### 7.4 礼品创建/编辑 (`/gifts/create` | `/gifts/edit/:id`)
|
||
- **表单字段**:名称、类型 Select(编辑时禁用)、描述 Textarea、图片 URL(含预览)、所需积分、总库存(编辑时禁用)、每人限兑
|
||
- **表单验证**:必填字段非空、积分/库存为正数
|
||
- **模式判断**:通过 `route.params.id` 区分创建/编辑,编辑时自动加载礼品数据
|
||
|
||
### 7.5 订单列表 (`/orders`)
|
||
- **筛选**:订单状态 Select(全部/待处理/已发货/已送达/已完成/已取消)
|
||
- **数据表格**:订单号、会员 ID(截短)、礼品名、数量、消耗积分、状态 Badge、时间、操作列
|
||
- **操作**(根据状态动态显示):
|
||
- 待处理 → 发货按钮(Dialog 输入物流单号)、取消按钮
|
||
- 已发货/已送达 → 完成按钮、取消按钮
|
||
- 所有状态 → 详情按钮
|
||
- **Dialog 交互**:发货需输入物流单号(可选)、取消需输入原因(必填)
|
||
|
||
### 7.6 订单详情 (`/orders/:id`)
|
||
- **订单信息卡片**:订单号、状态大 Badge、创建/更新时间、取消原因(如有)
|
||
- **礼品信息卡片**:礼品名、类型 Badge、数量、消耗积分
|
||
- **收货地址卡片**(仅实物):收货人、电话、地址、物流单号
|
||
- **操作按钮**:根据状态显示发货/完成/取消按钮 + 返回列表按钮
|
||
|
||
### 7.7 营销码管理 (`/marketing-codes`)
|
||
- **生成表单**:批次号、产品 ID、产品名称、生成数量(1-10000)、过期时间(可选)
|
||
- **生成结果**:显示批次号和数量,Table 列出所有营销码(等宽字体)
|
||
- **操作**:单个复制按钮、复制全部按钮、导出 CSV 按钮
|
||
|
||
### 7.8 积分规则管理 (`/points-rules`)
|
||
- **创建表单**:规则名称、规则类型 Select、积分值、奖励倍数(默认 1.0)、开始/结束时间
|
||
- **动态条件字段**:
|
||
- 产品规则 → 显示产品 ID + 品类 ID 输入框
|
||
- 会员等级规则 → 显示会员等级编码输入框
|
||
- 时间规则 → 无额外字段
|
||
- 创建成功后自动清空表单
|
||
|
||
### 7.9 会员查询 (`/members`)
|
||
- **搜索区域**:会员 ID 输入框(GUID 格式)+ 查询按钮
|
||
- **结果展示**(2x2 网格):
|
||
- 基本信息:ID、手机号、昵称
|
||
- 等级信息:等级编码、等级名称 Badge
|
||
- 积分信息:累计总积分、可用积分(大号字体)
|
||
- 账户状态:正常/禁用 Badge、注册时间
|
||
|
||
---
|
||
|
||
## 八、UI 组件使用
|
||
|
||
### 8.1 已安装的 shadcn-vue 组件
|
||
|
||
| 组件 | 用途 |
|
||
|------|------|
|
||
| Button | 操作按钮 |
|
||
| Input | 文本输入 |
|
||
| Textarea | 多行文本 |
|
||
| Label | 表单标签 |
|
||
| Select | 下拉选择(筛选器、类型选择) |
|
||
| Table | 数据表格 |
|
||
| Card | 卡片容器 |
|
||
| Dialog | 对话框(发货/取消/库存) |
|
||
| Badge | 状态标签 |
|
||
| Switch | 开关(上下架) |
|
||
| Tabs | 标签页 |
|
||
| Separator | 分隔线 |
|
||
| Avatar | 头像 |
|
||
| Breadcrumb | 面包屑导航 |
|
||
| Scroll Area | 滚动区域 |
|
||
| Sheet | 侧边抽屉 |
|
||
| Dropdown Menu | 下拉菜单 |
|
||
| Popover | 弹出框 |
|
||
| Tooltip | 工具提示 |
|
||
| Sonner | Toast 消息 |
|
||
|
||
### 8.2 添加新 shadcn-vue 组件
|
||
|
||
```bash
|
||
cd Frontend/Fengling.Backend.Admin
|
||
npx shadcn-vue@latest add [组件名]
|
||
```
|
||
|
||
---
|
||
|
||
## 九、当前状态与后续建议
|
||
|
||
### 9.1 当前状态
|
||
|
||
**已完成**:
|
||
- 项目基础架构搭建(Vite + Vue 3 + TypeScript + shadcn-vue)
|
||
- 全部 9 个管理页面的 UI 与交互逻辑
|
||
- 覆盖后端全部 15 个管理端 API 端点
|
||
- 路由守卫 + Mock 认证
|
||
- `pnpm build` 通过,无类型错误
|
||
- 生产构建产物约 155KB JS (gzip ~57KB)
|
||
|
||
**已知限制**:
|
||
- 认证为 Mock 模式,需后端 JWT 完善后对接
|
||
- 列表页无分页,需后端添加分页接口后实现
|
||
- 表单验证为手动实现,未使用 VeeValidate 等验证库
|
||
|
||
### 9.2 后续建议
|
||
|
||
#### 对接真实认证
|
||
1. 修改 `stores/auth.ts` 的 `login()` 方法,调用后端登录 API
|
||
2. 保存返回的 JWT Token 到 localStorage
|
||
3. 无需修改 `api/client.ts`(拦截器已适配 Bearer Token 模式)
|
||
|
||
#### 功能增强
|
||
- **分页**:后端添加分页支持后,在列表页添加 Pagination 组件
|
||
- **积分规则列表**:后端暴露查询端点后,在积分规则页添加已有规则列表
|
||
- **营销码查询**:后端添加查询端点后,支持按批次号查看历史生成记录
|
||
- **数据导出**:为订单列表、礼品列表添加 Excel/CSV 导出功能
|
||
- **仪表盘图表**:引入 ECharts/Chart.js 添加趋势图表
|
||
|
||
#### 技术优化
|
||
- 引入 VeeValidate 进行表单验证
|
||
- 大数据量场景引入虚拟滚动
|
||
- 添加 Vitest 单元测试
|