feat: 完善接口19-顶部通知铃铛与站内通知中心
All checks were successful
构建并部署前端到测试环境 / build-and-deploy (push) Successful in 4m5s

This commit is contained in:
luo
2026-07-25 10:20:53 +08:00
parent eb13763020
commit 9289a6e940
37 changed files with 1264 additions and 226 deletions

View File

@@ -0,0 +1,35 @@
## Context
临期结果由后端根据资产当前套餐及排队套餐计算。管理端需要在独立列表、普通资产列表、代理首页和通知中心保持相同的临期语义。本变更只覆盖管理端C 端资产和续费能力不纳入实现范围。
## Goals / Non-Goals
- Goals: 统一消费 `estimated_final_expires_at``days_until_final_expiry``expiry_level``expiry_level_name``can_renew`;提供临期查询、排序、高亮、统计、通知跳转和管理端续费入口。
- Goals: 由后端负责临期边界、预计到期结果和通知触发,前端只负责展示和路由。
- Non-Goals: 不计算套餐接续到期时间,不修改历史订单或已购套餐,不实现 C 端入口,不展示企微临期消息。
## Decisions
- Decision: 临期独立列表使用 `GET /api/admin/expiring-assets`,查询参数保持文档约定的 `asset_type``keyword``shop_id``package_id``days_min``days_max``expires_from``expires_to``page``size`
- Decision: 临期接口负责跨分页排序,返回结果按 0-3 天优先、其余按 `estimated_final_expires_at` 升序排列;前端只保留接口顺序,不改变普通资产列表原始接口排序。
- Decision: 颜色只按剩余天数映射8-15 天粉红、4-7 天紫色、0-3 天红色。已过期和不可预计记录由接口排除,前端不把它们补入临期列表。
- Decision: 续费入口由 `can_renew` 控制,具体续费动作复用现有管理端续费/充值路由和接口,不新增 C 端逻辑。
- Decision: 通知中心继续复用现有通知接口和目标跳转协议;临期通知由后端按 15 天、7 天、3 天生成,前端按通知目标跳转到临期列表或对应资产详情。
- Alternatives considered: 前端从普通资产列表筛选临期记录。Rejected because it无法保证全量、统一排序和后端预计最终到期结果的一致性。
## Risks / Trade-offs
- 风险代理首页当前概览接口未必已有临期计数字段。Mitigation在现有首页/概览响应中增加 `expiring_card_count``expiring_device_count`,避免前端分页统计。
- 风险不同资产列表的字段结构不完全一致。Mitigation在各自 API 类型中复用同一组临期字段语义,并通过统一展示格式处理空值和等级。
- 风险续费入口的现有路由可能依赖资产类型。Mitigation`asset_type``asset_id` 选择对应管理端续费入口,按钮仅在 `can_renew=true` 时展示。
## Migration Plan
1. 先扩展管理端 API 类型和服务,确认列表、首页统计和通知目标字段。
2. 上线临期列表及普通列表高亮,再接入首页统计和续费入口。
3. 最后验证通知中心过滤、已读和跳转,不修改 C 端功能。
## Open Questions
- 代理首页现有概览接口的具体路径和响应字段名称,需要以后端接口实现为准确认。
- 管理端卡/设备续费入口的现有路由是否统一,需实现时复用当前权限和路由定义。

View File

@@ -0,0 +1,35 @@
# Change: 增加管理端临期资产高亮、通知与续费入口
## Why
管理端目前缺少统一的临期资产查询入口,运营人员需要在普通资产列表中自行识别临近到期资产,且无法从临期记录快速进入续费操作。需要基于后端统一计算的预计最终到期结果,在管理端集中展示临期资产、标记普通列表并接入站内通知。
## What Changes
- 新增管理端临期资产列表,支持资产类型、关键字、店铺、套餐、剩余天数和预计到期时间筛选。
- 临期列表按 0-3 天固定置顶,其余按预计最终到期时间升序;已过期和不可预计资产不进入列表。
- 在卡列表、设备列表和资产相关列表中增加临期颜色高亮,但不改变普通列表原有排序。
- 在代理首页增加临期卡数量和临期设备数量展示,并可跳转临期列表。
- 在临期列表提供后端返回 `can_renew` 控制的续费入口,复用现有管理端续费/充值流程。
- 接入通知中心中的 15 天、7 天、3 天临期提醒及通知跳转;管理端不展示企微临期消息。
- 所有页面直接使用后端返回的预计最终到期字段和临期等级,不在前端重新计算最终到期时间。
## Impact
- Affected specs:
- `admin-expiring-assets`
- Affected code:
- `src/api/modules``src/types/api` 中的临期资产接口及类型
- 管理端临期资产列表页面和路由
- 网卡列表、设备列表及资产信息展示组件
- 代理首页统计组件
- 通知中心跳转处理
- API contracts:
- `GET /api/admin/expiring-assets`
- 现有代理首页/概览接口增加临期卡、设备数量字段,或提供等价的管理端统计响应
- 复用现有通知查询、已读和目标跳转接口
- Out of scope:
- C 端资产页临期展示
- C 端续费按钮和 C 端续费流程
- 企微临期消息展示或企微通知改造
- 前端根据套餐明细自行推导预计最终到期时间

View File

@@ -0,0 +1,111 @@
## ADDED Requirements
### Requirement: Admin Expiring Asset Query
The admin frontend SHALL provide an expiring asset list backed by `GET /api/admin/expiring-assets`. The query SHALL support `asset_type`, `keyword`, `shop_id`, `package_id`, `days_min`, `days_max`, `expires_from`, `expires_to`, `page`, and `size`.
#### Scenario: Filter expiring assets
- **WHEN** 管理端用户打开临期资产列表并提交筛选条件
- **THEN** 前端 MUST send the documented query parameters to `GET /api/admin/expiring-assets`
- **AND** 页面 MUST display the paginated response items
#### Scenario: Exclude unavailable assets
- **WHEN** 接口返回临期列表
- **THEN** 页面 MUST not add expired assets or assets without an estimable final expiry to the list on the client side
### Requirement: Expiring Asset Fields
Each expiring asset item SHALL preserve and display the backend fields `asset_type`, `asset_id`, `identifier`, `shop_name`, `package_name`, `estimated_final_expires_at`, `days_until_final_expiry`, `expiry_level`, `expiry_level_name`, and `can_renew`. The frontend MUST use backend-provided expiry results and MUST NOT calculate the estimated final expiry from package details.
#### Scenario: Display an estimable asset
- **WHEN** 临期接口返回资产及 `estimated_final_expires_at`
- **THEN** 页面 MUST display the asset identifier, shop, package, estimated final expiry, remaining days, and backend expiry level name
#### Scenario: Preserve backend result
- **WHEN** 临期接口返回 `estimated_final_expires_at``days_until_final_expiry`
- **THEN** 前端 MUST display the returned values
- **AND** 前端 MUST NOT derive or replace them from current or queued package data
### Requirement: Expiring List Ordering And Highlighting
The expiring asset API and standalone admin list SHALL return and preserve records with 0-3 remaining days first, then order the remaining records by `estimated_final_expires_at` ascending. The list SHALL apply pink highlighting to 8-15 days, purple highlighting to 4-7 days, and red highlighting to 0-3 days.
#### Scenario: Order critical assets first
- **GIVEN** the response contains assets in multiple expiry ranges
- **WHEN** 页面渲染临期列表
- **THEN** the API response MUST place assets with 0-3 remaining days before assets with more remaining days
- **AND** the API response MUST order records in the remaining ranges by estimated final expiry ascending
- **AND** the frontend MUST preserve that cross-page ordering
#### Scenario: Highlight by remaining days
- **WHEN** 页面渲染临期资产
- **THEN** 8-15 days MUST use the pink visual treatment
- **AND** 4-7 days MUST use the purple visual treatment
- **AND** 0-3 days MUST use the red visual treatment
### Requirement: Ordinary Admin Asset List Highlighting
The admin card and device lists SHALL apply the same expiry color treatment to returned expiring asset fields without changing their existing server or client sort order.
#### Scenario: Highlight ordinary asset rows
- **WHEN** 卡列表或设备列表返回临期字段
- **THEN** 页面 MUST apply the matching expiry color treatment
- **AND** 页面 MUST preserve the list's existing ordering
### Requirement: Admin Expiring Asset Renewal Entry
The admin expiring asset list SHALL display a renewal action only when the backend item has `can_renew=true`. The action SHALL navigate to the existing management-side renewal or recharge flow for the asset type.
#### Scenario: Renewable asset
- **GIVEN** 临期资产项返回 `can_renew=true`
- **WHEN** 用户查看临期列表
- **THEN** 页面 MUST provide the management-side renewal entry
- **AND** the entry MUST target the corresponding asset and preserve asset type context
#### Scenario: Non-renewable asset
- **GIVEN** 临期资产项返回 `can_renew=false`
- **WHEN** 用户查看临期列表
- **THEN** 页面 MUST NOT display an enabled renewal action
### Requirement: Agent Dashboard Expiry Counts
The agent-facing admin home SHALL display the number of expiring cards and expiring devices using backend-provided summary fields and SHALL provide navigation to the standalone expiring asset list.
#### Scenario: Display expiry counts
- **WHEN** 代理首页概览数据返回临期卡和设备数量
- **THEN** 页面 MUST display the expiring card count and expiring device count
- **AND** 页面 MUST not calculate the counts from a paginated asset list
### Requirement: Admin Expiry Notifications
The notification center SHALL display backend-generated admin expiry reminders for 15 days, 7 days, and 3 days through the existing notification API and target navigation. The admin frontend SHALL not display WeCom expiry messages.
#### Scenario: Display expiry reminder
- **WHEN** 通知接口返回 15 天、7 天或 3 天的临期提醒
- **THEN** 通知中心 MUST classify it as a 临期提醒
- **AND** 用户点击通知后 MUST navigate to the returned management-side target
#### Scenario: Exclude WeCom expiry message
- **WHEN** 管理端加载通知中心
- **THEN** 页面 MUST not add or render a separate WeCom expiry message channel
### Requirement: Admin-Only Scope
This capability SHALL be limited to the management frontend. It SHALL NOT add or modify C-end asset expiry display, C-end renewal buttons, C-end renewal APIs, or C-end notification behavior.
#### Scenario: Keep C-end unchanged
- **WHEN** this change is implemented
- **THEN** C-end asset pages and renewal flows MUST remain outside the change scope

View File

@@ -0,0 +1,35 @@
## 1. API Contract
- [x] 1.1 增加 `GET /api/admin/expiring-assets` 的查询参数、分页响应和临期资产项类型。
- [x] 1.2 为卡列表、设备列表、资产信息和首页概览类型补充统一临期字段及临期计数字段。
- [x] 1.3 增加临期资产 API 服务方法,并确认续费入口复用现有管理端服务和权限。
## 2. Expiring Asset List
- [x] 2.1 增加或接入 `/operations/expiring-assets` 管理端路由和页面。
- [x] 2.2 实现资产类型、关键字、店铺、套餐、剩余天数和预计到期时间筛选。
- [x] 2.3 展示资产、店铺、当前套餐、预计最终到期、剩余天数和后端临期等级名称。
- [x] 2.4 实现 0-3 天置顶、其余按预计到期时间升序,并排除已过期和不可预计记录。
- [x] 2.5 按 8-15 天粉红、4-7 天紫色、0-3 天红色实现行或到期字段高亮。
- [x] 2.6 根据 `can_renew` 展示管理端续费入口,并跳转现有续费/充值流程。
## 3. Existing Admin Pages
- [x] 3.1 在网卡普通列表增加临期字段展示和颜色高亮,不改变原排序。
- [x] 3.2 在设备普通列表增加临期字段展示和颜色高亮,不改变原排序。
- [x] 3.3 在资产信息详情复用同一临期展示规则,禁止前端重新计算预计最终到期时间。
- [x] 3.4 在代理首页展示临期卡数量和临期设备数量,并支持跳转临期列表。
## 4. Notifications
- [x] 4.1 在通知中心复用临期分类,展示后端生成的 15 天、7 天、3 天临期提醒。
- [x] 4.2 使用现有通知目标跳转到临期列表或对应管理端资产详情。
- [x] 4.3 确认管理端不展示企微临期消息,不新增 C 端通知入口。
## 5. Verification
- [x] 5.1 验证临期字段直接使用后端值,前端不根据套餐明细推导最终到期时间。
- [x] 5.2 验证 0-3 天置顶、日期升序、颜色映射和普通列表原排序保持不变。
- [x] 5.3 验证 `can_renew=false` 不展示续费入口,且各资产类型使用正确管理端入口。
- [x] 5.4 验证通知中心临期分类、已读状态和跳转行为。
- [x] 5.5 运行类型检查、相关 ESLint/Stylelint、构建和 `openspec validate add-admin-expiring-assets-notifications --strict`