From f7f18f51788f0620d9bda603a95ee11d11a31ae5 Mon Sep 17 00:00:00 2001 From: richarjiang Date: Tue, 7 Apr 2026 09:35:28 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E6=B7=BB=E5=8A=A0=E4=BC=9A=E5=91=98?= =?UTF-8?q?=E5=8D=A1=E7=BC=96=E8=BE=91=E5=8A=9F=E8=83=BD=E8=AE=BE=E8=AE=A1?= =?UTF-8?q?=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.6 --- .../2026-04-07-member-card-edit-design.md | 186 ++++++++++++++++++ 1 file changed, 186 insertions(+) create mode 100644 docs/superpowers/specs/2026-04-07-member-card-edit-design.md diff --git a/docs/superpowers/specs/2026-04-07-member-card-edit-design.md b/docs/superpowers/specs/2026-04-07-member-card-edit-design.md new file mode 100644 index 0000000..a0df627 --- /dev/null +++ b/docs/superpowers/specs/2026-04-07-member-card-edit-design.md @@ -0,0 +1,186 @@ +# 会员卡编辑功能设计 + +**日期:** 2026-04-07 +**状态:** 已批准 + +--- + +## 1. 概述 + +在管理后台会员列表中,点击会员 item 时弹出的详情弹窗增加"编辑"能力。管理员可编辑指定用户的卡种、卡有效期、剩余次数,也可清空/解除会员卡。 + +**前置约束:** +- 一个用户只能拥有一张会员卡 +- 支持清空卡(解除会员资格) + +--- + +## 2. 交互设计 + +### 2.1 弹窗结构 + +``` +┌─────────────────────────────────┐ +│ 会员详情 [×] │ +├──────────┬──────────────────────┤ +│ 详情 │ 编辑 │ ← Tab 切换 +├──────────┴──────────────────────┤ +│ 头像 / 昵称 / OpenID / 手机号 │ +│ ───────────────────────────── │ +│ 会员卡信息区(根据 Tab 显示) │ +│ 预约统计(总/完成/取消) │ +│ ───────────────────────────── │ +│ [关闭] │ +└─────────────────────────────────┘ +``` + +### 2.2 无卡用户交互 + +- 详情 Tab 显示"暂无会员卡"提示 +- 显示"去开卡"按钮,点击切换到编辑 Tab +- 编辑 Tab 中卡种 picker 默认选中列表第一项,有效期自动计算 + +### 2.3 状态说明 + +| 场景 | Tab 初始显示 | 编辑表单状态 | +|------|-------------|-------------| +| 有卡用户 | 详情 Tab | 预填充当前数据 | +| 无卡用户 | 详情 Tab(提示无卡) | 空白表单,卡种默认选中第一项 | + +--- + +## 3. 表单字段 + +| 字段 | 组件 | 条件 | 说明 | +|------|------|------|------| +| 卡种 | picker | 必填 | 从 `CardType` 表读取,按 sortOrder 排序 | +| 剩余次数 | input (number) | TIMES / TRIAL 类型 | 默认填充卡种的 totalTimes | +| 生效日期 | date picker | 必填 | 默认当天 | +| 有效期至 | date picker | 必填 | 自动计算,支持手动调整 | + +### 3.1 卡种切换逻辑 + +切换卡种时: +1. `remainingTimes` 自动填充新卡种的 `totalTimes`(TIMES/TRIAL 类型) +2. `expireDate` 按新卡种 `durationDays` 重新计算起始日期 +3. 编辑器内手动修改过 `expireDate` 时,不再自动覆盖 + +--- + +## 4. API 设计 + +### 4.1 获取用户会员卡 + +``` +GET /admin/members/:userId/membership +``` + +**响应:** +```json +{ + "userId": "uuid", + "membership": { + "id": "uuid", + "cardTypeId": "uuid", + "remainingTimes": 10, + "startDate": "2026-01-01", + "expireDate": "2026-04-01", + "status": "ACTIVE", + "cardType": { ... } + } | null +} +``` + +### 4.2 创建或更新会员卡 + +``` +PUT /admin/members/:userId/membership +``` + +**请求体:** +```json +{ + "cardTypeId": "uuid", + "remainingTimes": 10, + "startDate": "2026-04-07", + "expireDate": "2026-07-07" +} +``` + +**业务逻辑:** +- 若该用户已有 membership → 更新 +- 若该用户无 membership → 创建新的 +- `status` 由后端根据 expireDate 和 remainingTimes 自动计算 + +### 4.3 解除会员卡 + +``` +DELETE /admin/members/:userId/membership +``` + +**业务逻辑:** +- 将 membership 的 `status` 标记为 `EXPIRED`(软删除,便于审计) +- 不物理删除记录 + +--- + +## 5. 数据模型 + +### 5.1 会员卡状态自动计算规则 + +``` +if (expireDate < now) → EXPIRED +else if (remainingTimes === 0) → USED_UP +else → ACTIVE +``` + +### 5.2 变更日志 + +通过现有的 `BookingStatusHistory` 表记录操作(tbd: 是否需要独立 `MembershipChangeLog` 表,待实现时确认)。 + +--- + +## 6. 错误处理 + +| 场景 | 处理 | +|------|------| +| 卡种不存在 | 后端返回 404,前端提示"卡种不存在" | +| 有效期早于生效日期 | 前端表单校验失败,提示"有效期不能早于生效日期" | +| 次数为负数 | 前端表单校验失败,提示"次数不能为负数" | +| 网络错误 | Toast 提示"网络错误,请重试" | +| 清空卡确认 | 弹出确认对话框,提示"确定要解除该用户的会员卡吗?" | + +--- + +## 7. 涉及改动 + +### 后端 + +- `packages/server/src/membership/membership.controller.ts` — 新增三个 admin 接口 +- `packages/server/src/membership/membership.service.ts` — 新增 `getUserMembership` / `updateUserMembership` / `deleteUserMembership` +- `packages/server/src/user/user.controller.ts` — 无改动(列表接口保持不变) + +### 前端 + +- `packages/app/src/stores/admin.ts` — 新增三个 store action +- `packages/app/src/pages/admin/members.vue` — 将详情弹窗改造为 Tab 模式,新增编辑表单 + +--- + +## 8. UI 细节 + +### 8.1 Tab 切换 + +- 详情/编辑 Tab 横向排列,激活态有下划线指示 +- 无卡用户点击"去开卡"后,自动切到编辑 Tab + +### 8.2 编辑表单提交 + +- 保存成功后 Toast 提示"保存成功" +- 自动切回详情 Tab 并刷新数据 +- 保存按钮点击后置灰,防止重复提交 + +### 8.3 清空卡 + +- 需二次确认 +- 成功后弹窗关闭,列表自动刷新