feat(admin-frontend): 完成订阅与系统管理真实工作台
补齐订单、优惠券、主题、插件、公告与支付管理页面, 接入对应后台接口、路由入口与工具层类型定义。 同时修复套餐页开关初始化误写问题,避免浏览即触发写操作。 在订阅协议侧为 Stash 导出增加 AnyTLS 版本守卫, 未知版本或低于 3.3.0 时不再导出该协议,并补充回归测试与知识记录。
This commit is contained in:
+11
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"status": "completed",
|
||||
"completed": 6,
|
||||
"failed": 0,
|
||||
"pending": 0,
|
||||
"total": 6,
|
||||
"done": 6,
|
||||
"percent": 100,
|
||||
"current": "优惠券管理页面、弹窗与构建验证已完成,等待归档",
|
||||
"updated_at": "2026-04-24 16:28:00"
|
||||
}
|
||||
+196
@@ -0,0 +1,196 @@
|
||||
# 变更提案: admin-frontend-coupon-management
|
||||
|
||||
## 元信息
|
||||
```yaml
|
||||
类型: 新功能
|
||||
方案类型: implementation
|
||||
优先级: P1
|
||||
状态: 执行中
|
||||
创建: 2026-04-24
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 1. 需求
|
||||
|
||||
### 背景
|
||||
当前 `admin-frontend` 已完成仪表盘、用户管理、节点管理、套餐管理与系统配置,但“订阅管理”分组下的“优惠券管理”仍是禁用占位。用户本轮明确要求参考 `apple/DESIGN.md`、项目级 `.helloagents/DESIGN.md` 与提供的两张参考图,继续补完真正可用的优惠券管理页面,包括列表工作台与新增/编辑弹窗。
|
||||
|
||||
### 目标
|
||||
- 开放侧边栏中的“优惠券管理”入口,并接入真实页面与路由。
|
||||
- 基于现有 Laravel `coupon/*` 接口,完成优惠券列表、搜索、类型筛选、启停、删除、新增与编辑。
|
||||
- 页面视觉延续当前 Apple 化后台,尽量还原参考图中的黑白结构、紧凑表格与表单弹窗。
|
||||
|
||||
### 约束条件
|
||||
```yaml
|
||||
技术约束: 继续使用 Vue3 + TypeScript + Element Plus + Vite,不引入额外状态管理或重型日期/富文本依赖
|
||||
业务约束: 后端接口仅使用现有 `/coupon/fetch` `/coupon/generate` `/coupon/update` `/coupon/drop`,不改 Laravel API
|
||||
数据约束: 套餐限制项沿用现有 `/plan/fetch` 返回结果,优惠券周期限制遵循后端 legacy period 键值
|
||||
视觉约束: 遵循 `apple/DESIGN.md` 与 `.helloagents/DESIGN.md`,保持与仪表盘/套餐管理同一视觉家族
|
||||
```
|
||||
|
||||
### 验收标准
|
||||
- [ ] 左侧“订阅管理”分组中的“优惠券管理”由禁用态切换为真实可点击入口,并进入独立页面。
|
||||
- [ ] 优惠券管理页支持真实数据读取、关键字搜索、类型筛选、本地分页、启用开关、编辑和删除。
|
||||
- [ ] “添加优惠券 / 编辑优惠券”弹窗支持名称、批量生成数量、自定义优惠码、类型和值、有效期、总使用次数、每人使用次数、指定周期与指定订阅。
|
||||
- [ ] 页面中的类型标签、剩余次数、每人限制、有效期与过期提示可正确展示,并与后端字段含义一致。
|
||||
- [ ] `admin-frontend` 构建通过,且知识库同步反映“优惠券管理”已从占位入口升级为真实页面。
|
||||
|
||||
---
|
||||
|
||||
## 2. 方案
|
||||
|
||||
### 技术方案
|
||||
1. 扩展 `src/types/api.d.ts` 与 `src/api/admin.ts`,新增优惠券列表项、保存载荷、分页查询与计划选项的类型、请求封装。
|
||||
2. 新增 `src/utils/coupons.ts`,集中处理优惠券类型标签、legacy period 选项、时间范围换算、表单默认值、列表本地过滤与过期文案。
|
||||
3. 新增 `src/views/subscriptions/CouponsView.vue` 与 `CouponEditorDialog.vue`:
|
||||
- `CouponsView` 负责黑色首屏、工具条、表格、分页、行内开关与操作按钮。
|
||||
- `CouponEditorDialog` 负责新增/编辑表单、指定周期/订阅、时间范围和数值字段校验。
|
||||
4. 在 `AdminLayout.vue` 与 `router/index.ts` 中启用“优惠券管理”菜单与 `/subscriptions/coupons` 路由,同时保持“订单管理 / 礼品卡管理”为未完成状态。
|
||||
|
||||
### 影响范围
|
||||
```yaml
|
||||
涉及模块:
|
||||
- admin-frontend/src/layouts: 开放优惠券菜单入口
|
||||
- admin-frontend/src/router: 新增优惠券管理路由
|
||||
- admin-frontend/src/api: 新增 coupon 接口封装
|
||||
- admin-frontend/src/types: 新增优惠券类型定义
|
||||
- admin-frontend/src/utils: 新增优惠券数据转换与展示逻辑
|
||||
- admin-frontend/src/views/subscriptions: 新增优惠券页面、弹窗与样式
|
||||
预计变更文件: 7-9
|
||||
```
|
||||
|
||||
### 风险评估
|
||||
| 风险 | 等级 | 应对 |
|
||||
|------|------|------|
|
||||
| `/coupon/fetch` 的服务端筛选能力有限,关键字无法同时覆盖名称与券码 | 中 | 前端优先一次拉取合理数量后做本地搜索与分页,避免错误的 AND 过滤 |
|
||||
| 编辑接口复用 `/coupon/generate`,字段与新增表单共用,空值和 legacy period 容易提交错误 | 中 | 在 `utils/coupons.ts` 中统一序列化,空数组转 `undefined`,时间统一转 Unix 秒 |
|
||||
| 参考图包含较丰富的表格状态与表单布局,若实现不克制容易脱离既有后台风格 | 中 | 复用现有 Apple Admin token、表格与弹窗风格,不额外引入第二套后台皮肤 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 技术设计(可选)
|
||||
|
||||
### 架构设计
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[CouponsView] --> B[admin.ts coupon 接口]
|
||||
A --> C[coupons.ts 展示/序列化工具]
|
||||
A --> D[CouponEditorDialog]
|
||||
D --> B
|
||||
D --> C
|
||||
D --> E[getPlans]
|
||||
```
|
||||
|
||||
### API设计
|
||||
#### GET /coupon/fetch
|
||||
- **请求**: `{ current, pageSize }`
|
||||
- **响应**: `{ total, current_page, per_page, last_page, data[] }`
|
||||
|
||||
#### POST /coupon/generate
|
||||
- **请求**: `{ id?, generate_count?, name, code?, type, value, started_at, ended_at, limit_use?, limit_use_with_user?, limit_plan_ids?, limit_period? }`
|
||||
- **响应**: `{ status, data }`
|
||||
|
||||
#### POST /coupon/update
|
||||
- **请求**: `{ id, show }`
|
||||
- **响应**: `{ status, data }`
|
||||
|
||||
### 数据模型
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| id | number | 优惠券 ID |
|
||||
| show | boolean | 是否启用 |
|
||||
| name | string | 优惠券名称 |
|
||||
| type | 1 \| 2 | 1=按金额优惠,2=按比例优惠 |
|
||||
| value | number | 金额分/折扣整数 |
|
||||
| code | string | 券码 |
|
||||
| limit_use | number \| null | 总可用次数 |
|
||||
| limit_use_with_user | number \| null | 每人可用次数 |
|
||||
| limit_plan_ids | string[] \| null | 限制套餐 |
|
||||
| limit_period | string[] \| null | legacy 周期键 |
|
||||
| started_at / ended_at | number | 生效时间范围(Unix 秒) |
|
||||
|
||||
---
|
||||
|
||||
## 4. 核心场景
|
||||
|
||||
### 场景: 运营创建单张优惠券
|
||||
**模块**: admin-frontend/subscriptions
|
||||
**条件**: 管理员已登录,进入 `#/subscriptions/coupons`
|
||||
**行为**: 点击“添加优惠券”,填写名称、类型、金额、有效期并提交
|
||||
**结果**: 新优惠券保存成功,列表刷新并展示新记录
|
||||
|
||||
### 场景: 运营批量生成优惠码
|
||||
**模块**: admin-frontend/subscriptions
|
||||
**条件**: 管理员在新增弹窗中填写 `generate_count`
|
||||
**行为**: 提交批量生成请求
|
||||
**结果**: 后端批量创建优惠券,前端提示成功并刷新列表
|
||||
|
||||
### 场景: 运营筛选并停用过期优惠券
|
||||
**模块**: admin-frontend/subscriptions
|
||||
**条件**: 列表中存在多种类型与已过期记录
|
||||
**行为**: 使用关键字或类型筛选找到目标记录,关闭启用开关
|
||||
**结果**: 对应优惠券 `show=false`,列表状态即时更新
|
||||
|
||||
---
|
||||
|
||||
## 5. 技术决策
|
||||
|
||||
### admin-frontend-coupon-management#D001: 优惠券列表采用真实接口 + 本地搜索/筛选/分页
|
||||
**日期**: 2026-04-24
|
||||
**状态**: ✅采纳
|
||||
**背景**: 后端 `/coupon/fetch` 支持分页,但关键字筛选以 `where like` 串联多个字段时不适合做“名称或券码”搜索。
|
||||
**选项分析**:
|
||||
| 选项 | 优点 | 缺点 |
|
||||
|------|------|------|
|
||||
| A: 完全依赖后端筛选 | 数据量更轻 | 关键字搜索能力受限,名称/券码无法自然并行匹配 |
|
||||
| B: 拉取合理数量后本地搜索/筛选/分页 | 交互更贴近参考图,搜索更灵活 | 极大数据量下效率不如纯服务端 |
|
||||
**决策**: 选择方案 B
|
||||
**理由**: 当前后台优惠券数量通常不大,本地处理可更稳定满足截图中的使用方式。
|
||||
**影响**: `CouponsView.vue`、`admin.ts`、`coupons.ts`
|
||||
|
||||
### admin-frontend-coupon-management#D002: 新增与编辑共用同一弹窗,并统一序列化到 `/coupon/generate`
|
||||
**日期**: 2026-04-24
|
||||
**状态**: ✅采纳
|
||||
**背景**: 后端没有独立的 coupon save/update 表单接口,新增与编辑都通过 `generate` 处理。
|
||||
**选项分析**:
|
||||
| 选项 | 优点 | 缺点 |
|
||||
|------|------|------|
|
||||
| A: 新增/编辑拆两套表单 | 心智更直观 | 代码重复,字段校验需要维护两份 |
|
||||
| B: 共用一个表单模型与序列化逻辑 | 结构更稳定,便于维护 | 需要额外处理编辑态初始值 |
|
||||
**决策**: 选择方案 B
|
||||
**理由**: 与当前套餐编辑抽屉模式一致,能减少重复逻辑并提高一致性。
|
||||
**影响**: `CouponEditorDialog.vue`、`utils/coupons.ts`
|
||||
|
||||
### admin-frontend-coupon-management#D003: 编辑态继续采用居中弹窗而非侧边抽屉
|
||||
**日期**: 2026-04-24
|
||||
**状态**: ✅采纳
|
||||
**背景**: 参考图中优惠券编辑器为居中对话框,且字段密度更适合聚焦式表单。
|
||||
**选项分析**:
|
||||
| 选项 | 优点 | 缺点 |
|
||||
|------|------|------|
|
||||
| A: 复用抽屉模式 | 与套餐管理统一 | 与参考图差异更大,纵向表单视觉焦点分散 |
|
||||
| B: 改为居中弹窗 | 更贴近参考图,聚焦更强 | 需要单独编写对话框布局样式 |
|
||||
**决策**: 选择方案 B
|
||||
**理由**: 这页的主要新增价值就在参考图里的“表格 + 弹窗”组合,值得贴近还原。
|
||||
**影响**: `CouponEditorDialog.vue` 及其样式
|
||||
|
||||
---
|
||||
|
||||
## 6. 成果设计
|
||||
|
||||
### 设计方向
|
||||
- **美学基调**: Apple Admin Promotions。像 Apple 后台里的运营配置页,黑色首屏负责建立业务主题,正文工作台回到白底高密度表格,让折扣配置看起来更像精密运营台而不是营销页面。
|
||||
- **记忆点**: 大标题“优惠券管理”与白色表格之间形成明显的黑白切面;弹窗内部用整齐的双列字段和轻描边区块还原截图的“精密表单感”。
|
||||
- **参考**: `apple/DESIGN.md`、`.helloagents/DESIGN.md`、用户上传的优惠券列表与添加弹窗截图
|
||||
|
||||
### 视觉要素
|
||||
- **配色**: 首屏 `#000000`,工作区 `#ffffff`,页面背景 `#f5f5f7`,强调色 `#0071e3`,过期提示用浅红底 `rgba(201, 52, 40, 0.08)`
|
||||
- **字体**: 延续项目现有系统字体栈,标题走大字号紧行高,表格与辅助信息维持更轻的运营化层级
|
||||
- **布局**: 首屏 Hero + 工具条 + 表格工作台;编辑器采用居中弹窗,字段按双列网格排布,底部操作区固定在弹窗底部
|
||||
- **动效**: 保留开关切换、弹窗开合、按钮 hover 与筛选状态切换的轻量动效,不引入额外炫技动画
|
||||
- **氛围**: 工作台继续使用克制阴影、圆角白底与 Apple 式留白,避免多余卡片堆叠
|
||||
|
||||
### 技术约束
|
||||
- **可访问性**: 交互控件保留可见焦点,状态信息不只依赖颜色,危险操作保留明确文案
|
||||
- **响应式**: 桌面优先;窄屏下 Hero、工具条和弹窗网格折叠为单列,确保表单仍可完整操作
|
||||
@@ -0,0 +1,56 @@
|
||||
# 任务清单: admin-frontend-coupon-management
|
||||
|
||||
> **@status:** completed | 2026-04-24 16:28
|
||||
|
||||
```yaml
|
||||
@feature: admin-frontend-coupon-management
|
||||
@created: 2026-04-24
|
||||
@status: completed
|
||||
@mode: R2
|
||||
```
|
||||
|
||||
## 进度概览
|
||||
|
||||
| 完成 | 失败 | 跳过 | 总数 |
|
||||
|------|------|------|------|
|
||||
| 6 | 0 | 0 | 6 |
|
||||
|
||||
---
|
||||
|
||||
## 任务列表
|
||||
|
||||
### 1. 数据与路由准备
|
||||
|
||||
- [√] 1.1 在 `admin-frontend/src/types/api.d.ts` 与 `admin-frontend/src/api/admin.ts` 中补齐优惠券列表、保存载荷与接口封装 | depends_on: []
|
||||
- [√] 1.2 新增 `admin-frontend/src/utils/coupons.ts`,实现优惠券类型/周期选项、时间与表单转换、列表过滤与过期状态计算 | depends_on: [1.1]
|
||||
- [√] 1.3 在 `admin-frontend/src/layouts/AdminLayout.vue` 与 `admin-frontend/src/router/index.ts` 中开放“优惠券管理”菜单与路由 | depends_on: [1.1]
|
||||
|
||||
### 2. 优惠券页面实现
|
||||
|
||||
- [√] 2.1 新增 `admin-frontend/src/views/subscriptions/CouponsView.vue` 与样式,实现列表、搜索、类型筛选、本地分页、启停、编辑与删除入口 | depends_on: [1.1,1.2,1.3]
|
||||
- [√] 2.2 新增 `admin-frontend/src/views/subscriptions/CouponEditorDialog.vue` 与样式,实现新增/编辑弹窗、双列表单、指定周期/订阅、多码生成与提交保存 | depends_on: [1.1,1.2,1.3]
|
||||
|
||||
### 3. 验证与同步
|
||||
|
||||
- [√] 3.1 运行 `admin-frontend` 构建验证,并结合页面代码完成优惠券管理视觉/交互自检 | depends_on: [2.1,2.2]
|
||||
|
||||
---
|
||||
|
||||
## 执行日志
|
||||
|
||||
| 时间 | 任务 | 状态 | 备注 |
|
||||
|------|------|------|------|
|
||||
| 2026-04-24 15:51 | 方案包初始化 | completed | 已确认本轮范围为完整优惠券管理接入,采用 Apple 化后台风格 |
|
||||
| 2026-04-24 16:06 | 1.1 / 1.2 / 1.3 | completed | 已补齐 coupon 类型、接口、工具函数,并开放“优惠券管理”菜单与路由 |
|
||||
| 2026-04-24 16:18 | 2.1 / 2.2 | completed | 已完成优惠券列表页与新增/编辑弹窗,接入真实 coupon 接口与套餐限制项 |
|
||||
| 2026-04-24 16:28 | 3.1 | completed | `npm run build` 通过;当前环境缺少可复用浏览器与登录态,仅完成代码级视觉/交互自检 |
|
||||
|
||||
---
|
||||
|
||||
## 执行备注
|
||||
|
||||
> 记录执行过程中的重要说明、决策变更、风险提示等
|
||||
|
||||
- 当前工作树可能存在与本轮无关的其他改动,实施过程中需保持最小作用域,不覆盖既有未提交修改。
|
||||
- 当前后端缺少专门的 coupon detail/save 分离接口,编辑流程将复用 `coupon/generate`,并在前端统一做字段序列化。
|
||||
- 当前视觉验收受限于本地缺少可复用的后台登录态与浏览器截图工具,本轮已通过构建产物、组件结构与样式代码完成代码级验收,建议后续在真实管理登录态下补一次人工点检。
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"status": "completed",
|
||||
"completed": 5,
|
||||
"failed": 0,
|
||||
"pending": 0,
|
||||
"total": 5,
|
||||
"done": 5,
|
||||
"percent": 100,
|
||||
"current": "插件管理工作台、详情抽屉与构建验证已完成",
|
||||
"updated_at": "2026-04-24 16:12:00"
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
{
|
||||
"updatedAt": "2026-04-24T07:55:29.737Z",
|
||||
"version": 1,
|
||||
"source": "manual",
|
||||
"originCommand": "plugin-management-r2",
|
||||
"verifyMode": "review-first",
|
||||
"reviewerFocus": [
|
||||
"插件管理页是否延续当前 Apple 风格后台,并形成真实工作台而不是占位页",
|
||||
"卡片动作优先级、危险动作和受保护插件边界是否清晰",
|
||||
"详情抽屉中的 README 与配置双视图是否易读且层级明确"
|
||||
],
|
||||
"testerFocus": [
|
||||
"插件列表、类型切换、状态筛选与搜索是否真实连接 /plugin/getPlugins 数据流",
|
||||
"上传、安装、启用、禁用、升级、卸载动作是否真实命中对应插件接口",
|
||||
"插件配置读取与保存是否真实命中 /plugin/config"
|
||||
],
|
||||
"ui": {
|
||||
"required": true,
|
||||
"designContract": true,
|
||||
"sourcePriority": [
|
||||
"plan.md",
|
||||
".helloagents/DESIGN.md",
|
||||
"hello-ui"
|
||||
],
|
||||
"styleAdvisor": {
|
||||
"required": false,
|
||||
"reason": "",
|
||||
"focus": []
|
||||
},
|
||||
"visualValidation": {
|
||||
"required": true,
|
||||
"reason": "插件管理属于整页 UI 重做,需确认卡片列表、筛选工具栏与详情抽屉层级符合 Apple 风格后台契约",
|
||||
"screens": [
|
||||
"#/system/plugins desktop",
|
||||
"#/system/plugins detail-drawer desktop"
|
||||
],
|
||||
"states": [
|
||||
"插件列表加载完成态",
|
||||
"插件列表空状态或错误态",
|
||||
"插件详情 README 态",
|
||||
"插件配置编辑态"
|
||||
]
|
||||
}
|
||||
},
|
||||
"advisor": {
|
||||
"required": false,
|
||||
"reason": "",
|
||||
"focus": [],
|
||||
"preferredSources": []
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
# admin-frontend 插件管理首版交付 — 实施规划
|
||||
|
||||
## 目标与范围
|
||||
- 把 `#/system/plugins` 从占位页升级为真实插件管理页面。
|
||||
- 本轮范围聚焦“单页工作台 + 详情抽屉”模型:列表承担检索、筛选和高频动作,抽屉承担 README、配置与补充说明。
|
||||
- 其余系统管理子页保持现状,不借本轮需求扩展其他模块。
|
||||
|
||||
## 架构与实现策略
|
||||
- 在 `admin-frontend/src/api/admin.ts` 与 `src/types/api.d.ts` 中补齐插件管理接口和类型定义,保证所有页面动作都走真实后端契约。
|
||||
- 新增 `src/utils/plugins.ts`,集中处理插件类型文案、状态判断、筛选、README 渲染与配置表单值序列化,避免视图组件堆积逻辑。
|
||||
- 将 `/system/plugins` 路由替换为独立的 `PluginManagementView.vue`,继续保留黑色 hero + 白色工作台层次,首屏承载搜索、类型切换、状态筛选、上传入口与运营摘要。
|
||||
- 新增 `PluginDetailDrawer.vue` 作为插件详情工作台:
|
||||
- 左侧 / 顶部展示插件基本信息与状态
|
||||
- 中部切换 README / 配置两个视图
|
||||
- 配置基于后端返回的动态 schema 渲染,不额外臆造字段
|
||||
- 列表卡片提供高频动作按钮:
|
||||
- 未安装:安装
|
||||
- 已安装未启用:启用、卸载
|
||||
- 已启用:禁用
|
||||
- 可升级:升级
|
||||
- 受保护 / 核心插件:明确显示保护边界,避免危险误操作
|
||||
|
||||
## 完成定义
|
||||
- `#/system/plugins` 能真实拉取插件列表,并按类型 / 状态 / 关键词筛选。
|
||||
- 页面支持上传 zip 插件包,并在上传成功后刷新列表。
|
||||
- 管理员可以对插件执行安装、启用、禁用、升级、卸载动作,并获得明确成功 / 失败反馈。
|
||||
- 详情抽屉可查看 README 和插件基础信息;对存在配置 schema 的插件,可读取并保存配置。
|
||||
- 验证主路径:`review-first`
|
||||
- reviewer 关注边界:
|
||||
- 插件管理首屏是否与现有 Apple 风格后台一致,且不像占位页
|
||||
- 列表动作优先级、危险按钮和受保护插件边界是否清晰
|
||||
- 详情抽屉的 README / 配置双视图是否足够清楚
|
||||
- tester 关注边界:
|
||||
- `/plugin/getPlugins`、`/plugin/upload`、`/plugin/install`、`/plugin/enable`、`/plugin/disable`、`/plugin/uninstall`、`/plugin/upgrade` 是否都已接入真实数据流
|
||||
- 插件配置读取 / 保存是否真实命中 `/plugin/config`
|
||||
- 搜索、类型切换、状态筛选是否真实影响渲染结果
|
||||
|
||||
## 文件结构
|
||||
- `admin-frontend/src/router/index.ts`
|
||||
- `admin-frontend/src/api/admin.ts`
|
||||
- `admin-frontend/src/types/api.d.ts`
|
||||
- `admin-frontend/src/utils/plugins.ts`(新增)
|
||||
- `admin-frontend/src/views/system/PluginManagementView.vue`(新增)
|
||||
- `admin-frontend/src/views/system/PluginManagementView.scss`(新增)
|
||||
- `admin-frontend/src/views/system/PluginDetailDrawer.vue`(新增)
|
||||
|
||||
## UI / 设计约束
|
||||
- 首屏延续当前系统管理模块的黑色 hero,右侧摘要卡片改为“插件总数 / 已启用 / 可升级 / 用户上传”等运营信息。
|
||||
- 列表采用大卡片而不是传统密表格,强调插件名称、类型、版本、作者、描述与状态标签,贴近用户截图的阅读方式。
|
||||
- 顶部筛选区使用轻量 segmented control + select + search 组合,不引入多层复杂过滤器。
|
||||
- 配置表单要兼容 `boolean / string / text / json / select` 等基础字段类型,字段说明与 placeholder 保持可见。
|
||||
- README 区域使用真实 Markdown 渲染,保留代码块、列表和标题层级。
|
||||
|
||||
## 风险与验证
|
||||
- 风险 1:后端返回的插件配置 schema 是动态结构,前端需要兼容多种字段类型与空配置插件。
|
||||
- 风险 2:`getPlugins` 已带部分配置和 README,但已安装插件的配置需要保证与 `/plugin/config` 拉取一致,避免抽屉内旧数据。
|
||||
- 风险 3:本地环境缺少真实登录态时,无法做完整浏览器联调;需要用 build + 代码级结构自检给出本轮 UI 验收结论。
|
||||
- 验证方式:
|
||||
- `npm run build`
|
||||
- 对构建产物与代码结构做 UI 自检,确认搜索、筛选、卡片操作与抽屉视图均已真实连接数据流
|
||||
|
||||
## 决策记录
|
||||
- [2026-04-24] D001:插件管理采用“卡片列表 + 详情抽屉”,不回退到纯表格,兼顾截图风格和后台可操作性。
|
||||
- [2026-04-24] D002:配置编辑采用动态 schema 渲染,不为单个插件写死字段。
|
||||
- [2026-04-24] D003:README 与配置合并进同一个详情工作台,避免列表页信息密度失控。
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
# admin-frontend 插件管理首版交付 — 需求
|
||||
|
||||
确认后冻结,执行阶段不可修改。如需变更必须回到设计阶段重新确认。
|
||||
|
||||
## 核心目标
|
||||
- 在 `admin-frontend` 中把 `/system/plugins` 从结构化占位页升级为真实插件管理工作台。
|
||||
- 页面视觉继续遵循 `apple/DESIGN.md` 与当前后台 Apple 化风格,并尽量贴近用户提供的目标截图:顶部搜索 / 分组切换 / 状态筛选 / 上传入口,下方插件卡片列表。
|
||||
- 让管理员可以在同一页面完成插件浏览、筛选、上传、安装、启用 / 禁用、升级、卸载,以及 README / 配置查看与编辑。
|
||||
|
||||
## 功能边界
|
||||
- 必须接入现有 Laravel 管理接口的真实数据链路:
|
||||
- `GET /plugin/types`
|
||||
- `GET /plugin/getPlugins`
|
||||
- `POST /plugin/upload`
|
||||
- `POST /plugin/install`
|
||||
- `POST /plugin/uninstall`
|
||||
- `POST /plugin/enable`
|
||||
- `POST /plugin/disable`
|
||||
- `GET /plugin/config`
|
||||
- `POST /plugin/config`
|
||||
- `POST /plugin/upgrade`
|
||||
- 必须支持:
|
||||
- 按关键词搜索插件
|
||||
- 按插件类型切换(全部 / 功能 / 支付方式)
|
||||
- 按状态筛选(全部 / 已启用 / 已安装未启用 / 未安装 / 可升级)
|
||||
- 上传 zip 插件包
|
||||
- 列表中直接执行安装、启用、禁用、升级、卸载动作
|
||||
- 打开插件详情工作台,查看 README、基础元信息,并对可配置插件进行配置保存
|
||||
- 必须覆盖加载、空列表、错误、按钮提交中、配置保存成功 / 失败等状态。
|
||||
|
||||
## 非目标
|
||||
- 本轮不实现主题、公告、支付配置、知识库管理的真实 CRUD 页面。
|
||||
- 本轮不新增或重构 Laravel 插件管理接口。
|
||||
- 本轮不接入浏览器端拖拽上传、批量操作或插件市场远程下载能力。
|
||||
- 本轮不修改 `public/assets/admin` 子模块之外的发布流程。
|
||||
|
||||
## 技术约束
|
||||
- 技术栈固定为 `Vue 3 + TypeScript + Vite + Element Plus`。
|
||||
- 后端真相源以现有 `PluginController` / `PluginConfigService` / `PluginManager` 为准,不在前端猜测额外字段。
|
||||
- 视觉契约优先级:本方案 > `.helloagents/DESIGN.md` > `apple/DESIGN.md` 参考原则。
|
||||
- 构建验证使用 `admin-frontend/package.json` 中已有 `npm run build`。
|
||||
|
||||
## 质量要求
|
||||
- 插件管理页必须保持 Apple 风格后台的一致性,同时比现有占位页更强调运营效率与状态可读性。
|
||||
- 卡片与详情工作台中的插件状态、危险动作和受保护插件边界必须清晰可辨。
|
||||
- README 展示与配置编辑必须是真实数据流,不允许停留在纯展示占位。
|
||||
- 最终至少完成一次构建验证,并补一份本轮 UI 验收结论。
|
||||
@@ -0,0 +1,13 @@
|
||||
# admin-frontend 插件管理首版交付 — 任务分解
|
||||
|
||||
## 任务列表
|
||||
- [x] 任务1:冻结本轮插件管理方案包与状态上下文(涉及文件:`.helloagents/plan/202604241553_admin-frontend-plugin-management/requirements.md`、`.helloagents/plan/202604241553_admin-frontend-plugin-management/plan.md`、`.helloagents/plan/202604241553_admin-frontend-plugin-management/tasks.md`、`.helloagents/plan/202604241553_admin-frontend-plugin-management/contract.json`、`.helloagents/sessions/master/default/STATE.md`;完成标准:存在可执行的需求/方案/任务/合同文件,状态文件已切到插件管理主线;验证方式:文件检查)
|
||||
- [x] 任务2:补齐插件管理前端类型与 API(涉及文件:`admin-frontend/src/api/admin.ts`、`admin-frontend/src/types/api.d.ts`、`admin-frontend/src/utils/plugins.ts`;完成标准:存在插件列表、动作、配置、上传所需的真实接口封装与辅助类型 / 工具;验证方式:`npm run build`)
|
||||
- [x] 任务3:实现插件管理列表工作台(涉及文件:`admin-frontend/src/router/index.ts`、`admin-frontend/src/views/system/PluginManagementView.vue`、`admin-frontend/src/views/system/PluginManagementView.scss`;完成标准:`#/system/plugins` 能展示真实插件卡片、搜索、类型切换、状态筛选、上传入口与列表动作;验证方式:`npm run build`)
|
||||
- [x] 任务4:实现插件详情与配置工作台(涉及文件:`admin-frontend/src/views/system/PluginDetailDrawer.vue`、`admin-frontend/src/utils/plugins.ts`、`admin-frontend/src/api/admin.ts`;完成标准:可打开 README / 配置抽屉,并支持真实配置读取与保存;验证方式:`npm run build`)
|
||||
- [x] 任务5:完成验证、知识库同步与交付证据(涉及文件:`.helloagents/modules/admin-frontend.md`、`.helloagents/CHANGELOG.md`、`.helloagents/.ralph-visual.json`、`.helloagents/.ralph-closeout.json`、`.helloagents/archive/_index.md`、`.helloagents/sessions/master/default/STATE.md`;完成标准:构建通过,UI 验收结论与知识库记录同步完成;验证方式:命令输出 + 证据文件)
|
||||
|
||||
## 进度
|
||||
- [x] 已冻结插件管理首版交付范围。
|
||||
- [x] 已完成插件管理页面与详情工作台。
|
||||
- [x] 已完成验证与知识库同步。
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"status": "completed",
|
||||
"completed": 6,
|
||||
"failed": 0,
|
||||
"pending": 0,
|
||||
"total": 6,
|
||||
"done": 6,
|
||||
"percent": 100,
|
||||
"current": "支付配置真实工作台已完成,等待归档与用户验收",
|
||||
"updated_at": "2026-04-24 16:14:00"
|
||||
}
|
||||
+206
@@ -0,0 +1,206 @@
|
||||
# 变更提案: admin-frontend-payment-management
|
||||
|
||||
## 元信息
|
||||
```yaml
|
||||
类型: 功能开发
|
||||
方案类型: implementation
|
||||
优先级: P1
|
||||
状态: 进行中
|
||||
创建: 2026-04-24
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 1. 需求
|
||||
|
||||
### 背景
|
||||
当前 `admin-frontend` 的“支付配置”仍是占位页,但 Laravel 后端已经提供 `payment/fetch`、`payment/getPaymentMethods`、`payment/getPaymentForm`、`payment/save`、`payment/show`、`payment/drop`、`payment/sort` 等完整管理接口。用户本轮明确选择“完整真实 CRUD”方案,并提供了支付列表、编辑抽屉与支付接口下拉截图,要求继续完成支付配置模块。
|
||||
|
||||
### 目标
|
||||
- 将 `#/system/payments` 从占位页升级为真实可用的支付配置页面。
|
||||
- 提供支付方式列表、关键词搜索、启停、新增/编辑、删除与排序能力。
|
||||
- 抽屉表单按所选支付接口动态拉取配置字段,保持与后端支付插件表单契约一致。
|
||||
- 视觉上延续 `apple/DESIGN.md` 与 `.helloagents/DESIGN.md` 的 Apple 风格后台体系。
|
||||
|
||||
### 约束条件
|
||||
```yaml
|
||||
范围约束: 仅实现支付配置工作台,不扩展插件/主题/知识库等其他系统模块
|
||||
技术约束: 继续使用 Vue3 + TypeScript + Element Plus,不新增第三方表单或拖拽依赖
|
||||
业务约束: 后端真实契约以 PaymentController / PaymentService / 插件 form() 返回字段为准,不在前端猜测额外支付字段
|
||||
数据约束: 排序继续调用 `/payment/sort`;启停继续调用 `/payment/show` 的“切换”语义接口
|
||||
视觉约束: 延续黑色 hero + 白色工作台 + 克制蓝色交互,保持与现有系统配置/套餐管理同一视觉家族
|
||||
```
|
||||
|
||||
### 验收标准
|
||||
- [ ] `#/system/payments` 可真实拉取支付方式列表,并显示 ID、启用状态、显示名称、支付接口、通知地址与操作列。
|
||||
- [ ] 页面支持关键词搜索,筛选后结果与分页计数同步更新。
|
||||
- [ ] 支持新增与编辑支付方式,字段覆盖显示名称、图标 URL、通知域名、百分比手续费、固定手续费、支付接口与动态支付配置字段。
|
||||
- [ ] 支持启停、删除与排序,并给出明确成功/失败反馈。
|
||||
- [ ] `admin-frontend` 执行 `npm run build` 通过。
|
||||
|
||||
---
|
||||
|
||||
## 2. 方案
|
||||
|
||||
### 页面结构
|
||||
1. 延续系统管理页面的 Apple 化后台结构,顶部使用黑色 hero 展示支付概览统计。
|
||||
2. 主工作区使用白色表格容器,提供“添加支付方式”“搜索支付方式”“编辑排序”三类核心操作。
|
||||
3. 支付方式编辑采用右侧抽屉,顶层字段集中展示显示名称、图标、通知域名、手续费与支付接口。
|
||||
4. 抽屉下半区按支付接口动态加载真实配置字段,保持与后端插件 `form()` 返回结果一致。
|
||||
5. 排序使用独立对话框,通过上移/下移维护本地顺序,再提交到 `/payment/sort`。
|
||||
|
||||
### 前端实现策略
|
||||
1. 在 `src/types/api.d.ts` 与 `src/api/admin.ts` 中补齐支付方式列表、动态配置字段与保存载荷类型 / API 封装。
|
||||
2. 新增 `src/utils/payments.ts`,集中处理支付方式归一化、关键词过滤、排序移动、手续费展示与动态配置序列化。
|
||||
3. 新增:
|
||||
- `src/views/system/SystemPaymentsView.vue`
|
||||
- `src/views/system/SystemPaymentsView.scss`
|
||||
- `src/views/system/SystemPaymentEditorDrawer.vue`
|
||||
- `src/views/system/SystemPaymentEditorDrawer.scss`
|
||||
4. 将 `/system/payments` 路由切换为真实页面,其余系统管理入口保持现状不动。
|
||||
|
||||
### 影响范围
|
||||
```yaml
|
||||
涉及模块:
|
||||
- admin-frontend/src/types: 补齐支付配置相关类型定义
|
||||
- admin-frontend/src/api: 新增 payment 管理接口封装
|
||||
- admin-frontend/src/utils: 新增支付数据转换、过滤、保存辅助逻辑
|
||||
- admin-frontend/src/views/system: 新增支付列表页与编辑抽屉
|
||||
- admin-frontend/src/router: 将支付配置路由切换到真实页面
|
||||
预计变更文件: 8-9
|
||||
```
|
||||
|
||||
### 风险评估
|
||||
| 风险 | 等级 | 应对 |
|
||||
| 后端 `/payment/show` 是切换型接口,不接受显式目标状态 | 中 | 前端只在用户主动切换时调用一次,并在成功后按目标值更新本地状态 |
|
||||
| 动态支付配置字段完全由插件 form() 返回,前端若自行假设字段会导致保存错位 | 高 | 抽屉内所有支付配置字段均通过 `/payment/getPaymentForm` 实时拉取,不写死配置项 |
|
||||
| 构建会刷新 `public/assets/admin` 子模块产物 | 中 | 仅执行 `admin-frontend` 构建验证,不自动代做子模块发布 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 技术设计(可选)
|
||||
|
||||
### 架构设计
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[SystemPaymentsView] --> B[admin.ts payment API]
|
||||
A --> C[payments.ts]
|
||||
A --> D[SystemPaymentEditorDrawer]
|
||||
D --> B
|
||||
D --> C
|
||||
```
|
||||
|
||||
### API设计
|
||||
#### GET /payment/fetch
|
||||
- **请求**: 无
|
||||
- **响应**: `AdminPaymentListItem[]`
|
||||
|
||||
#### GET /payment/getPaymentMethods
|
||||
- **请求**: 无
|
||||
- **响应**: `string[]`
|
||||
|
||||
#### POST /payment/getPaymentForm
|
||||
- **请求**: `{ payment, id? }`
|
||||
- **响应**: `Record<string, AdminPaymentConfigField>`
|
||||
|
||||
#### POST /payment/save
|
||||
- **请求**: `{ id?, name, icon?, payment, config, notify_domain?, handling_fee_fixed?, handling_fee_percent? }`
|
||||
- **响应**: `{ status, data }`
|
||||
|
||||
### 数据模型
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| id | number | 支付方式 ID |
|
||||
| payment | string | 支付接口代码,如 EPay / TokenPay |
|
||||
| name | string | 后台显示名称 |
|
||||
| icon | string \| null | 图标 URL |
|
||||
| notify_domain | string \| null | 自定义通知域名 |
|
||||
| notify_url | string \| null | 后端拼接后的完整通知地址 |
|
||||
| handling_fee_fixed | number \| null | 固定手续费 |
|
||||
| handling_fee_percent | number \| null | 百分比手续费 |
|
||||
| enable | boolean | 是否启用 |
|
||||
| config | Record<string, unknown> | 支付插件配置对象 |
|
||||
|
||||
---
|
||||
|
||||
## 4. 核心场景
|
||||
|
||||
### 场景: 运营新增支付方式
|
||||
**模块**: admin-frontend/system
|
||||
**条件**: 管理员已登录,进入 `#/system/payments`
|
||||
**行为**: 点击“添加支付方式”,选择支付接口并填写网关参数后提交
|
||||
**结果**: 新支付方式保存成功,列表刷新并展示新记录
|
||||
|
||||
### 场景: 运营切换支付启用状态
|
||||
**模块**: admin-frontend/system
|
||||
**条件**: 列表中存在可用支付方式
|
||||
**行为**: 在列表中切换启用开关
|
||||
**结果**: 对应支付方式状态被切换,并在当前列表中即时更新
|
||||
|
||||
### 场景: 运营维护支付排序
|
||||
**模块**: admin-frontend/system
|
||||
**条件**: 系统中存在多个支付方式
|
||||
**行为**: 打开“编辑排序”,调整上下顺序并保存
|
||||
**结果**: 后端 `/payment/sort` 接收新的排序序列,列表刷新为最新顺序
|
||||
|
||||
---
|
||||
|
||||
## 5. 技术决策
|
||||
|
||||
### admin-frontend-payment-management#D001: 支付配置采用“真实列表页 + 动态配置抽屉 + 独立排序对话框”
|
||||
**日期**: 2026-04-24
|
||||
**状态**: ✅采纳
|
||||
**背景**: 用户截图已经明确表达“列表 + 右侧编辑抽屉 + 编辑排序”的后台工作流结构。
|
||||
**选项分析**:
|
||||
| 选项 | 优点 | 缺点 |
|
||||
| A: 继续使用占位页 | 改动最小 | 无法完成真实支付配置任务 |
|
||||
| B: 列表页 + 动态配置抽屉 + 排序对话框 | 最贴近截图,也与套餐管理模式一致 | 需要新增更多前端结构与状态管理 |
|
||||
**决策**: 选择方案 B
|
||||
**理由**: 能同时覆盖用户截图中的真实使用方式与当前 Apple 风格后台架构。
|
||||
**影响**: `SystemPaymentsView.vue`、`SystemPaymentEditorDrawer.vue`
|
||||
|
||||
### admin-frontend-payment-management#D002: 支付配置字段完全以后端 `/payment/getPaymentForm` 为唯一真相源
|
||||
**日期**: 2026-04-24
|
||||
**状态**: ✅采纳
|
||||
**背景**: 各支付插件的配置字段由插件 `form()` 动态生成,字段集并不固定。
|
||||
**选项分析**:
|
||||
| 选项 | 优点 | 缺点 |
|
||||
|------|------|------|
|
||||
| A: 前端写死常见支付字段 | 实现快 | 无法覆盖不同插件,容易与后端表单脱节 |
|
||||
| B: 每次根据接口动态拉取字段 | 契约最稳定 | 需要额外处理加载与切换状态 |
|
||||
**决策**: 选择方案 B
|
||||
**理由**: 可同时兼容 EPay、TokenPay、AlipayF2F、Coinbase 等不同插件,不会因为字段假设错误而破坏保存链路。
|
||||
**影响**: `admin.ts`、`payments.ts`、`SystemPaymentEditorDrawer.vue`
|
||||
|
||||
### admin-frontend-payment-management#D003: 支付启停继续沿用现有“切换型接口”,前端做同值短路保护
|
||||
**日期**: 2026-04-24
|
||||
**状态**: ✅采纳
|
||||
**背景**: `/payment/show` 后端实现是直接反转状态,不接收目标状态。
|
||||
**选项分析**:
|
||||
| 选项 | 优点 | 缺点 |
|
||||
|------|------|------|
|
||||
| A: 前端假设为“设置型接口”并传目标值 | 交互直觉更强 | 与后端真实行为不一致,容易在重复事件下错位 |
|
||||
| B: 前端只做主动点击触发 + 成功后同步本地状态 | 与现有接口完全对齐 | 需要额外防止无效 change 事件 |
|
||||
**决策**: 选择方案 B
|
||||
**理由**: 能最小代价对齐后端现状,并避免初始化或重复事件导致的误切换。
|
||||
**影响**: `SystemPaymentsView.vue`
|
||||
|
||||
---
|
||||
|
||||
## 6. 成果设计
|
||||
|
||||
### 设计方向
|
||||
- **美学基调**: Apple Admin Payments。黑色首屏强调“系统级支付运营台”的沉稳感,正文回到白底高密度工作台,重点突出支付方式与通知链路,而不是营销化装饰。
|
||||
- **记忆点**: 支付配置列表里的“图标 + 名称 + 手续费摘要”组合,与右侧动态配置抽屉形成明显的黑白双层结构。
|
||||
- **参考**: `apple/DESIGN.md`、`.helloagents/DESIGN.md`、用户提供的支付列表 / 编辑抽屉 / 支付接口下拉截图
|
||||
|
||||
### 视觉要素
|
||||
- **配色**: 首屏 `#000000`,页面背景 `#f5f5f7`,工作区 `#ffffff`,强调色 `#0071e3`,危险动作保持 `var(--xboard-danger)`
|
||||
- **字体**: 延续项目现有系统字体栈,首屏标题保持大字号紧行高,列表和抽屉字段走轻量运营层级
|
||||
- **布局**: Hero + 工具条 + 表格工作台;编辑器采用右侧抽屉,表单上半部为顶层字段,下半部为动态支付配置
|
||||
- **动效**: 仅保留抽屉开合、按钮 hover、排序对话框切换与开关状态变化的轻量动效
|
||||
- **氛围**: 使用克制阴影、圆角白底、胶囊型通知地址与简洁图标预览,不堆叠过多卡片或装饰性标签
|
||||
|
||||
### 技术约束
|
||||
- **可访问性**: 开关、按钮、抽屉表单需保留可见焦点;错误和危险操作不能只靠颜色表达
|
||||
- **响应式**: 桌面优先;窄屏下 hero、工具条、排序对话框和抽屉字段网格需折叠为单列
|
||||
@@ -0,0 +1,53 @@
|
||||
# 任务清单: admin-frontend-payment-management
|
||||
|
||||
> **@status:** completed | 2026-04-24 16:14
|
||||
|
||||
```yaml
|
||||
@feature: admin-frontend-payment-management
|
||||
@created: 2026-04-24
|
||||
@status: completed
|
||||
@mode: R2
|
||||
```
|
||||
|
||||
## 进度概览
|
||||
|
||||
| 完成 | 失败 | 跳过 | 总数 |
|
||||
|------|------|------|------|
|
||||
| 6 | 0 | 0 | 6 |
|
||||
|
||||
---
|
||||
|
||||
## 任务列表
|
||||
|
||||
### 1. 数据与路由准备
|
||||
|
||||
- [√] 1.1 在 `admin-frontend/src/types/api.d.ts` 与 `admin-frontend/src/api/admin.ts` 中补齐支付方式列表、动态配置字段与接口封装 | depends_on: []
|
||||
- [√] 1.2 新增 `admin-frontend/src/utils/payments.ts`,实现支付方式归一化、过滤、排序移动与保存序列化 | depends_on: [1.1]
|
||||
- [√] 1.3 在 `admin-frontend/src/router/index.ts` 中将 `/system/payments` 切换到真实支付配置页面 | depends_on: [1.1]
|
||||
|
||||
### 2. 支付配置页面实现
|
||||
|
||||
- [√] 2.1 新增 `admin-frontend/src/views/system/SystemPaymentsView.vue` 与样式,实现列表、搜索、启停、删除、新增/编辑入口与排序对话框 | depends_on: [1.1,1.2,1.3]
|
||||
- [√] 2.2 新增 `admin-frontend/src/views/system/SystemPaymentEditorDrawer.vue` 与样式,实现动态支付接口配置抽屉与保存提交流程 | depends_on: [1.1,1.2,1.3]
|
||||
|
||||
### 3. 验证与同步
|
||||
|
||||
- [√] 3.1 运行 `admin-frontend` 构建验证,并结合页面代码完成支付配置视觉/交互自检 | depends_on: [2.1,2.2]
|
||||
|
||||
---
|
||||
|
||||
## 执行日志
|
||||
|
||||
| 时间 | 任务 | 状态 | 备注 |
|
||||
|------|------|------|------|
|
||||
| 2026-04-24 15:58 | 方案包初始化 | completed | 已确认本轮范围为支付配置完整 CRUD 工作台,目标对齐用户截图与 `/payment/*` 后端接口 |
|
||||
| 2026-04-24 16:05 | 1.1 / 1.2 / 1.3 | completed | 已补齐支付配置类型、API、工具层与真实路由切换 |
|
||||
| 2026-04-24 16:11 | 2.1 / 2.2 | completed | 已完成支付配置列表、排序对话框与动态支付配置抽屉 |
|
||||
| 2026-04-24 16:14 | 3.1 | completed | `npm run build` 通过;当前环境无浏览器自动化工具,已完成代码级视觉与交互自检 |
|
||||
|
||||
---
|
||||
|
||||
## 执行备注
|
||||
|
||||
- 当前工作树存在与本轮无关的其他未提交修改,实施时需保持最小作用域,不覆盖已有 in-progress 改动。
|
||||
- 构建验证会刷新 `public/assets/admin` 子模块产物,本轮仅提供功能实现与验证证据,不自动代做发布。
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"status": "completed",
|
||||
"completed": 5,
|
||||
"failed": 0,
|
||||
"pending": 0,
|
||||
"total": 5,
|
||||
"done": 5,
|
||||
"percent": 100,
|
||||
"current": "主题管理页面、动态配置抽屉与构建验证已完成,等待交付",
|
||||
"updated_at": "2026-04-24 16:12:00"
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
# 变更提案: admin-frontend-theme-management
|
||||
|
||||
## 元信息
|
||||
```yaml
|
||||
类型: 新功能
|
||||
方案类型: implementation
|
||||
优先级: P1
|
||||
状态: 已完成
|
||||
创建: 2026-04-24
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 1. 需求
|
||||
|
||||
### 背景
|
||||
当前 `admin-frontend` 已经完成系统配置真实页,但 `#/system/themes` 仍停留在结构化占位状态。用户本轮要求继续基于 `apple/DESIGN.md`、项目级 `.helloagents/DESIGN.md` 和提供的参考图,把“主题配置”升级为真实可用的主题管理页面。
|
||||
|
||||
### 目标
|
||||
- 将 `#/system/themes` 从占位页升级为真实主题管理工作台。
|
||||
- 展示可用主题列表、当前主题标记和主题基础信息。
|
||||
- 提供主题设置抽屉,支持动态主题配置保存。
|
||||
- 提供 zip 主题包上传入口,并支持把某个主题设为当前主题。
|
||||
|
||||
### 约束条件
|
||||
```yaml
|
||||
技术约束: 继续使用 Vue3 + TypeScript + Element Plus + Vite,不新增主题编辑器或上传库
|
||||
业务约束: 后端沿用现有 `theme/*` 与 `config/save(frontend_theme)` 能力,不修改 Laravel API
|
||||
范围约束: 本轮先完成主题列表、当前主题切换、主题设置与上传;删除主题保留到下一轮
|
||||
视觉约束: 保持 Apple 化后台语义,页面结构优先贴近参考图中的“标题 + 说明 + 主题卡片 + 上传入口”
|
||||
```
|
||||
|
||||
### 验收标准
|
||||
- [ ] `#/system/themes` 能展示真实主题列表,不再使用占位页。
|
||||
- [ ] 页面能明确标记当前主题,并允许把其他主题设为当前主题。
|
||||
- [ ] 点击“主题设置”可打开配置抽屉,按主题 schema 渲染字段并保存。
|
||||
- [ ] 页面提供 zip 主题包上传入口,并接入真实后端上传接口。
|
||||
- [ ] `admin-frontend` 构建通过,且知识库记录主题管理已从占位页升级为真实页面。
|
||||
|
||||
---
|
||||
|
||||
## 2. 方案
|
||||
|
||||
### 技术方案
|
||||
1. 在 `src/types/api.d.ts` 与 `src/api/admin.ts` 中补齐主题列表、主题配置和主题上传所需类型与接口封装。
|
||||
2. 新增 `src/utils/themes.ts`,统一处理主题列表排序、配置默认值回填和表单序列化。
|
||||
3. 新增 `src/views/system/ThemesView.vue` 与 `ThemeConfigDrawer.vue`:
|
||||
- `ThemesView` 负责标题区、当前主题/数量摘要、主题卡片、上传按钮与切换逻辑。
|
||||
- `ThemeConfigDrawer` 负责根据主题 schema 动态渲染配置项并保存。
|
||||
4. 在 `src/router/index.ts` 中把 `system/themes` 路由从占位页切换到真实页面组件。
|
||||
|
||||
### 风险评估
|
||||
| 风险 | 等级 | 应对 |
|
||||
|------|------|------|
|
||||
| 主题切换没有独立 `switchTheme` 路由 | 中 | 复用 `config/save` 的 `frontend_theme` 保存链路,由后端内部触发 `ThemeService::switch` |
|
||||
| 主题配置字段完全动态,前端容易误假设字段类型 | 中 | 仅支持后端 schema 已声明的 `input / textarea / select` 三类字段 |
|
||||
| 本地缺少后台登录态与浏览器截图工具 | 低 | 本轮以构建通过 + 代码级视觉自检作为验收证据,并在知识库中注明限制 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 技术决策
|
||||
|
||||
### admin-frontend-theme-management#D001: 主题切换复用 `config/save(frontend_theme)`,不前端直连未开放路由
|
||||
**日期**: 2026-04-24
|
||||
**状态**: ✅采纳
|
||||
**背景**: 后端 `ThemeController` 存在 `switchTheme()`,但当前管理路由未公开对应 endpoint。
|
||||
**决策**: 前端将“设为当前主题”统一走 `saveAdminConfig({ frontend_theme })`。
|
||||
**理由**: 这条链路已被 `ConfigController` 正式支持,且内部会触发 `ThemeService->switch`,无需扩展后端接口。
|
||||
|
||||
### admin-frontend-theme-management#D002: 主题配置使用右侧抽屉,不在卡片内直接展开表单
|
||||
**日期**: 2026-04-24
|
||||
**状态**: ✅采纳
|
||||
**背景**: 参考图强调卡片式主题列表;主题配置字段是动态 schema,直接展开会破坏列表节奏。
|
||||
**决策**: 卡片只承载主题信息与主操作,详细配置统一放进 `ThemeConfigDrawer`。
|
||||
**理由**: 更贴合 Apple 化后台“主列表 + 聚焦设置面板”的结构,也便于后续扩展删除/预览等动作。
|
||||
@@ -0,0 +1,54 @@
|
||||
# 任务清单: admin-frontend-theme-management
|
||||
|
||||
> **@status:** completed | 2026-04-24 16:12
|
||||
|
||||
```yaml
|
||||
@feature: admin-frontend-theme-management
|
||||
@created: 2026-04-24
|
||||
@status: completed
|
||||
@mode: R2
|
||||
```
|
||||
|
||||
## 进度概览
|
||||
|
||||
| 完成 | 失败 | 跳过 | 总数 |
|
||||
|------|------|------|------|
|
||||
| 5 | 0 | 0 | 5 |
|
||||
|
||||
---
|
||||
|
||||
## 任务列表
|
||||
|
||||
### 1. 数据与路由准备
|
||||
|
||||
- [√] 1.1 在 `admin-frontend/src/types/api.d.ts` 与 `admin-frontend/src/api/admin.ts` 中补齐主题管理类型、配置接口与上传接口 | depends_on: []
|
||||
- [√] 1.2 新增 `admin-frontend/src/utils/themes.ts`,统一处理主题列表排序、动态配置默认值和序列化逻辑 | depends_on: [1.1]
|
||||
- [√] 1.3 在 `admin-frontend/src/router/index.ts` 中把 `system/themes` 路由切换到真实页面 | depends_on: [1.1]
|
||||
|
||||
### 2. 主题管理页面实现
|
||||
|
||||
- [√] 2.1 新增 `admin-frontend/src/views/system/ThemesView.vue`,实现标题区、主题卡片、当前主题标记、切换和上传按钮 | depends_on: [1.1,1.2,1.3]
|
||||
- [√] 2.2 新增 `admin-frontend/src/views/system/ThemeConfigDrawer.vue`,实现主题设置抽屉、动态字段表单与保存动作 | depends_on: [1.1,1.2]
|
||||
|
||||
### 3. 验证与同步
|
||||
|
||||
- [√] 3.1 运行 `admin-frontend` 构建验证,并结合页面代码完成主题管理视觉/交互自检 | depends_on: [2.1,2.2]
|
||||
|
||||
---
|
||||
|
||||
## 执行日志
|
||||
|
||||
| 时间 | 任务 | 状态 | 备注 |
|
||||
|------|------|------|------|
|
||||
| 2026-04-24 16:07 | 方案包初始化 | completed | 已确认本轮范围为主题列表、当前主题切换、主题设置抽屉与上传主题 |
|
||||
| 2026-04-24 16:09 | 1.1 / 1.2 / 1.3 | completed | 已补齐主题类型、API、工具函数,并将 `system/themes` 指向真实页面 |
|
||||
| 2026-04-24 16:11 | 2.1 / 2.2 | completed | 已完成主题卡片页与动态设置抽屉,接入真实主题配置/上传能力 |
|
||||
| 2026-04-24 16:12 | 3.1 | completed | `npm run build` 通过;当前环境缺少后台登录态与浏览器工具,已完成代码级视觉自检 |
|
||||
|
||||
---
|
||||
|
||||
## 执行备注
|
||||
|
||||
- “设为当前主题”当前复用 `config/save(frontend_theme)` 完成,因为管理路由中没有公开独立的主题切换 endpoint。
|
||||
- 本轮未实现删除主题,避免在没有额外确认和危险操作设计的情况下引入破坏性入口。
|
||||
- `public/assets/admin` 为构建产物子模块;本轮构建已刷新对应产物,但未代做子模块提交与根仓发布。
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"updatedAt": "2026-04-24T16:20:00+08:00",
|
||||
"version": 1,
|
||||
"source": "manual",
|
||||
"originCommand": "generic-r2",
|
||||
"verifyMode": "build-first",
|
||||
"reviewerFocus": [
|
||||
"订单管理列表结构是否贴近用户提供的后台截图",
|
||||
"详情抽屉是否覆盖查看、手动支付、取消与佣金状态维护主链路"
|
||||
],
|
||||
"testerFocus": [
|
||||
"订单列表是否真实连接 /order/fetch,并响应搜索、筛选、排序与分页",
|
||||
"分配订单抽屉是否真实连接 /order/assign",
|
||||
"详情抽屉是否真实连接 /order/detail /order/paid /order/cancel /order/update"
|
||||
],
|
||||
"ui": {
|
||||
"required": true,
|
||||
"designContract": true,
|
||||
"sourcePriority": [
|
||||
"requirements.md",
|
||||
".helloagents/DESIGN.md",
|
||||
"hello-ui"
|
||||
],
|
||||
"styleAdvisor": {
|
||||
"required": false,
|
||||
"reason": "",
|
||||
"focus": []
|
||||
},
|
||||
"visualValidation": {
|
||||
"required": true,
|
||||
"reason": "订单管理属于真实后台业务页,需要确认列表结构、筛选条与详情抽屉在代码实现上与目标截图和 Apple 化后台契约一致。",
|
||||
"screens": [
|
||||
"#/subscriptions/orders desktop"
|
||||
],
|
||||
"states": [
|
||||
"订单列表默认加载完成态",
|
||||
"分配订单抽屉展开态",
|
||||
"订单详情抽屉展开态"
|
||||
]
|
||||
}
|
||||
},
|
||||
"advisor": {
|
||||
"required": false,
|
||||
"reason": "",
|
||||
"focus": [],
|
||||
"preferredSources": []
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
# admin-frontend 订单管理首版交付 — 实施规划
|
||||
|
||||
## 目标与范围
|
||||
- 在现有订阅管理分组中补齐订单管理真实页,替换原先的禁用态入口。
|
||||
- 页面聚焦“订单运营工作台”主链路:查订单、分配订单、看详情、手工补单、管理佣金状态。
|
||||
|
||||
## 架构与实现策略
|
||||
- 在现有 `AdminLayout` 中开放 `/subscriptions/orders` 导航入口,并新增对应路由。
|
||||
- 新增 `OrdersView` 作为真实列表页,整体结构参考用户截图:
|
||||
- 顶部标题与说明
|
||||
- “添加订单”主按钮
|
||||
- 搜索框
|
||||
- 类型 / 周期 / 订单状态 / 佣金状态筛选按钮
|
||||
- 数据表格与分页
|
||||
- 新增两个子组件:
|
||||
- `OrderAssignDrawer.vue`:负责手动分配订单
|
||||
- `OrderDetailDrawer.vue`:负责查看详情与行级动作
|
||||
- 在 `src/utils/orders.ts` 中集中处理:
|
||||
- 金额分→元格式化
|
||||
- 类型 / 状态 / 周期映射
|
||||
- 筛选参数组装
|
||||
- 分配订单周期选项生成
|
||||
- API 层在 `src/api/admin.ts` 中新增订单接口封装;类型定义统一收敛到 `src/types/api.d.ts`。
|
||||
|
||||
## 完成定义
|
||||
- 侧边栏中的“订单管理”不再是禁用入口,能正常进入 `#/subscriptions/orders`。
|
||||
- 订单列表可真实连接 `/order/fetch`,并响应搜索、筛选、排序与分页。
|
||||
- 订单详情抽屉可真实连接 `/order/detail`,且能触发已支付、取消、佣金状态更新。
|
||||
- 分配订单抽屉可真实连接 `/order/assign`。
|
||||
- 订单金额相关字段统一正确展示为人民币元值。
|
||||
|
||||
## 文件结构
|
||||
- `admin-frontend/src/router/index.ts`
|
||||
- `admin-frontend/src/layouts/AdminLayout.vue`
|
||||
- `admin-frontend/src/api/admin.ts`
|
||||
- `admin-frontend/src/types/api.d.ts`
|
||||
- `admin-frontend/src/utils/orders.ts`
|
||||
- `admin-frontend/src/views/subscriptions/OrdersView.vue`
|
||||
- `admin-frontend/src/views/subscriptions/OrdersView.scss`
|
||||
- `admin-frontend/src/views/subscriptions/OrderAssignDrawer.vue`
|
||||
- `admin-frontend/src/views/subscriptions/OrderDetailDrawer.vue`
|
||||
|
||||
## UI / 设计约束
|
||||
- 列表页以白色工作台为主,不堆叠多余卡片;重点放在表格可读性与运营效率。
|
||||
- 订单号作为主入口,点击后进入详情抽屉,不额外拉长操作列。
|
||||
- 筛选入口使用紧凑 pill 风格按钮,对齐截图中的轻量筛选条。
|
||||
- 详情抽屉用黑色 hero + 白色信息卡的节奏,兼顾 Apple 风格与运营后台的信息密度。
|
||||
|
||||
## 风险与验证
|
||||
- 风险 1:`/order/fetch` 返回的 `period` 已被后端转换成 legacy key,筛选时需要继续使用数据库真实值。
|
||||
- 风险 2:订单金额与佣金金额在后端仍以分为单位存储,若前端直接展示会再次出现后台金额口径错误。
|
||||
- 风险 3:本地环境缺少真实后台登录态时,只能做结构与构建验证,不能替代完整联调。
|
||||
- 验证方式:
|
||||
- `npm run build`
|
||||
- 代码级结构自检 `#/subscriptions/orders`
|
||||
- 结构化视觉验收记录(无浏览器工具时以 code inspection 说明边界)
|
||||
|
||||
## 决策记录
|
||||
- [2026-04-24] 订单主操作收口到详情抽屉,不额外新增宽操作列,优先对齐用户截图。
|
||||
- [2026-04-24] 金额展示统一由 `src/utils/orders.ts` 处理,避免分/元换算逻辑散落在页面组件。
|
||||
- [2026-04-24] 分配订单抽屉默认按所选套餐周期自动回填金额,但允许运营手动覆盖。
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
# admin-frontend 订单管理首版交付 — 需求
|
||||
|
||||
确认后冻结,执行阶段不可修改。如需变更必须回到设计阶段重新确认。
|
||||
|
||||
## 核心目标
|
||||
- 在 `admin-frontend` 中开放“订阅管理 / 订单管理”入口,不再保留禁用态。
|
||||
- 参考用户提供的订单管理截图,交付真实订单列表页,覆盖搜索、筛选、排序、分页与详情查看。
|
||||
- 保持 `apple/DESIGN.md` 与 `.helloagents/DESIGN.md` 定义的 Apple 化后台视觉语言,但优先贴近截图中的数据密集型运营视图。
|
||||
|
||||
## 功能边界
|
||||
- 必须实现 `#/subscriptions/orders` 真实页面。
|
||||
- 页面必须包含:
|
||||
- 添加订单入口
|
||||
- 订单号搜索
|
||||
- 类型 / 周期 / 订单状态 / 佣金状态筛选
|
||||
- 支持排序的订单表格
|
||||
- 订单详情抽屉
|
||||
- 分配订单抽屉
|
||||
- 必须接入现有 Laravel 管理接口:
|
||||
- `GET /order/fetch`
|
||||
- `POST /order/detail`
|
||||
- `POST /order/assign`
|
||||
- `POST /order/paid`
|
||||
- `POST /order/cancel`
|
||||
- `POST /order/update`
|
||||
- 详情抽屉至少支持:
|
||||
- 查看订单核心信息与金额拆解
|
||||
- 对待支付订单手动标记已支付
|
||||
- 对待支付订单取消
|
||||
- 对有佣金金额的订单更新佣金状态
|
||||
|
||||
## 非目标
|
||||
- 本轮不实现礼品卡管理真实页面。
|
||||
- 本轮不改造 Laravel 订单后端接口逻辑。
|
||||
- 本轮不新增批量操作、多选导出或订单打印等扩展功能。
|
||||
|
||||
## 技术约束
|
||||
- 技术栈固定为 `Vue 3 + TypeScript + Vite + Element Plus`。
|
||||
- 后端真相源以仓库内 `App\Http\Controllers\V2\Admin\OrderController` 为准。
|
||||
- 构建验证使用 `admin-frontend/package.json` 中已有 `npm run build`。
|
||||
|
||||
## 质量要求
|
||||
- 订单页面需要对齐截图中的高密度表格工作流,同时保持 Apple 化后台的克制风格。
|
||||
- 金额字段必须统一处理“后端以分存储、前端以元展示”的换算。
|
||||
- 页面需覆盖加载、错误、空状态与成功反馈。
|
||||
- 最终至少完成一次构建验证,并留下结构化视觉验收与交付证据。
|
||||
@@ -0,0 +1,14 @@
|
||||
# admin-frontend 订单管理首版交付 — 任务分解
|
||||
|
||||
## 任务列表
|
||||
- [x] 任务1:补齐订单管理的方案与知识产物(涉及文件:`.helloagents/archive/2026-04/202604241620_admin-frontend-order-management/*`;完成标准:存在需求、方案、任务与合同文件;验证方式:文件检查)
|
||||
- [x] 任务2:开放导航与路由入口(涉及文件:`admin-frontend/src/layouts/AdminLayout.vue`、`admin-frontend/src/router/index.ts`;完成标准:侧边栏可进入 `#/subscriptions/orders`;验证方式:`npm run build`)
|
||||
- [x] 任务3:补齐订单 API、类型与工具层(涉及文件:`admin-frontend/src/api/admin.ts`、`admin-frontend/src/types/api.d.ts`、`admin-frontend/src/utils/orders.ts`;完成标准:前端可消费 `order/*` 接口并统一金额/状态映射;验证方式:`npm run build`)
|
||||
- [x] 任务4:实现订单列表页(涉及文件:`admin-frontend/src/views/subscriptions/OrdersView.vue`、`admin-frontend/src/views/subscriptions/OrdersView.scss`;完成标准:列表页支持搜索、筛选、排序、分页与详情入口;验证方式:`npm run build`)
|
||||
- [x] 任务5:实现分配订单与详情抽屉(涉及文件:`admin-frontend/src/views/subscriptions/OrderAssignDrawer.vue`、`admin-frontend/src/views/subscriptions/OrderDetailDrawer.vue`;完成标准:支持分配订单、查看详情、手动支付、取消订单与佣金状态维护;验证方式:`npm run build`)
|
||||
- [x] 任务6:完成验证与知识库同步(涉及文件:`.helloagents/CHANGELOG.md`、`.helloagents/context.md`、`.helloagents/modules/admin-frontend.md`、`.helloagents/.ralph-visual.json`、`.helloagents/.ralph-closeout.json`;完成标准:构建通过、知识库更新、交付证据写入;验证方式:命令输出 + 证据文件)
|
||||
|
||||
## 进度
|
||||
- [x] 已确认订单管理首版范围,聚焦真实列表、详情抽屉与分配订单。
|
||||
- [x] 已完成订单管理页面、抽屉与订单接口接入。
|
||||
- [x] 已完成构建验证,待输出最终交付摘要。
|
||||
@@ -7,6 +7,11 @@
|
||||
|
||||
| 时间戳 | 名称 | 类型 | 涉及模块 | 决策 | 结果 |
|
||||
|--------|------|------|---------|------|------|
|
||||
| 202604241620 | admin-frontend-order-management | implementation | admin-frontend | admin-frontend-order-management#D001,#D002,#D003 | ✅完成 |
|
||||
| 202604241558 | admin-frontend-payment-management | implementation | admin-frontend | admin-frontend-payment-management#D001,#D002,#D003 | ✅完成 |
|
||||
| 202604241553 | admin-frontend-plugin-management | implementation | admin-frontend | admin-frontend-plugin-management#D001,#D002,#D003 | ✅完成 |
|
||||
| 202604241607 | admin-frontend-theme-management | implementation | admin-frontend | admin-frontend-theme-management#D001,#D002 | ✅完成 |
|
||||
| 202604241551 | admin-frontend-coupon-management | implementation | admin-frontend | admin-frontend-coupon-management#D001,#D002,#D003 | ✅完成 |
|
||||
| 202604232345 | traffic-rank-limit-backend-adapt | implementation | admin-frontend,backend | traffic-rank-limit-backend-adapt#D001,#D002 | ✅完成 |
|
||||
| 202604232329 | admin-frontend-system-management | implementation | admin-frontend | admin-frontend-system-management#D001,#D002,#D003 | ✅完成 |
|
||||
| 202604232320 | admin-frontend-node-management | implementation | admin-frontend | admin-frontend-node-management#D001,#D002 | ✅完成 |
|
||||
@@ -24,6 +29,11 @@
|
||||
## 按月归档
|
||||
|
||||
### 2026-04
|
||||
- [202604241620_admin-frontend-order-management](./2026-04/202604241620_admin-frontend-order-management/) - 开放“订单管理”入口,交付真实订单列表、筛选、分配订单、详情抽屉、手动支付与佣金状态维护
|
||||
- [202604241558_admin-frontend-payment-management](./2026-04/202604241558_admin-frontend-payment-management/) - 将 `#/system/payments` 从占位页升级为真实支付配置工作台,接入支付方式列表、动态配置抽屉、启停、删除与排序
|
||||
- [202604241553_admin-frontend-plugin-management](./2026-04/202604241553_admin-frontend-plugin-management/) - 将 `#/system/plugins` 从占位页升级为真实插件管理工作台,接入插件列表、筛选、上传、安装、启停、升级、卸载,以及 README / 动态配置抽屉
|
||||
- [202604241607_admin-frontend-theme-management](./2026-04/202604241607_admin-frontend-theme-management/) - 将 `#/system/themes` 从占位页升级为真实主题管理页面,接入主题列表、当前主题切换、动态配置抽屉与 zip 主题上传
|
||||
- [202604241551_admin-frontend-coupon-management](./2026-04/202604241551_admin-frontend-coupon-management/) - 开放“优惠券管理”入口,完整交付优惠券列表、类型筛选、启停、删除,以及接入真实 coupon 接口的新增/编辑弹窗
|
||||
- [202604232345_traffic-rank-limit-backend-adapt](./2026-04/202604232345_traffic-rank-limit-backend-adapt/) - traffic rank 接口新增 limit=10|20 支持,并让 dashboard 的 10/20 切换真正驱动后端返回条数
|
||||
- [202604232329_admin-frontend-system-management](./2026-04/202604232329_admin-frontend-system-management/) - 新增“系统管理”侧边栏分组,完整交付系统配置页,并接入插件/主题/公告/支付/知识库结构化占位页
|
||||
- [202604232320_admin-frontend-node-management](./2026-04/202604232320_admin-frontend-node-management/) - 新增“节点管理”侧边栏分组、节点管理工作台,以及权限组/路由管理占位页
|
||||
|
||||
Reference in New Issue
Block a user