实现套餐生效条件覆盖与购买快照
This commit is contained in:
@@ -2011,6 +2011,10 @@ components:
|
||||
type: object
|
||||
DtoBatchAllocatePackagesRequest:
|
||||
properties:
|
||||
expiry_base_override:
|
||||
description: 分配生效条件覆盖 (null:跟随套餐默认值, from_activation:实名激活时生效, from_purchase:购买即生效)
|
||||
nullable: true
|
||||
type: string
|
||||
one_time_commission_amount:
|
||||
description: 该代理能拿到的一次性佣金(分)
|
||||
minimum: 0
|
||||
@@ -2030,6 +2034,24 @@ components:
|
||||
- shop_id
|
||||
- series_id
|
||||
type: object
|
||||
DtoBatchAllocatePackagesResponse:
|
||||
properties:
|
||||
allocated_count:
|
||||
description: 成功分配数量
|
||||
type: integer
|
||||
allocations:
|
||||
description: 本次新建套餐分配及其生效条件
|
||||
items:
|
||||
$ref: '#/components/schemas/DtoShopPackageAllocationTermsResponse'
|
||||
nullable: true
|
||||
type: array
|
||||
skipped_count:
|
||||
description: 跳过数量(已存在)
|
||||
type: integer
|
||||
total_packages:
|
||||
description: 总套餐数
|
||||
type: integer
|
||||
type: object
|
||||
DtoBatchPricingSkipped:
|
||||
properties:
|
||||
allocation_id:
|
||||
@@ -3845,6 +3867,10 @@ components:
|
||||
description: 是否启用代理强充
|
||||
nullable: true
|
||||
type: boolean
|
||||
expiry_base_override:
|
||||
description: 分配生效条件覆盖 (null:跟随套餐默认值, from_activation:实名激活时生效, from_purchase:购买即生效)
|
||||
nullable: true
|
||||
type: string
|
||||
force_recharge_amount:
|
||||
description: 代理强充金额(分)
|
||||
nullable: true
|
||||
@@ -6085,6 +6111,10 @@ components:
|
||||
type: object
|
||||
DtoManageGrantPackagesParams:
|
||||
properties:
|
||||
expiry_base_override:
|
||||
description: 新增分配的生效条件覆盖 (null:跟随套餐默认值, from_activation:实名激活时生效, from_purchase:购买即生效)
|
||||
nullable: true
|
||||
type: string
|
||||
packages:
|
||||
description: 套餐操作列表
|
||||
items:
|
||||
@@ -6605,6 +6635,12 @@ components:
|
||||
data_reset_cycle:
|
||||
description: 流量重置周期 (daily:每日, monthly:每月, yearly:每年, none:不重置)
|
||||
type: string
|
||||
default_expiry_base:
|
||||
description: 套餐默认生效条件 (from_activation:实名激活时生效, from_purchase:购买即生效)
|
||||
type: string
|
||||
default_expiry_base_name:
|
||||
description: 套餐默认生效条件名称(中文)
|
||||
type: string
|
||||
duration_days:
|
||||
description: 套餐天数(calendar_type=by_day时有值)
|
||||
nullable: true
|
||||
@@ -6612,6 +6648,12 @@ components:
|
||||
duration_months:
|
||||
description: 套餐时长(月数)
|
||||
type: integer
|
||||
effective_expiry_base:
|
||||
description: 最终生效条件 (from_activation:实名激活时生效, from_purchase:购买即生效)
|
||||
type: string
|
||||
effective_expiry_base_name:
|
||||
description: 最终生效条件名称(中文)
|
||||
type: string
|
||||
effective_retail_price:
|
||||
description: 生效零售价(分,仅销售链路展示使用)
|
||||
nullable: true
|
||||
@@ -6622,6 +6664,13 @@ components:
|
||||
expiry_base:
|
||||
description: 到期时间基准 (from_activation:实名激活时起算, from_purchase:购买时起算)
|
||||
type: string
|
||||
expiry_base_override:
|
||||
description: 分配生效条件覆盖,null 表示跟随套餐默认值
|
||||
nullable: true
|
||||
type: string
|
||||
expiry_base_override_name:
|
||||
description: 分配生效条件覆盖名称(中文)
|
||||
type: string
|
||||
id:
|
||||
description: 套餐ID
|
||||
minimum: 0
|
||||
@@ -7991,6 +8040,32 @@ components:
|
||||
description: 总记录数
|
||||
type: integer
|
||||
type: object
|
||||
DtoShopPackageAllocationTermsResponse:
|
||||
properties:
|
||||
default_expiry_base:
|
||||
description: 套餐默认生效条件 (from_activation:实名激活时生效, from_purchase:购买即生效)
|
||||
type: string
|
||||
default_expiry_base_name:
|
||||
description: 套餐默认生效条件名称(中文)
|
||||
type: string
|
||||
effective_expiry_base:
|
||||
description: 最终生效条件 (from_activation:实名激活时生效, from_purchase:购买即生效)
|
||||
type: string
|
||||
effective_expiry_base_name:
|
||||
description: 最终生效条件名称(中文)
|
||||
type: string
|
||||
expiry_base_override:
|
||||
description: 分配生效条件覆盖,null 表示跟随套餐默认值
|
||||
nullable: true
|
||||
type: string
|
||||
expiry_base_override_name:
|
||||
description: 分配生效条件覆盖名称(中文)
|
||||
type: string
|
||||
id:
|
||||
description: 套餐分配ID
|
||||
minimum: 0
|
||||
type: integer
|
||||
type: object
|
||||
DtoShopPageResult:
|
||||
properties:
|
||||
items:
|
||||
@@ -8153,6 +8228,25 @@ components:
|
||||
cost_price:
|
||||
description: 成本价(分)
|
||||
type: integer
|
||||
default_expiry_base:
|
||||
description: 套餐默认生效条件 (from_activation:实名激活时生效, from_purchase:购买即生效)
|
||||
type: string
|
||||
default_expiry_base_name:
|
||||
description: 套餐默认生效条件名称(中文)
|
||||
type: string
|
||||
effective_expiry_base:
|
||||
description: 最终生效条件 (from_activation:实名激活时生效, from_purchase:购买即生效)
|
||||
type: string
|
||||
effective_expiry_base_name:
|
||||
description: 最终生效条件名称(中文)
|
||||
type: string
|
||||
expiry_base_override:
|
||||
description: 分配生效条件覆盖,null 表示跟随套餐默认值
|
||||
nullable: true
|
||||
type: string
|
||||
expiry_base_override_name:
|
||||
description: 分配生效条件覆盖名称(中文)
|
||||
type: string
|
||||
package_code:
|
||||
description: 套餐编码
|
||||
type: string
|
||||
@@ -8610,6 +8704,13 @@ components:
|
||||
nullable: true
|
||||
type: string
|
||||
type: object
|
||||
DtoUpdateAllocationExpiryBaseParams:
|
||||
properties:
|
||||
expiry_base_override:
|
||||
description: 分配生效条件覆盖 (null:跟随套餐默认值, from_activation:实名激活时生效, from_purchase:购买即生效)
|
||||
nullable: true
|
||||
type: string
|
||||
type: object
|
||||
DtoUpdateAssetPackageExpiresAtRequest:
|
||||
properties:
|
||||
expires_at:
|
||||
@@ -22325,6 +22426,78 @@ paths:
|
||||
summary: 移除权限
|
||||
tags:
|
||||
- 角色
|
||||
/api/admin/shop-package-allocations/{id}/expiry-base:
|
||||
patch:
|
||||
parameters:
|
||||
- description: ID
|
||||
in: path
|
||||
name: id
|
||||
required: true
|
||||
schema:
|
||||
description: ID
|
||||
minimum: 0
|
||||
type: integer
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/DtoUpdateAllocationExpiryBaseParams'
|
||||
responses:
|
||||
"200":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
properties:
|
||||
code:
|
||||
description: 响应码
|
||||
example: 0
|
||||
type: integer
|
||||
data:
|
||||
$ref: '#/components/schemas/DtoShopPackageAllocationTermsResponse'
|
||||
msg:
|
||||
description: 响应消息
|
||||
example: success
|
||||
type: string
|
||||
timestamp:
|
||||
description: 时间戳
|
||||
format: date-time
|
||||
type: string
|
||||
required:
|
||||
- code
|
||||
- msg
|
||||
- data
|
||||
- timestamp
|
||||
type: object
|
||||
description: 成功
|
||||
"400":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
description: 请求参数错误
|
||||
"401":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
description: 未认证或认证已过期
|
||||
"403":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
description: 无权访问
|
||||
"500":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
description: 服务器内部错误
|
||||
security:
|
||||
- BearerAuth: []
|
||||
summary: 修改套餐分配生效条件覆盖
|
||||
tags:
|
||||
- 批量套餐分配
|
||||
/api/admin/shop-package-batch-allocations:
|
||||
post:
|
||||
requestBody:
|
||||
@@ -22333,6 +22506,32 @@ paths:
|
||||
schema:
|
||||
$ref: '#/components/schemas/DtoBatchAllocatePackagesRequest'
|
||||
responses:
|
||||
"200":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
properties:
|
||||
code:
|
||||
description: 响应码
|
||||
example: 0
|
||||
type: integer
|
||||
data:
|
||||
$ref: '#/components/schemas/DtoBatchAllocatePackagesResponse'
|
||||
msg:
|
||||
description: 响应消息
|
||||
example: success
|
||||
type: string
|
||||
timestamp:
|
||||
description: 时间戳
|
||||
format: date-time
|
||||
type: string
|
||||
required:
|
||||
- code
|
||||
- msg
|
||||
- data
|
||||
- timestamp
|
||||
type: object
|
||||
description: 成功
|
||||
"400":
|
||||
content:
|
||||
application/json:
|
||||
|
||||
24
docs/ur55-package-expiry-base/功能总结.md
Normal file
24
docs/ur55-package-expiry-base/功能总结.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# UR#55 套餐分配生效条件覆盖与购买快照
|
||||
|
||||
## 实现范围
|
||||
|
||||
- 系列首次授权、系列追加授权和批量套餐分配必须显式提交 `expiry_base_override`,支持 `null`、`from_purchase`、`from_activation`。
|
||||
- 套餐分配响应返回套餐默认值、分配覆盖值和最终有效值及其中文名称。
|
||||
- 新增单条分配覆盖修改接口:`PATCH /api/admin/shop-package-allocations/{id}/expiry-base`,显式 `null` 恢复跟随默认,重复提交保持幂等。
|
||||
- 同步购买和自动购包创建主套餐或加油包时,在同一事务写入生效条件、周期类型、月数和天数快照。
|
||||
- 实名激活、指定激活、排队接续和退款后的下一套餐接续优先读取购买快照;仅四字段全部为空或零的历史记录允许告警回退套餐当前配置,部分缺失或非法快照直接拒绝。
|
||||
|
||||
## 数据库变更
|
||||
|
||||
- `tb_shop_package_allocation.expiry_base_override`:可空字符串,`NULL` 表示跟随套餐默认值。
|
||||
- `tb_package_usage`:新增 `expiry_base_snapshot`、`calendar_type_snapshot`、`duration_months_snapshot`、`duration_days_snapshot`。
|
||||
- 历史套餐使用记录不回填,保留空值和零值作为历史未快照标记。
|
||||
|
||||
## 发布与回滚
|
||||
|
||||
发布时先部署兼容读取快照和历史回退的应用,再执行 162、163 迁移,并在同一维护窗口切换所有写入路径。回滚迁移只删除本需求新增字段和约束,不修改套餐使用状态或历史业务数据。
|
||||
|
||||
## 验证
|
||||
|
||||
- 领域测试覆盖覆盖值解析、自然月/按天快照、快照优先、历史回退和异常快照拒绝。
|
||||
- 已执行全仓 `go test ./...`、OpenAPI 文档生成以及迁移向上、单步向下、重新向上验证。
|
||||
Reference in New Issue
Block a user