feat: 实现运营商模块重构,添加冗余字段优化查询性能
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 5m16s
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 5m16s
主要变更: - 新增 Carrier CRUD API(创建、列表、详情、更新、删除、状态更新) - IotCard/IotCardImportTask 添加 carrier_type/carrier_name 冗余字段 - 移除 Carrier 表的 channel_name/channel_code 字段 - 查询时直接使用冗余字段,避免 JOIN Carrier 表 - 添加数据库迁移脚本(000021-000023) - 添加单元测试和集成测试 - 同步更新 OpenAPI 文档和 specs
This commit is contained in:
@@ -1,11 +1,13 @@
|
||||
# carrier Specification
|
||||
|
||||
## Purpose
|
||||
TBD - created by archiving change add-wallet-transfer-tag-models. Update Purpose after archive.
|
||||
管理运营商(Carrier)实体,支持四大固定运营商(中国移动、中国联通、中国电信、广电)的 CRUD 操作。
|
||||
|
||||
## Requirements
|
||||
|
||||
### Requirement: 运营商实体定义
|
||||
|
||||
系统 SHALL 定义运营商(Carrier)实体,管理四大固定运营商(中国移动、中国联通、中国电信、广电)的渠道信息
|
||||
系统 SHALL 定义运营商(Carrier)实体,管理四大固定运营商(中国移动、中国联通、中国电信、广电)。
|
||||
|
||||
**四大运营商固定枚举**:
|
||||
- **CMCC**:中国移动
|
||||
@@ -15,44 +17,114 @@ TBD - created by archiving change add-wallet-transfer-tag-models. Update Purpose
|
||||
|
||||
**实体字段**:
|
||||
- `id`:运营商 ID(主键,BIGINT)
|
||||
- `carrier_type`:运营商类型(VARCHAR(20),枚举值:"CMCC" | "CUCC" | "CTCC" | "CBN")**【新增】**
|
||||
- `carrier_code`:运营商编码(VARCHAR(50),唯一约束)
|
||||
- `carrier_name`:运营商名称(VARCHAR(100),如"中国移动")
|
||||
- `carrier_code`:运营商编码(VARCHAR(50),保留字段,建议填充与 carrier_type 相同)
|
||||
- `channel_name`:渠道名称(VARCHAR(100),可自定义,如"北京渠道1")**【新增】**
|
||||
- `channel_code`:渠道编码(VARCHAR(50),可自定义,如"BJ001")**【新增】**
|
||||
- `status`:状态(INT,1-启用 2-禁用)
|
||||
- `carrier_type`:运营商类型(VARCHAR(20),枚举值:"CMCC" | "CUCC" | "CTCC" | "CBN")
|
||||
- `description`:运营商描述(VARCHAR(500),可选)
|
||||
- `status`:状态(INT,1-启用 0-禁用)
|
||||
- `creator`:创建人 ID(BIGINT)
|
||||
- `updater`:更新人 ID(BIGINT)
|
||||
- `created_at`:创建时间(TIMESTAMP,自动填充)
|
||||
- `updated_at`:更新时间(TIMESTAMP,自动填充)
|
||||
- `deleted_at`:删除时间(TIMESTAMP,可空,软删除)
|
||||
|
||||
**唯一约束**:`(carrier_type, channel_code)` 在 `deleted_at IS NULL` 条件下唯一
|
||||
**唯一约束**:`carrier_code` 在 `deleted_at IS NULL` 条件下唯一
|
||||
|
||||
#### Scenario: 创建中国移动的渠道
|
||||
---
|
||||
|
||||
- **WHEN** 平台创建中国移动的北京渠道,`carrier_type` 为 "CMCC",`carrier_name` 为 "中国移动",`channel_name` 为 "北京渠道1",`channel_code` 为 "BJ001"
|
||||
- **THEN** 系统创建运营商记录,`carrier_type` 为 "CMCC",`channel_name` 为 "北京渠道1",`channel_code` 为 "BJ001"
|
||||
### Requirement: 创建运营商
|
||||
|
||||
#### Scenario: 同一运营商创建多个渠道
|
||||
系统 SHALL 允许管理员创建新的运营商记录。创建时必须指定 carrier_code(唯一编码)、carrier_name(显示名称)、carrier_type(运营商类型,枚举值)。description 为选填字段。创建成功后默认状态为启用(status=1)。
|
||||
|
||||
- **WHEN** 平台为中国移动创建两个渠道:北京渠道(BJ001)和上海渠道(SH001)
|
||||
- **THEN** 系统创建两条运营商记录,`carrier_type` 都为 "CMCC",但 `channel_code` 不同
|
||||
#### Scenario: 成功创建运营商
|
||||
- **WHEN** 管理员提交有效的创建请求,carrier_code 不重复,carrier_type 为有效枚举值
|
||||
- **THEN** 系统创建运营商记录,返回完整的运营商信息
|
||||
|
||||
#### Scenario: 渠道编码重复
|
||||
#### Scenario: carrier_code 重复
|
||||
- **WHEN** 管理员提交的 carrier_code 已存在
|
||||
- **THEN** 系统返回错误"运营商编码已存在"
|
||||
|
||||
- **WHEN** 平台创建中国移动的渠道,`carrier_type` 为 "CMCC",`channel_code` 为已存在的 "BJ001"
|
||||
- **THEN** 系统拒绝创建,返回错误信息"该运营商的渠道编码已存在"
|
||||
#### Scenario: carrier_type 无效
|
||||
- **WHEN** 管理员提交的 carrier_type 不是 CMCC/CUCC/CTCC/CBN 之一
|
||||
- **THEN** 系统返回参数校验错误
|
||||
|
||||
#### Scenario: 不同运营商可以使用相同渠道编码
|
||||
---
|
||||
|
||||
- **WHEN** 平台为中国移动创建渠道(carrier_type=CMCC, channel_code=BJ001),然后为中国联通创建渠道(carrier_type=CUCC, channel_code=BJ001)
|
||||
- **THEN** 系统允许创建,因为 `carrier_type` 不同
|
||||
### Requirement: 查询运营商列表
|
||||
|
||||
#### Scenario: 运营商类型枚举限制
|
||||
系统 SHALL 提供分页查询运营商列表的接口,支持按 carrier_type、status、carrier_name(模糊搜索)筛选。
|
||||
|
||||
- **WHEN** 平台创建运营商,`carrier_type` 为 "OTHER"(不在枚举中)
|
||||
- **THEN** 系统拒绝创建,返回错误信息"运营商类型必须是 CMCC/CUCC/CTCC/CBN 之一"
|
||||
#### Scenario: 无筛选条件查询
|
||||
- **WHEN** 管理员请求列表,不带筛选条件
|
||||
- **THEN** 系统返回所有运营商的分页列表,按 ID 降序排列
|
||||
|
||||
#### Scenario: 按运营商类型筛选
|
||||
- **WHEN** 管理员指定 carrier_type=CMCC
|
||||
- **THEN** 系统仅返回 carrier_type 为 CMCC 的记录
|
||||
|
||||
#### Scenario: 按名称模糊搜索
|
||||
- **WHEN** 管理员指定 carrier_name=移动
|
||||
- **THEN** 系统返回 carrier_name 包含"移动"的记录
|
||||
|
||||
---
|
||||
|
||||
### Requirement: 获取运营商详情
|
||||
|
||||
系统 SHALL 允许管理员通过 ID 获取单个运营商的详细信息。
|
||||
|
||||
#### Scenario: 成功获取详情
|
||||
- **WHEN** 管理员请求存在的运营商 ID
|
||||
- **THEN** 系统返回该运营商的完整信息
|
||||
|
||||
#### Scenario: 运营商不存在
|
||||
- **WHEN** 管理员请求不存在的运营商 ID
|
||||
- **THEN** 系统返回错误"运营商不存在"
|
||||
|
||||
---
|
||||
|
||||
### Requirement: 更新运营商
|
||||
|
||||
系统 SHALL 允许管理员更新运营商的 carrier_name 和 description 字段。carrier_code 和 carrier_type 创建后不可修改。
|
||||
|
||||
#### Scenario: 成功更新运营商
|
||||
- **WHEN** 管理员提交有效的更新请求
|
||||
- **THEN** 系统更新运营商信息,返回更新后的完整信息
|
||||
|
||||
#### Scenario: 尝试修改 carrier_code
|
||||
- **WHEN** 管理员尝试修改 carrier_code
|
||||
- **THEN** 系统忽略该字段(不报错,但不修改)
|
||||
|
||||
---
|
||||
|
||||
### Requirement: 删除运营商
|
||||
|
||||
系统 SHALL 允许管理员软删除运营商记录。
|
||||
|
||||
#### Scenario: 成功删除运营商
|
||||
- **WHEN** 管理员请求删除存在的运营商
|
||||
- **THEN** 系统软删除该记录(设置 deleted_at)
|
||||
|
||||
#### Scenario: 删除不存在的运营商
|
||||
- **WHEN** 管理员请求删除不存在的运营商 ID
|
||||
- **THEN** 系统返回错误"运营商不存在"
|
||||
|
||||
---
|
||||
|
||||
### Requirement: 更新运营商状态
|
||||
|
||||
系统 SHALL 允许管理员启用或禁用运营商。状态值:1=启用,0=禁用。
|
||||
|
||||
#### Scenario: 启用运营商
|
||||
- **WHEN** 管理员将状态设置为 1
|
||||
- **THEN** 系统更新运营商状态为启用
|
||||
|
||||
#### Scenario: 禁用运营商
|
||||
- **WHEN** 管理员将状态设置为 0
|
||||
- **THEN** 系统更新运营商状态为禁用
|
||||
|
||||
#### Scenario: 无效状态值
|
||||
- **WHEN** 管理员提交的状态值不是 0 或 1
|
||||
- **THEN** 系统返回参数校验错误
|
||||
|
||||
---
|
||||
|
||||
@@ -64,9 +136,8 @@ TBD - created by archiving change add-wallet-transfer-tag-models. Update Purpose
|
||||
- `carrier_type`:必填,枚举值 "CMCC" | "CUCC" | "CTCC" | "CBN"
|
||||
- `carrier_name`:必填,长度 1-100 字符
|
||||
- `carrier_code`:必填,长度 1-50 字符
|
||||
- `channel_name`:可选,长度 1-100 字符
|
||||
- `channel_code`:可选,长度 1-50 字符
|
||||
- `status`:必填,枚举值 1-2
|
||||
- `description`:可选,长度 0-500 字符
|
||||
- `status`:必填,枚举值 0 或 1
|
||||
|
||||
#### Scenario: 创建运营商时 carrier_type 无效
|
||||
|
||||
|
||||
@@ -237,3 +237,27 @@ TBD - created by archiving change iot-card-standalone-management. Update Purpose
|
||||
- **WHEN** Worker 处理导入任务创建卡记录
|
||||
- **THEN** 创建的 `IotCard` 记录 `iccid` 为 "898600...",`msisdn` 为 "13800000001"
|
||||
|
||||
---
|
||||
|
||||
### Requirement: 导入物联网卡时记录运营商信息
|
||||
|
||||
系统 SHALL 在导入物联网卡时,将运营商的 carrier_type 和 carrier_name 作为冗余字段存储到 IotCard 记录中。这些字段在导入时从 Carrier 表查询并写入,后续不再依赖 Carrier 表。
|
||||
|
||||
#### Scenario: 导入时填充冗余字段
|
||||
- **WHEN** 系统处理物联网卡导入任务
|
||||
- **THEN** 系统根据 carrier_id 查询 Carrier 表,将 carrier_type 和 carrier_name 写入每条 IotCard 记录
|
||||
|
||||
#### Scenario: Carrier 不存在
|
||||
- **WHEN** 导入任务指定的 carrier_id 对应的 Carrier 不存在或已删除
|
||||
- **THEN** 系统拒绝导入,返回错误"运营商不存在"
|
||||
|
||||
---
|
||||
|
||||
### Requirement: 导入任务记录运营商名称
|
||||
|
||||
系统 SHALL 在创建导入任务时,将 carrier_name 作为冗余字段存储到 IotCardImportTask 记录中(已有 carrier_type)。
|
||||
|
||||
#### Scenario: 创建导入任务时填充 carrier_name
|
||||
- **WHEN** 管理员创建物联网卡导入任务
|
||||
- **THEN** 系统根据 carrier_id 查询 Carrier 表,将 carrier_name 写入导入任务记录
|
||||
|
||||
|
||||
@@ -544,3 +544,37 @@ This capability supports:
|
||||
- **WHEN** 卡的授权被回收后(revoked_at 不为空),企业用户查询该卡
|
||||
- **THEN** 系统不返回该卡信息,企业无法再看到该卡
|
||||
|
||||
---
|
||||
|
||||
### Requirement: 查询物联网卡时返回运营商信息
|
||||
|
||||
系统 SHALL 在查询物联网卡列表/详情时,直接从 IotCard 记录的冗余字段返回 carrier_type 和 carrier_name,无需 JOIN Carrier 表。
|
||||
|
||||
#### Scenario: 列表查询返回运营商信息
|
||||
- **WHEN** 管理员查询物联网卡列表
|
||||
- **THEN** 响应中的 carrier_type 和 carrier_name 直接来自 IotCard 记录的冗余字段
|
||||
|
||||
#### Scenario: 详情查询返回运营商信息
|
||||
- **WHEN** 管理员查询单张物联网卡详情
|
||||
- **THEN** 响应中的 carrier_type 和 carrier_name 直接来自 IotCard 记录的冗余字段
|
||||
|
||||
---
|
||||
|
||||
### Requirement: 查询导入任务时返回运营商名称
|
||||
|
||||
系统 SHALL 在查询导入任务列表/详情时,直接从 IotCardImportTask 记录的冗余字段返回 carrier_name,无需 JOIN Carrier 表。
|
||||
|
||||
#### Scenario: 导入任务列表返回运营商名称
|
||||
- **WHEN** 管理员查询导入任务列表
|
||||
- **THEN** 响应中的 carrier_name 直接来自 IotCardImportTask 记录的冗余字段
|
||||
|
||||
---
|
||||
|
||||
### Requirement: 设备绑定卡查询返回运营商信息
|
||||
|
||||
系统 SHALL 在查询设备绑定的物联网卡时,直接从 IotCard 记录的冗余字段返回 carrier_name,无需 JOIN Carrier 表。
|
||||
|
||||
#### Scenario: 设备绑定卡列表返回运营商名称
|
||||
- **WHEN** 管理员查询设备绑定的物联网卡列表
|
||||
- **THEN** 响应中的 carrier_name 直接来自 IotCard 记录的冗余字段
|
||||
|
||||
|
||||
Reference in New Issue
Block a user