Files
dukang/docs/杜康好客-v3.5.8-开发文档.md
T
jacy 5935024ea8
CI / verify (pull_request) Waiting to run
v3.5.8和v3.5.9版本更新
2026-08-25 09:20:32 +08:00

133 lines
5.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 杜康好客 · v3.5.8 开发文档
> **2026-08-24** · admin-web / API
> **主题**:HQ 单账号追加/撤销权限、运营改客服修复、城市门店服务角色与城市范围
---
## 1. 版本目标
1. **单账号权限** 在角色基础上可追加,也可撤销某项功能。
2. **运营 → 客服** 可保存成功,且生效权限跟随新角色(清空账号级追加/撤销)。
3. **新分组「城市门店服务」**:默认门店列表、审核通知、评价、分类;按账号勾选城市,非勾选城市的门店不可见。
4. 任意 HQ 账号都可绑城市;**未勾选 = 全国**。该新角色 **必须至少 1 个城市**
5. 超管始终全权限、全国可见,不受撤销/城市限制。
**不做**:C 端 / 合伙人 / 门店端;按区分权;小程序版本号。
---
## 2. 权限模型
公式:`生效权限 = (角色权限 ∪ 账号追加) − 账号撤销`
| 层 | 存储 | 说明 |
|----|------|------|
| 角色 | `hq_role_permission` | 分组默认能力,超管基础权限固定 |
| 账号追加 | `hq_account_permission.effect=GRANT` | 在角色之上加点权限 |
| 账号撤销 | `hq_account_permission.effect=DENY` | 去掉角色已有的某项 |
同一账号同一权限键只能 GRANT 或 DENY。切换角色时清空该账号 GRANT/DENY。
### 2.1 角色
| 值 | 标签 | 默认 |
|----|------|------|
| SUPER_ADMIN | 超级管理员 | 目录全部(含调试;危险操作需按用户勾选) |
| OPS | 运营 | 与现网一致,且含拆分后的门店子权限 |
| FINANCE | 财务 | 同上(含门店子权限) |
| CUSTOMER_SERVICE | 客服 | dashboard / users / orders / tickets / tech_support / invoices / logs |
| CITY_STORE_SERVICE | 城市门店服务 | dashboard、stores、store_audits、store_ratings、store_categories**无** store_categories_delete |
### 2.2 门店权限拆分
| 键 | 菜单 |
|----|------|
| `stores` | 门店列表(含入驻审核) |
| `store_audits` | 审核通知(套餐变更 / 信息变更) |
| `store_ratings` | 门店评价 |
| `store_categories` | 门店分类(全国字典,不按城过滤;可新增/编辑) |
| `store_categories_delete` | 删除门店分类 / 同步默认分类(危险操作;运营/财务默认有,城市门店服务无) |
| `store_accounts` | 门店账户 |
| `store_media` | 门店资源 |
存量角色/账号若已有 `stores`,迁移一次性补齐后 5 键(行为与拆分前一致)。新角色不补账户/资源。删除分类键另按「非城市门店服务 + 已有分类权限」补齐。
---
## 3. 城市范围
-`hq_account_city`;空列表且非「城市门店服务」= 全国。
- 「城市门店服务」保存时必须 ≥1 城;若数据异常无城市,则看不到任何门店。
- 有范围时:列表/详情/审核/评价/账户/资源均 `Store.cityId IN (...)`;越权 403「无权访问该城市的门店」。
- 概览 `GET /admin/dashboard/stats|analytics`:按生效权限裁剪指标;有城市范围时只统计负责城市(无「未选城」)。
- `GET /admin/auth/me` 返回 `cityIds``cityScoped`
---
## 4. 运营改客服修复
1. 短信账号 `loginName` 为空时,编辑提交空字符串不再报「用户名不能为空」(视为不改)。
2. 切换角色清空账号级权限,避免运营追加的门店等权限带到客服。
3. 改为「城市门店服务」时若未绑城市则拒绝。
---
## 5. Prisma / SQL
- `HqAdminRole` 增加 `CITY_STORE_SERVICE`
- `HqPermissionEffect``GRANT` / `DENY``hq_account_permission.effect`
- `hq_account_city`
脚本:[`server/dukang-api/prisma/migrate-hq-permissions-v358.sql`](../server/dukang-api/prisma/migrate-hq-permissions-v358.sql)
已跑过主脚本的库补删除分类键:[`migrate-hq-permissions-v358-categories-delete.sql`](../server/dukang-api/prisma/migrate-hq-permissions-v358-categories-delete.sql)
---
## 6. API
| 方法 | 路径 | 说明 |
|------|------|------|
| GET/PUT | `/admin/hq-permissions/accounts/:id` | 返回/保存 `grantKeys``denyKeys` |
| PUT | `/admin/hq-accounts/:id` | 可传 `cityIds`;空 loginName 忽略 |
| GET | `/admin/auth/me` | `permissionKeys` + `cityIds` + `cityScoped` |
门店相关 HQ 接口加 `HqPermissionGuard` 对应键。
---
## 7. 发版步骤
| 步骤 | 动作 |
|------|------|
| 1 | 执行 `migrate-hq-permissions-v358.sql``prisma db push` |
| 2 | `pnpm build`shared-types + API + admin-web |
| 3 | 发 `dukang-api` + `admin-web` |
---
## 8. 关键路径
| 域 | 路径 |
|----|------|
| 权限目录/公式 | `packages/shared-types/src/hq-permissions.ts` |
| 生效解析 | `hq-permission.guard.ts` |
| 账号/城市 | `admin-hq-accounts.service.ts` |
| 权限页 | `HqPermissionsPage.tsx` |
| 账户页 | `HqAccountsPage.tsx` |
| 菜单 | `AdminLayout.tsx` |
| 门店范围 | `admin-stores.service.ts`、套餐/信息变更审核、评价 |
---
## 9. 验收清单
- [ ] 按用户分配:可追加非角色权限,可取消角色已有权限(撤销后菜单与 API 均不可用)
- [ ] 短信登录的运营账号改为客服:保存成功;刷新后无运营菜单
- [ ] 新建「城市门店服务」不选城市无法保存;选城后仅见这些城市的门店/审核/评价
- [ ] 直链其他城市门店详情/审核 403
- [ ] 该角色默认无「门店账户」「门店资源」;运营原菜单不变
- [ ] 超管仍全国、全权限
- [ ] 分类页可见但不按城过滤;城市门店服务可新增/编辑,无删除与「同步默认分类」
- [ ] 概览只显示有权限的卡片;城市范围账号仅统计负责城市