diff --git a/changelogs/2026-03/2026-03-18_dashboard_module.md b/changelogs/2026-03/2026-03-18_dashboard_module.md new file mode 100644 index 0000000..6f2e23c --- /dev/null +++ b/changelogs/2026-03/2026-03-18_dashboard_module.md @@ -0,0 +1,853 @@ +# 管理端首页工作台模块 - 前端对接指南 + +> **日期**: 2026-03-18 +> **后端状态**: ✅ 已完成,可直接对接 +> **页面路由**: `/dashboard`(首页工作台) +> **核心特性**: 同一个接口,按登录角色自动返回不同的工作台数据 + +--- + +## 页面功能说明 + +管理端首页工作台根据当前登录管理员的**角色**自动展示不同内容。前端只需调用同一个接口 `GET /admin/profile/dashboard`,后端根据角色路由到对应的工作台数据。 + +**支持的角色及工作台类型**: + +| 角色 role_key | 角色中文名 | 工作台类型 | 数据特点 | +|---------------|-----------|-----------|---------| +| `SUPER_ADMIN` | 超级管理员 | 全局管理台 | 全平台数据概览 + 团队排行 + 用户/产品统计 | +| `ADMIN` | 管理员 | 全局管理台 | 同超级管理员 | +| `CUSTOMIZER` | 定制师 | 个人工作台 | 个人业绩 + 转化漏斗 + 快捷入口 + 评价/客户/产品统计 | +| `ROOM_MANAGER` | 房务管理员 | 房务工作台 | 酒店/房型统计 + 待安排住宿 + 即将入住 | +| `VEHICLE_MANAGER` | 车务管理员 | 车务工作台 | 车辆/车型统计 + 待安排车辆 + 即将用车 | +| `FINANCE` | 财务 | 财务工作台 | 收支概览 + 退款待审 + 尾款逾期 + 收支趋势 | +| `MATERIAL_ADMIN` | 素材管理员 | 素材工作台 | 素材统计 + 分类分布 | +| 其他角色 | — | 全局管理台 | 降级使用管理员工作台 | + +--- + +## 接口清单 + +| # | 接口 | 方法 | 路径 | 说明 | +|---|------|------|------|------| +| 1 | 工作台仪表盘 | GET | `/admin/profile/dashboard` | **核心接口**,按角色返回不同数据结构 | +| 2 | 获取个人资料 | GET | `/admin/profile/me` | 工作台顶部展示用户信息 | +| 3 | 更新个人资料 | PUT | `/admin/profile/me` | 定制师编辑个人简介等 | +| 4 | 我的评价列表 | GET | `/admin/profile/reviews` | 定制师查看收到的评价(分页) | +| 5 | 我的订单列表 | GET | `/admin/profile/orders` | 定制师查看关联订单(分页) | +| 6 | 我的产品列表 | GET | `/admin/profile/products` | 定制师查看关联产品(分页) | + +> 所有接口都需要管理员登录认证(Header 传 `Authorization: Bearer {token}`)。 + +--- + +## 接口 1:工作台仪表盘(核心接口) + +**使用场景**:首页加载时调用,后端自动根据登录角色返回对应数据结构。前端根据返回的数据结构渲染不同的工作台布局。 + +``` +GET /admin/profile/dashboard?period=today +``` + +### 请求参数 + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| period | String | 否 | 时间范围,默认 `today`。可选值:`today`=今日、`week`=本周、`month`=本月 | + +> **前端判断角色**:调用 接口2 `GET /admin/profile/me` 获取 `role` 字段,用于决定渲染哪种工作台布局。 + +--- + +### 1A. 超级管理员/管理员工作台(SUPER_ADMIN / ADMIN) + +**返回类型**: `AdminDashboardVO` + +```json +{ + "code": 200, + "message": "成功", + "data": { + "overview": { + "orderCount": 15, + "orderCountDiff": 3, + "orderCountDiffRate": 0.25, + "gmv": 128000.00, + "gmvDiffRate": 0.18, + "newUserCount": 42, + "newUserCountDiffRate": 0.15, + "visitorCount": 380, + "visitorCountDiffRate": -0.05, + "period": "today" + }, + "todos": { + "totalActive": 8, + "CONFIRM_ORDER": 3, + "INSURANCE": 1, + "CONTRACT": 2, + "ARRANGE_ROOM": 1, + "ARRANGE_VEHICLE": 1, + "CONFIRM_CHECKLIST": 0, + "PROCESS_REFUND": 0, + "pendingRefund": 2, + "upcomingDeparture": 5, + "overdueBalance": 1 + }, + "trend": [ + { "date": "2026-03-12", "orderCount": 10, "gmv": 85000.00 }, + { "date": "2026-03-13", "orderCount": 8, "gmv": 62000.00 } + ], + "ranking": [ + { "customizerId": "2025607151170445301", "customizerName": "李明", "gmv": 320000.00, "orderCount": 28 }, + { "customizerId": "2025607151170445302", "customizerName": "张丽", "gmv": 285000.00, "orderCount": 22 } + ], + "upcomingTrips": [ + { + "orderId": "2025607151170445401", + "orderNo": "HL20260318001", + "departureDate": "2026-03-20", + "productName": "呼伦贝尔5日深度游", + "headcount": 4, + "status": "PAID", + "statusLabel": "已全额支付" + } + ], + "totalMiniAppUsers": 1580, + "totalAdmins": 12, + "totalProducts": 45, + "publishedProducts": 28 + } +} +``` + +#### 响应字段 + +| 字段 | 类型 | 说明 | +|------|------|------| +| **overview** | Object | 数据概览卡片 | +| overview.orderCount | Long | 当期订单数 | +| overview.orderCountDiff | Long | 与前一期订单数差值(正=增长,负=下降) | +| overview.orderCountDiffRate | BigDecimal | 订单数环比增长率(小数,0.25=25%) | +| overview.gmv | BigDecimal | 当期GMV(成交金额,元) | +| overview.gmvDiffRate | BigDecimal | GMV环比增长率 | +| overview.newUserCount | Long | 当期新增C端用户数 | +| overview.newUserCountDiffRate | BigDecimal | 新增用户环比增长率 | +| overview.visitorCount | Long | 当期活跃C端用户数 | +| overview.visitorCountDiffRate | BigDecimal | 活跃用户环比增长率 | +| overview.period | String | 当前时间范围(today/week/month) | +| **todos** | Map | 待办汇总(key→数量) | +| todos.totalActive | Integer | 活跃待办总数 | +| todos.CONFIRM_ORDER | Integer | 待确认订单数 | +| todos.INSURANCE | Integer | 待配置保险数 | +| todos.CONTRACT | Integer | 待签合同数 | +| todos.ARRANGE_ROOM | Integer | 待安排住宿数 | +| todos.ARRANGE_VEHICLE | Integer | 待安排车辆数 | +| todos.CONFIRM_CHECKLIST | Integer | 待确认清单数 | +| todos.PROCESS_REFUND | Integer | 待处理退款数 | +| todos.pendingRefund | Integer | 退款审核待处理 | +| todos.upcomingDeparture | Integer | 即将出发订单数 | +| todos.overdueBalance | Integer | 尾款逾期数 | +| **trend** | List | 数据趋势(默认7天,每天一条) | +| trend[].date | String | 日期(yyyy-MM-dd) | +| trend[].orderCount | Integer | 当日订单数 | +| trend[].gmv | BigDecimal | 当日GMV | +| **ranking** | List | 定制师业绩排行(当月) | +| ranking[].customizerId | String | 定制师ID(雪花ID字符串) | +| ranking[].customizerName | String | 定制师姓名 | +| ranking[].gmv | BigDecimal | 当月GMV | +| ranking[].orderCount | Integer | 当月订单数 | +| **upcomingTrips** | List | 即将出行列表(最多5条) | +| upcomingTrips[].orderId | String | 订单ID | +| upcomingTrips[].orderNo | String | 订单编号 | +| upcomingTrips[].departureDate | String | 出发日期(yyyy-MM-dd) | +| upcomingTrips[].productName | String | 产品名称 | +| upcomingTrips[].headcount | Integer | 出行人数 | +| upcomingTrips[].status | String | 订单状态(关联字典 `order_status`) | +| upcomingTrips[].statusLabel | String | 订单状态中文 | +| **totalMiniAppUsers** | Integer | C端小程序用户总数 | +| **totalAdmins** | Integer | 管理员总数 | +| **totalProducts** | Integer | 全局产品总数 | +| **publishedProducts** | Integer | 已上架产品数 | + +--- + +### 1B. 定制师工作台(CUSTOMIZER) + +**返回类型**: `DesignerDashboardVO` + +```json +{ + "code": 200, + "message": "成功", + "data": { + "overview": { + "orderCount": 5, + "orderCountDiff": 2, + "gmv": 45000.00, + "gmvDiffRate": 0.30, + "period": "today" + }, + "todos": { + "totalActive": 4, + "CONFIRM_ORDER": 2, + "INSURANCE": 1, + "CONTRACT": 1, + "ARRANGE_ROOM": 0, + "ARRANGE_VEHICLE": 0, + "CONFIRM_CHECKLIST": 0, + "PROCESS_REFUND": 0, + "pendingRefund": 1, + "upcomingDeparture": 3, + "overdueBalance": 0 + }, + "shortcuts": [ + { "name": "新建产品", "icon": "product-add", "path": "/product/create" }, + { "name": "我的订单", "icon": "order", "path": "/admin/profile/orders" }, + { "name": "我的评价", "icon": "review", "path": "/admin/profile/reviews" }, + { "name": "素材库", "icon": "material", "path": "/material/list" } + ], + "trend": [ + { "date": "2026-03-12", "orderCount": 3, "gmv": 28000.00 }, + { "date": "2026-03-13", "orderCount": 2, "gmv": 18000.00 } + ], + "funnel": { + "ordered": 20, + "paid": 16, + "departed": 12, + "completed": 10 + }, + "upcomingTrips": [ + { + "orderId": "2025607151170445401", + "orderNo": "HL20260318001", + "departureDate": "2026-03-20", + "productName": "呼伦贝尔5日深度游", + "headcount": 4, + "status": "PAID", + "statusLabel": "已全额支付" + } + ], + "ranking": [ + { "customizerId": "2025607151170445301", "customizerName": "李明", "gmv": 320000.00, "orderCount": 28 } + ], + "calendarEvents": [ + { "date": "2026-03-20", "type": "departure", "label": "出团", "count": 2 }, + { "date": "2026-03-25", "type": "return", "label": "回程", "count": 1 } + ], + "reviewStats": { + "totalReviews": 86, + "averageRating": 4.7, + "goodRate": 92.5 + }, + "productStats": { + "totalProducts": 12, + "publishedProducts": 8 + }, + "customerStats": { + "customerAddCount": 5, + "customerLossCount": 1 + } + } +} +``` + +#### 响应字段 + +| 字段 | 类型 | 说明 | +|------|------|------| +| **overview** | Object | 个人数据概览 | +| overview.orderCount | Long | 我的当期订单数 | +| overview.orderCountDiff | Long | 与前一期差值 | +| overview.gmv | BigDecimal | 我的当期GMV(元) | +| overview.gmvDiffRate | BigDecimal | GMV环比增长率 | +| overview.period | String | 当前时间范围 | +| **todos** | Map | 我的待办汇总(结构同管理员,但数据只包含自己的) | +| **shortcuts** | List | 快捷入口列表 | +| shortcuts[].name | String | 入口名称(中文) | +| shortcuts[].icon | String | 图标标识(前端自行映射图标组件) | +| shortcuts[].path | String | 跳转路径 | +| **trend** | List | 我的数据趋势(7天) | +| trend[].date | String | 日期 | +| trend[].orderCount | Integer | 当日订单数 | +| trend[].gmv | BigDecimal | 当日GMV | +| **funnel** | Map | 转化漏斗(当月) | +| funnel.ordered | Integer | 下单数 | +| funnel.paid | Integer | 已支付数 | +| funnel.departed | Integer | 已出行数(含TRAVELLING+COMPLETED) | +| funnel.completed | Integer | 已完成数 | +| **upcomingTrips** | List | 我的即将出行(最多5条,结构同管理员) | +| **ranking** | List | 月度业绩排行(含自己的排名,用于自我定位) | +| **calendarEvents** | List | 日历事件(当月出团/回程事件) | +| calendarEvents[].date | String | 事件日期 | +| calendarEvents[].type | String | 事件类型(departure=出团, return=回程) | +| calendarEvents[].label | String | 事件中文标签 | +| calendarEvents[].count | Integer | 当日事件数量 | +| **reviewStats** | Object | 评价统计 | +| reviewStats.totalReviews | Integer | 评价总数 | +| reviewStats.averageRating | BigDecimal | 平均评分(1.0~5.0) | +| reviewStats.goodRate | BigDecimal | 好评率(百分比,如92.5=92.5%) | +| **productStats** | Object | 产品统计 | +| productStats.totalProducts | Integer | 我的产品总数 | +| productStats.publishedProducts | Integer | 已上架产品数 | +| **customerStats** | Object | 客户统计 | +| customerStats.customerAddCount | Integer | 新增客户数 | +| customerStats.customerLossCount | Integer | 流失客户数 | + +--- + +### 1C. 房务管理员工作台(ROOM_MANAGER) + +**返回类型**: `HousekeepingDashboardVO` + +```json +{ + "code": 200, + "message": "成功", + "data": { + "totalHotels": 8, + "totalRoomTypes": 24, + "pendingArrangeRoom": 3, + "upcomingTrips": [ + { + "orderId": "2025607151170445401", + "orderNo": "HL20260318001", + "departureDate": "2026-03-20", + "productName": "呼伦贝尔5日深度游", + "headcount": 4, + "status": "PAID", + "statusLabel": "已全额支付" + } + ] + } +} +``` + +#### 响应字段 + +| 字段 | 类型 | 说明 | +|------|------|------| +| totalHotels | Integer | 酒店总数 | +| totalRoomTypes | Integer | 房型总数 | +| pendingArrangeRoom | Integer | 待安排住宿的订单数(红色角标提醒) | +| upcomingTrips | List | 近7天即将入住的订单列表(结构同管理员的upcomingTrips) | + +> **注意**:`period` 参数对房务工作台无效,数据始终为全局统计。 + +--- + +### 1D. 车务管理员工作台(VEHICLE_MANAGER) + +**返回类型**: `LogisticsDashboardVO` + +```json +{ + "code": 200, + "message": "成功", + "data": { + "totalVehicles": 15, + "totalVehicleModels": 6, + "pendingArrangeVehicle": 2, + "upcomingTrips": [ + { + "orderId": "2025607151170445401", + "orderNo": "HL20260318001", + "departureDate": "2026-03-20", + "productName": "呼伦贝尔5日深度游", + "headcount": 4, + "status": "PAID", + "statusLabel": "已全额支付" + } + ] + } +} +``` + +#### 响应字段 + +| 字段 | 类型 | 说明 | +|------|------|------| +| totalVehicles | Integer | 车辆总数 | +| totalVehicleModels | Integer | 车型总数 | +| pendingArrangeVehicle | Integer | 待安排车辆的订单数(红色角标提醒) | +| upcomingTrips | List | 近7天即将用车的订单列表(结构同管理员的upcomingTrips) | + +> **注意**:`period` 参数对车务工作台无效。 + +--- + +### 1E. 财务工作台(FINANCE) + +**返回类型**: `FinanceDashboardVO` + +```json +{ + "code": 200, + "message": "成功", + "data": { + "periodIncome": 128000.00, + "periodRefund": 5600.00, + "monthIncome": 890000.00, + "monthRefund": 32000.00, + "pendingRefundCount": 3, + "overdueBalanceCount": 2, + "trend": [ + { "date": "2026-02-17", "income": 35000.00, "refund": 2000.00 }, + { "date": "2026-02-18", "income": 42000.00, "refund": 1500.00 } + ] + } +} +``` + +#### 响应字段 + +| 字段 | 类型 | 说明 | +|------|------|------| +| periodIncome | BigDecimal | 当期收入(元,受period参数影响) | +| periodRefund | BigDecimal | 当期退款(元) | +| monthIncome | BigDecimal | 本月总收入(始终为本月) | +| monthRefund | BigDecimal | 本月总退款 | +| pendingRefundCount | Integer | 待审核退款申请数(红色角标) | +| overdueBalanceCount | Integer | 尾款逾期提醒数(红色角标) | +| trend | List | 收支趋势(30天,每天一条) | +| trend[].date | String | 日期 | +| trend[].income | BigDecimal | 当日收入 | +| trend[].refund | BigDecimal | 当日退款 | + +--- + +### 1F. 素材管理员工作台(MATERIAL_ADMIN) + +**返回类型**: `MaterialDashboardVO` + +```json +{ + "code": 200, + "message": "成功", + "data": { + "totalMaterials": 1280, + "monthNewCount": 56, + "totalRefCount": 3420, + "categoryCount": 12, + "categoryDistribution": [ + { "categoryName": "风景照片", "count": 450 }, + { "categoryName": "酒店图片", "count": 320 }, + { "categoryName": "活动素材", "count": 280 } + ] + } +} +``` + +#### 响应字段 + +| 字段 | 类型 | 说明 | +|------|------|------| +| totalMaterials | Integer | 素材总数 | +| monthNewCount | Integer | 本月新增素材数 | +| totalRefCount | Integer | 素材总引用次数 | +| categoryCount | Integer | 素材分类总数 | +| categoryDistribution | List | 各分类素材数量分布 | +| categoryDistribution[].categoryName | String | 分类名称 | +| categoryDistribution[].count | Integer | 该分类下素材数量 | + +> **注意**:`period` 参数对素材工作台无效。 + +--- + +## 接口 2:获取个人资料 + +**使用场景**:页面加载时获取当前用户信息,用于工作台顶部展示姓名/头像,以及判断角色决定渲染哪种工作台。 + +``` +GET /admin/profile/me +``` + +### 请求参数 + +无(从登录Token中自动获取)。 + +### 响应示例 + +```json +{ + "code": 200, + "message": "成功", + "data": { + "adminId": "2025607151170445301", + "role": "CUSTOMIZER", + "roleName": "定制师", + "name": "李明", + "avatar": "https://oss.example.com/avatar/liming.jpg", + "phone": "13800138001", + "contactQrUrl": "https://work.weixin.qq.com/qr/xxx", + "description": "10年+呼伦贝尔定制旅行专家", + "motto": "让每一次旅行都值得回忆", + "experience": 10, + "certLevel": "gold", + "certified": true, + "specialties": ["亲子游", "深度游", "摄影游"], + "serviceAreas": ["呼伦贝尔", "阿尔山", "漠河"], + "sortOrder": 1, + "isFeatured": true, + "createdAt": "2025-06-01T10:00:00", + "updatedAt": "2026-03-15T14:30:00" + } +} +``` + +### 响应字段 + +| 字段 | 类型 | 说明 | +|------|------|------| +| adminId | String | 管理员ID(雪花ID字符串) | +| role | String | 角色标识,见下方角色枚举 | +| roleName | String | 角色中文名 | +| name | String | 姓名 | +| avatar | String | 头像URL,可能为null | +| phone | String | 手机号,可能为null | +| contactQrUrl | String | 企微联系二维码URL,可能为null | +| description | String | 个人简介(**仅定制师有值**,其他角色为null) | +| motto | String | 座右铭(仅定制师) | +| experience | Integer | 从业年限(仅定制师) | +| certLevel | String | 认证等级(仅定制师):none/bronze/silver/gold/diamond | +| certified | Boolean | 是否已认证(仅定制师) | +| specialties | List\ | 擅长领域(仅定制师),如 ["亲子游","深度游"] | +| serviceAreas | List\ | 服务区域(仅定制师),如 ["呼伦贝尔","阿尔山"] | +| sortOrder | Integer | 展示排序(仅定制师) | +| isFeatured | Boolean | 是否推荐定制师(仅定制师) | +| createdAt | String | 创建时间(ISO 8601) | +| updatedAt | String | 更新时间(ISO 8601) | + +### 前端实现建议 +- 页面加载时先调此接口,拿到 `role` 后再调 `dashboard` 接口 +- 用 `role` 判断渲染哪种工作台布局(switch-case) +- 顶部显示 `name` + `avatar` + `roleName` +- 定制师额外展示认证徽章(根据 `certLevel`) + +--- + +## 接口 3:更新个人资料 + +**使用场景**:定制师编辑个人简介、擅长领域等信息。 + +``` +PUT /admin/profile/me +Content-Type: application/json +``` + +### 请求参数 + +```json +{ + "description": "10年+呼伦贝尔定制旅行专家", + "motto": "让每一次旅行都值得回忆", + "experience": 10, + "certLevel": "gold", + "certified": true, + "specialties": ["亲子游", "深度游", "摄影游"], + "serviceAreas": ["呼伦贝尔", "阿尔山", "漠河"], + "sortOrder": 1, + "isFeatured": true +} +``` + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| description | String | 否 | 个人简介,最多500字 | +| motto | String | 否 | 座右铭,最多200字 | +| experience | Integer | 否 | 从业年限(0~99) | +| certLevel | String | 否 | 认证等级:none/bronze/silver/gold/diamond | +| certified | Boolean | 否 | 是否已认证 | +| specialties | List\ | 否 | 擅长领域列表 | +| serviceAreas | List\ | 否 | 服务区域列表 | +| sortOrder | Integer | 否 | 展示排序(最小0) | +| isFeatured | Boolean | 否 | 是否推荐 | + +### 响应 + +返回更新后的 `ProfileVO`,结构同接口2。 + +--- + +## 接口 4:我的评价列表 + +**使用场景**:定制师查看客户对自己的评价,支持按好评/中评/差评筛选。 + +``` +GET /admin/profile/reviews?page=1&pageSize=20&ratingLevel=GOOD +``` + +### 请求参数 + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| page | Integer | 否 | 页码,默认1 | +| pageSize | Integer | 否 | 每页条数,默认20 | +| ratingLevel | String | 否 | 评价等级筛选,见下方枚举 | + +### 评价等级枚举(ratingLevel)— 关联字典 `rating_level` + +| 值 | 中文 | 说明 | +|----|------|------| +| `GOOD` | 好评 | 4~5星 | +| `MEDIUM` | 中评 | 3星 | +| `BAD` | 差评 | 1~2星 | + +### 响应示例 + +```json +{ + "code": 200, + "message": "成功", + "data": { + "list": [ + { + "reviewId": "2025607151170445501", + "orderId": "2025607151170445401", + "orderNo": "HL20260318001", + "productName": "呼伦贝尔5日深度游", + "userName": "张三", + "userAvatar": "https://oss.example.com/avatar/user1.jpg", + "rating": 5, + "ratingLevel": "GOOD", + "content": "定制师很专业,行程安排非常合理!", + "createdAt": "2026-03-16T14:00:00" + } + ], + "total": 86, + "page": 1, + "pageSize": 20 + } +} +``` + +--- + +## 接口 5:我的订单列表 + +**使用场景**:定制师查看自己负责的订单,支持按状态筛选和关键词搜索。 + +``` +GET /admin/profile/orders?page=1&pageSize=20&status=PAID&keyword=呼伦贝尔 +``` + +### 请求参数 + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| page | Integer | 否 | 页码,默认1 | +| pageSize | Integer | 否 | 每页条数,默认20 | +| status | String | 否 | 订单状态筛选,见下方枚举 | +| keyword | String | 否 | 搜索关键词(匹配订单号、产品名、联系人名) | + +### 订单状态枚举(status)— 关联字典 `order_status` + +| 值 | 中文 | 说明 | +|----|------|------| +| `PENDING_PAY` | 待支付 | 订单已创建,等待支付 | +| `DEPOSIT_PAID` | 已付定金 | 已支付定金 | +| `PAID` | 已全额支付 | 全额支付完成 | +| `CONFIRMED` | 已确认 | 订单已确认 | +| `PENDING_BALANCE` | 待付尾款 | 等待支付尾款 | +| `PENDING_DEPARTURE` | 待出行 | 一切就绪,等待出发 | +| `TRAVELLING` | 旅行中 | 正在旅行 | +| `COMPLETED` | 已完成 | 行程结束 | +| `AFTER_SALES` | 售后中 | 售后处理中 | +| `CANCELLED` | 已取消 | 订单已取消 | +| `REFUNDING` | 退款中 | 退款处理中 | +| `REFUNDED` | 已退款 | 退款完成 | + +### 响应示例 + +```json +{ + "code": 200, + "message": "成功", + "data": { + "list": [ + { + "orderId": "2025607151170445401", + "orderNo": "HL20260318001", + "productName": "呼伦贝尔5日深度游", + "contactName": "张三", + "contactPhone": "13800138000", + "headcount": 4, + "totalAmount": 12800.00, + "status": "PAID", + "statusLabel": "已全额支付", + "departureDate": "2026-03-20", + "createdAt": "2026-03-10T10:00:00" + } + ], + "total": 28, + "page": 1, + "pageSize": 20 + } +} +``` + +--- + +## 接口 6:我的产品列表 + +**使用场景**:定制师查看自己创建的产品,支持按状态筛选和关键词搜索。 + +``` +GET /admin/profile/products?page=1&pageSize=20&status=PUBLISHED&keyword=呼伦贝尔 +``` + +### 请求参数 + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| page | Integer | 否 | 页码,默认1 | +| pageSize | Integer | 否 | 每页条数,默认20 | +| status | String | 否 | 产品状态筛选,见下方枚举 | +| keyword | String | 否 | 搜索关键词(匹配产品名称) | + +### 产品状态枚举(status)— 关联字典 `product_status` + +| 值 | 中文 | 说明 | +|----|------|------| +| `DRAFT` | 草稿 | 未提交 | +| `PENDING_REVIEW` | 待审核 | 已提交审核 | +| `REVIEWED` | 已审核 | 审核通过 | +| `REJECTED` | 已驳回 | 审核驳回 | +| `PUBLISHED` | 已上架 | 小程序可见 | +| `UNPUBLISHED` | 已下架 | 已下架 | +| `COMPLETED` | 已完成 | 产品周期结束 | + +### 响应示例 + +```json +{ + "code": 200, + "message": "成功", + "data": { + "list": [ + { + "productId": "2025607151170445601", + "productName": "呼伦贝尔5日深度游", + "status": "PUBLISHED", + "statusLabel": "已上架", + "coverImage": "https://oss.example.com/product/cover1.jpg", + "priceRange": "3200-4800", + "orderCount": 15, + "createdAt": "2026-02-01T10:00:00" + } + ], + "total": 12, + "page": 1, + "pageSize": 20 + } +} +``` + +--- + +## 待办类型枚举 — 关联字典 `order_todo_type` + +| 值 | 中文 | 适用角色 | 说明 | +|----|------|----------|------| +| `CONFIRM_ORDER` | 确认订单 | 定制师/管理员 | 新订单需确认 | +| `INSURANCE` | 配置保险 | 定制师/管理员 | 需为订单配置保险 | +| `CONTRACT` | 签订合同 | 定制师/管理员 | 合同待签署 | +| `ARRANGE_ROOM` | 安排住宿 | 房务管理员/管理员 | 需安排酒店房间 | +| `ARRANGE_VEHICLE` | 安排车辆 | 车务管理员/管理员 | 需安排用车 | +| `CONFIRM_CHECKLIST` | 确认清单 | 定制师/管理员 | 出行清单待确认 | +| `PROCESS_REFUND` | 处理退款 | 财务/管理员 | 退款申请待处理 | + +--- + +## 角色枚举(role) + +| 值 | 中文名 | 工作台类型 | +|----|--------|-----------| +| `SUPER_ADMIN` | 超级管理员 | AdminDashboardVO | +| `ADMIN` | 管理员 | AdminDashboardVO | +| `CUSTOMIZER` | 定制师 | DesignerDashboardVO | +| `ROOM_MANAGER` | 房务管理员 | HousekeepingDashboardVO | +| `VEHICLE_MANAGER` | 车务管理员 | LogisticsDashboardVO | +| `FINANCE` | 财务 | FinanceDashboardVO | +| `MATERIAL_ADMIN` | 素材管理员 | MaterialDashboardVO | +| `OPERATOR` | 运营 | AdminDashboardVO(降级) | +| `CUSTOMER_SERVICE` | 客服 | AdminDashboardVO(降级) | + +--- + +## 前端实现建议 — 页面布局 + +### 整体架构 + +``` +┌──────────────────────────────────────────────────┐ +│ [头像] 李明 定制师 ⚙️ 编辑资料 │ ← GET /admin/profile/me +├──────────────────────────────────────────────────┤ +│ 时间范围: [今日] [本周] [本月] │ ← period 参数切换 +├──────────────────────────────────────────────────┤ +│ ┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐ │ +│ │订单 15│ │GMV 12W│ │新用户42│ │访客380│ │ ← overview 数据卡片 +│ │ +3 ▲ │ │+18% ▲ │ │+15% ▲ │ │-5% ▼ │ │ 数字+趋势箭头+百分比 +│ └───────┘ └───────┘ └───────┘ └───────┘ │ +├──────────────────────────────────────────────────┤ +│ 待办事项 │ +│ 确认订单(3) 配置保险(1) 签合同(2) │ ← todos Map +│ 安排住宿(1) 安排车辆(1) │ 数值>0 显示红色角标 +├──────────────────────────────────────────────────┤ +│ ┌──────────────────┐ ┌──────────────────┐ │ +│ │ 数据趋势(7天) │ │ 转化漏斗 │ │ ← trend + funnel +│ │ 折线图/柱状图 │ │ 漏斗图 │ │ (漏斗仅定制师有) +│ └──────────────────┘ └──────────────────┘ │ +├──────────────────────────────────────────────────┤ +│ ┌──────────────────┐ ┌──────────────────┐ │ +│ │ 即将出行(5条) │ │ 业绩排行 │ │ +│ │ 卡片列表 │ │ 排行列表 │ │ +│ └──────────────────┘ └──────────────────┘ │ +└──────────────────────────────────────────────────┘ +``` + +### 核心逻辑 + +```javascript +// 1. 获取个人资料(判断角色) +const { data: profile } = await request.get('/admin/profile/me') +const role = profile.role // "CUSTOMIZER" / "SUPER_ADMIN" / ... + +// 2. 获取工作台数据(同一接口,后端按角色返回不同结构) +const { data: dashboard } = await request.get('/admin/profile/dashboard', { + params: { period: 'today' } +}) + +// 3. 根据 role 渲染不同布局 +switch (role) { + case 'SUPER_ADMIN': + case 'ADMIN': + // 渲染全局管理台:overview + todos + trend + ranking + upcomingTrips + 统计数字 + break + case 'CUSTOMIZER': + // 渲染定制师工作台:overview + todos + shortcuts + trend + funnel + upcomingTrips + // + ranking + calendarEvents + reviewStats + productStats + customerStats + break + case 'ROOM_MANAGER': + // 渲染房务工作台:totalHotels + totalRoomTypes + pendingArrangeRoom + upcomingTrips + break + case 'VEHICLE_MANAGER': + // 渲染车务工作台:totalVehicles + totalVehicleModels + pendingArrangeVehicle + upcomingTrips + break + case 'FINANCE': + // 渲染财务工作台:periodIncome/Refund + monthIncome/Refund + pending + trend + break + case 'MATERIAL_ADMIN': + // 渲染素材工作台:totalMaterials + monthNewCount + totalRefCount + categoryDistribution + break + default: + // 降级使用管理员工作台 + break +} +``` + +### 注意事项 +- **雪花ID**:所有 ID 字段都是字符串(超过 JS Number 安全范围),用 `String` 接收 +- **金额字段**:BigDecimal 序列化为数字(非字符串),前端用 `Number` 或 `toFixed(2)` 处理 +- **增长率**:小数格式(0.25 = 25%),前端需 `×100` 再展示百分比 +- **空值安全**:部分字段可能为 null(如远程服务不可用时),做好默认值处理 +- **时间范围切换**:切换 period 时重新调用 dashboard 接口,局部刷新数据