fix: some

This commit is contained in:
luo
2026-09-17 12:16:20 +08:00
parent 2308d82d0f
commit 76d4e4ec02
126 changed files with 11671 additions and 294 deletions

View File

@@ -0,0 +1,38 @@
# Design: H5 运营弹窗配置管理(管理后台)
## 页面结构
- 设置管理下新增「H5运营弹窗配置」入口仅超管/平台):
- 列表页 `src/views/settings/h5-popup-configuration/index.vue`
- 创建/编辑表单弹窗(复用 ArtForm + ArtSearchBar/ArtTable 模式)
- 详情以弹窗/抽屉展示完整配置
- 分页、筛选、表格沿用 ArtTable / ArtSearchBar / ArtTableHeader 与统一响应结构(`code/msg/timestamp/data`、分页 `items/page/size/total`)。
## 接口与类型
- 新增 `src/api/modules/h5PopupConfiguration.ts``src/types/api/h5PopupConfiguration.ts`
- `GET /api/admin/h5-popup-configurations`page/page_size/enabled倒序分页
- `POST /api/admin/h5-popup-configurations`(创建)
- `GET /api/admin/h5-popup-configurations/{id}`(详情)
- `PUT /api/admin/h5-popup-configurations/{id}`(更新,整表提交,版本 +1
- `POST /api/admin/h5-popup-configurations/{id}/enable``{id}/disable`(请求体 `{ id }`,返回更新后配置)
- 枚举映射常量集中放置:`pages`home/asset_detail/package_purchase/asset_wallet_recharge`frequency`once/daily`action_type`package_purchase/asset_wallet_recharge空字符串 = 无)、`card_types`CMCC/CUCC/CTCC/CBN
## 表单约定
- `pages` 多选必填(空数组非法);`title`1100/`content`12000/`frequency`/起止时间必填。
- 范围三选器(店铺/设备类型/卡类型)空数组 = 全量,回显「全部」。
- 起止时间用 datetimerange提交转 ISO 8601`starts_at`/`ends_at``ends_at` 不得早于 `starts_at`
- `priority` 数字输入01000000`enabled` 开关;`action_type` 下拉(含「无」选项,提交空字符串清除受控动作)。
- 编辑表单整表提交;编辑保存成功后提示「每次更新版本递增,旧版本通知保留原快照,新版本可向原命中客户按频率重新投放一次」。
- 启用/停用为行操作(停用需二次确认),以接口返回的更新后配置刷新当前行。
## 权限与可见性
- 权限码:`h5_popup_configuration:list`(菜单/列表)、`:create``:update``:enable``:disable`
- 路由 `meta.permissions` + 按钮 `v-permission`/`usePermission`,仅超管/平台可见;代理/企业/个人由后端 403 兜底并原文透传失败文案。
- 不提供删除入口(文档无 DELETE 接口)。
## 待确认
- 权限编码以后端菜单配置为准(前端默认 `h5_popup_configuration:list/create/update/enable/disable`)。

View File

@@ -0,0 +1,46 @@
# Change: 新增 H5 运营弹窗配置管理(管理后台)
## Why
H5 端(个人客户)需要在首页、资产详情、套餐购买、资产钱包充值等页面投放运营/风险弹窗,弹窗文案、命中页面、投放范围与生效规则需要后台配置。当前后台没有任何弹窗配置入口,运营只能走数据库操作。
本 Change 为管理后台新增「H5 运营弹窗配置」管理能力:配置标题与正文、命中页面、投放范围(店铺/设备类型/卡类型)、优先级、投放频率、生效时间与启停。
H5 端契约(`GET /api/c/v1/popup-candidates``POST /api/c/v1/risk-exchanges/{asset_id}/address`、通知列表/未读/已读接口)不在本 Change 范围,需求方已明确不处理 C 端。
## What Changes
- 新增 6 个后台接口(仅超管/平台,代理/企业/个人 403
- `GET /api/admin/h5-popup-configurations`:配置列表,`page`110000/ `page_size`1100/ `enabled` 筛选,按最近更新时间倒序分页返回 `items/page/size/total`
- `POST /api/admin/h5-popup-configurations`:创建;`title`/`content`/`pages`/`frequency`/`starts_at`/`ends_at` 必填;`priority`/`enabled`/`action_type`/`shop_ids`/`device_types`/`card_types` 可选(范围集合空数组 = 全量)。
- `GET /api/admin/h5-popup-configurations/{id}`:详情(含 `version``frequency_text``enabled_text``creator`/`updater`)。
- `PUT /api/admin/h5-popup-configurations/{id}`:更新;成功即版本 +1新版本可向原命中客户按频率重新投放一次旧版本已投放通知的内容与快照不被改写`id` 外全部字段可选,**不传保持原值**`action_type` 传空字符串 = 清除受控动作;`shop_ids`/`device_types`/`card_types` 传空数组 = 改为全量;`pages` 传空数组非法(页面必选);`enabled` 不传保持原值(启停刷新最近更新时间);`ends_at` 不得早于 `starts_at``content` 12000 字符、`title` 1100 字符、`priority` 01000000。
- `POST /api/admin/h5-popup-configurations/{id}/enable`:启用,参与候选匹配,刷新 `updated_at`(影响同优先级排序),返回更新后的配置。
- `POST /api/admin/h5-popup-configurations/{id}/disable`:停用,停止新投放,历史通知在展示期内仍可见;刷新 `updated_at`,返回更新后的配置。
- 新增「H5 运营弹窗配置」管理页(设置管理下,仅超管/平台可见):分页列表 + 创建/编辑表单 + 详情 + 行操作启用/停用。
- 前端契约约定:
- 范围集合 `shop_ids` / `device_types` / `card_types` 空数组 = 全量,列表与编辑回显「全部」。
- 枚举:`pages` = home / asset_detail / package_purchase / asset_wallet_recharge`frequency` = once / daily`action_type` = package_purchase / asset_wallet_recharge空字符串 = 无受控动作);`card_types` = CMCC / CUCC / CTCC / CBN。
- 无「删除」接口,页面不提供删除入口;停用不清数据,列表保留历史配置。
- 编辑表单整表提交(所有字段都传,未传语义仅在部分更新时生效);范围清空传空数组、动作清除传空字符串、页面集合不可为空。
- 权限编码由前端确定:`h5_popup_configuration:list` / `:create` / `:update` / `:enable` / `:disable`
## Impact
- Affected specs:
- `h5-popup-configuration-management`
- Affected code:
- `src/api/modules/h5PopupConfiguration.ts`(新增)
- `src/types/api/h5PopupConfiguration.ts`(新增)
- `src/api/modules/index.ts``src/types/api/index.ts`
- `src/config/constants/`(权限码常量)
- `src/router/routesAlias.ts``src/router/routes/asyncRoutes.ts`(设置管理下新增菜单与路由)
- `src/locales/langs/zh.json``src/locales/langs/en.json`
- `src/views/settings/h5-popup-configuration/`(列表、表单弹窗、详情)
- Dependencies:
- 后端按 `docs/产品迭代8月份/通知.md` 提供上述 6 接口Bearer JWT 鉴权,代理/企业/个人 403。
- Breaking changes:
- 无;全部为新增页面、接口模块与类型。
- 待确认:
- 权限编码(前端默认 `h5_popup_configuration:list/create/update/enable/disable`)以后端菜单配置为准。
- 列表分页上限与「按最近更新时间倒序」以文档为准,联调核对后端行为。

View File

@@ -0,0 +1,117 @@
## ADDED Requirements
### Requirement: H5 运营弹窗配置列表
后台 MUST 提供 H5 运营弹窗配置的分页列表GET /api/admin/h5-popup-configurations支持 `page`110000/ `page_size`1100/ `enabled` 筛选,按最近更新时间倒序返回 `items/page/size/total`;列表项 MUST 包含标题、命中页面、范围(店铺/设备类型/卡类型)、优先级、频率(`frequency_text`)、启停(`enabled_text`)、受控动作、生效起止时间、版本、创建/更新人与时间。
#### Scenario: 按启停状态筛选并分页
- **GIVEN** 超管/平台账号进入「H5运营弹窗配置」列表
- **WHEN** 以 page/page_size/enabled 发起查询
- **THEN** 前端 MUST 展示分页结果(后端按最近更新时间倒序)
- **AND** 切换 enabled 筛选后按新条件重新请求
#### Scenario: 范围空数组显示全部
- **GIVEN** 某条配置的 shop_ids/device_types/card_types 为空数组
- **THEN** 列表 MUST 在范围列展示「全部」
#### Scenario: 越权访问
- **GIVEN** 代理/企业/个人账号访问列表接口或直达路由
- **THEN** 后端 MUST 返回 403前端 MUST NOT 渲染入口
- **AND** 失败文案 MUST 按后端返回原文透传
### Requirement: 创建弹窗配置
后台 MUST 支持创建 H5 运营弹窗配置POST /api/admin/h5-popup-configurations`title`/`content`/`pages`/`frequency`/`starts_at`/`ends_at` 必填;`priority`/`enabled`/`action_type`/`shop_ids`/`device_types`/`card_types` 可选,范围集合空数组 = 全量。
#### Scenario: 必填校验
- **GIVEN** 用户提交创建表单
- **WHEN** title/content/pages/frequency/starts_at/ends_at 任一缺失
- **THEN** 前端 MUST 拦截并提示必填MUST NOT 发送请求
#### Scenario: 范围集合为空数组表示全量
- **GIVEN** 用户未选择店铺/设备类型/卡类型范围
- **THEN** 请求体对应数组 MUST 传空数组,后端按全量投放处理
### Requirement: 弹窗配置详情
后台 MUST 提供弹窗配置详情GET /api/admin/h5-popup-configurations/{id}),返回完整配置含 `version``frequency_text``enabled_text``creator`/`updater`
#### Scenario: 查看详情
- **GIVEN** 用户点击列表行「详情」
- **WHEN** 请求详情成功
- **THEN** 前端 MUST 展示完整配置要素(含版本与启停/频率中文名)
### Requirement: 更新弹窗配置
后台 MUST 支持更新弹窗配置PUT /api/admin/h5-popup-configurations/{id}),成功即版本 +1新版本可向原命中客户按频率重新投放一次旧版本已投放通知的内容与快照不被改写。除 `id` 外所有字段均可选,**不传保持原值**`action_type` 传空字符串 = 清除受控动作;`shop_ids`/`device_types`/`card_types` 传空数组 = 改为全量;`pages` 传空数组非法(页面必选);`enabled` 不传保持原值(启停刷新最近更新时间);`ends_at` 不得早于 `starts_at``content` 12000 字符、`title` 1100 字符、`priority` 01000000。
#### Scenario: 更新成功版本递增并重新投放
- **GIVEN** 用户保存编辑
- **WHEN** 更新成功
- **THEN** 前端 MUST 提示「每次更新版本递增,旧版本通知保留原快照,新版本可向原命中客户按频率重新投放一次」并刷新列表
- **AND** 列表/详情版本号较更新前 +1旧版本已投放通知内容不被改写
#### Scenario: 范围清空表示改为全量
- **GIVEN** 编辑时清空某范围集合
- **THEN** 提交对应数组 MUST 为空数组,后端按全量处理
#### Scenario: 受控动作清除
- **GIVEN** 编辑时把 action_type 从 package_purchase 切换为「无」
- **THEN** 请求体 action_type MUST 传空字符串,后端清除受控动作
#### Scenario: 页面集合不得为空
- **GIVEN** 编辑时清空全部命中页面
- **THEN** 前端 MUST 拦截提示命中页面必选MUST NOT 传空 pages 数组
#### Scenario: 未传字段保持原值
- **GIVEN** 请求体省略某字段(如 enabled
- **THEN** 后端 MUST 保持原值;前端编辑表单整表提交,范围清空按空数组、动作清除按空字符串处理
### Requirement: 启用与停用弹窗配置
后台 MUST 支持启用/停用弹窗配置POST /api/admin/h5-popup-configurations/{id}/enable、/{id}/disable请求体 `{ id }`,返回更新后的配置),停用停止新投放且历史通知在展示期内仍可见,启用参与候选匹配;两者均刷新最近更新时间(影响同优先级排序)且不递增版本。
#### Scenario: 停用需二次确认
- **GIVEN** 用户点击某启用的配置「停用」
- **WHEN** 二次确认提交
- **THEN** 前端 MUST 调用 disable 并提示「停用后停止新投放,历史通知在展示期内仍可见」
- **AND** 以返回的更新后配置刷新当前行(状态为停用、最近更新时间更新、版本不变)
#### Scenario: 启用
- **GIVEN** 用户点击某停用的配置「启用」
- **THEN** 前端 MUST 调用 enable 并提示「启用后参与候选匹配」
- **AND** 以返回的更新后配置刷新当前行(状态为启用、最近更新时间更新、版本不变)
### Requirement: 角色权限与交互约定
弹窗配置入口 MUST 仅对超级管理员与平台账号可见;前端权限码固定为 `h5_popup_configuration:list`(菜单/列表)、`:create``:update``:enable``:disable`;页面 MUST NOT 提供删除入口(文档无 DELETE 接口);停用不清数据,列表保留历史配置。
#### Scenario: 入口按角色隐藏
- **GIVEN** 代理/企业/个人账号登录
- **WHEN** 系统渲染菜单
- **THEN** MUST NOT 展示「H5运营弹窗配置」菜单项
#### Scenario: 按钮权限码控制
- **GIVEN** 账号具备列表权限但缺 enable/disable 权限
- **THEN** 前端 MUST 只渲染具备权限的操作按钮
#### Scenario: 不提供删除入口
- **GIVEN** 用户查看列表或详情
- **THEN** 页面 MUST NOT 出现删除操作,仅提供启用/停用

View File

@@ -0,0 +1,43 @@
## 1. Contract Confirmation
- [x] 1.1 权限编码前端确定:`h5_popup_configuration:list` / `:create` / `:update` / `:enable` / `:disable`(以后端菜单配置为准)。
- [x] 1.2 更新接口语义按文档:不传保持原值;`action_type` 空串 = 清除;范围空数组 = 改全量;`pages` 空数组非法;`enabled` 不传保持原值;`ends_at` 不得早于 `starts_at``content` 12000、`title` 1100、`priority` 01000000更新成功版本 +1 且旧版本通知不被改写。
- [x] 1.3 `enable`/`disable` 请求体 `{ id }`,返回更新后的 DtoH5PopupConfigurationResponse。
- [x] 1.4 列表 `page` 110000、`page_size` 1100、`enabled` 筛选,按最近更新时间倒序分页。
## 2. API And Types
- [ ] 2.1 新增 `src/api/modules/h5PopupConfiguration.ts`:列表、创建、详情、更新、启用、停用 6 个接口。
- [ ] 2.2 新增 `src/types/api/h5PopupConfiguration.ts`:请求/响应 DTO含 pages/frequency/action_type/card_types 枚举、范围集合、version、creator/updater 等;更新语义按「不传保持原值/空数组=全量/空串=清除」注释)。
- [ ] 2.3 在 `src/api/modules/index.ts``src/types/api/index.ts` 导出新模块/类型。
- [ ] 2.4 对齐统一响应 `code/msg/timestamp/data` 与分页 `items/page/size/total`
## 3. List Page
- [ ] 3.1 设置管理下新增「H5运营弹窗配置」菜单与路由仅超管/平台可见,权限码 `h5_popup_configuration:list`)。
- [ ] 3.2 列表:`page`/`page_size`/`enabled` 筛选,分页展示,按后端倒序。
- [ ] 3.3 列:标题、命中页面、范围(店铺/设备类型/卡类型,空数组显示「全部」)、优先级、频率、启停状态、受控动作、生效起止、版本、创建/更新人与时间。
- [ ] 3.4 行操作:详情、编辑、启用/停用(停用需二次确认);无删除入口。
## 4. Create / Edit / Detail
- [ ] 4.1 创建表单:`title`/`content`/`pages` 多选/`frequency`/起止时间必填校验pages 非空);`priority`/`enabled`/`action_type`/范围可选。
- [ ] 4.2 范围集合 `shop_ids`/`device_types`/`card_types` 空数组 = 全量;编辑读回空数组显示「全部」。
- [ ] 4.3 编辑表单整表提交;保存成功提示「每次更新版本递增,旧版本通知保留原快照,新版本可向原命中客户按频率重新投放一次」。
- [ ] 4.4 编辑支持 `action_type` 清空(「无」→ 空字符串)与 `ends_at` 不早于 `starts_at` 的前端校验。
- [ ] 4.5 详情(弹窗/抽屉)展示完整配置(含 version、frequency_text、enabled_text、creator/updater
## 5. Permissions And UX
- [ ] 5.1 按钮/入口按 `h5_popup_configuration:list/create/update/enable/disable` 接入 `usePermission`/`v-permission`,无权限不渲染。
- [ ] 5.2 固定提示停用「停用后停止新投放历史通知在展示期内仍可见」启用「启用后参与候选匹配」403 文案原文透传。
- [ ] 5.3 表单校验与请求失败提示稳定,不破坏列表渲染。
## 6. Verification
- [ ] 6.1 `vue-tsc --noEmit` 与新增文件 eslint 通过。
- [ ] 6.2 列表筛选/分页/倒序展示正确。
- [ ] 6.3 创建必填校验、范围全量语义、编辑版本 +1 提示正确。
- [ ] 6.4 启用/停用流程与提示正确;停用不清数据;启停不递增版本、刷新最近更新时间。
- [ ] 6.5 代理/企业/个人看不到入口;直达路由 403 文案透传。
- [ ] 6.6 联调:编辑整表提交后版本 +1、启停返回完整配置并刷新行`ends_at` 早于 `starts_at` 被后端拒绝。