feat(资产钱包自动续费): 新增全局配置、每日扫描续购与可靠复机
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 10m15s
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 10m15s
- 新增单行配置表 tb_asset_auto_renewal_config 与尝试记录表 tb_asset_auto_renewal_attempt(迁移 000229/000230) - 每日按上海自然日扫描,窗口内以同一资产钱包可用余额续购当前主套餐,资金/订单/套餐/审计同一事务闭合 - 唯一键保证每资产每日至多一次尝试,占位中断由后续扫描收敛,当日不重试 - 四类失败原因向客户与店铺各投递每日至多一条站内通知,并注册通知类型与个人客户白名单 - 续费成功后按条件经 Outbox 可靠投递复机,新增恢复扫描只查询回填,不使用即发即弃调用 - 配置读写仅超级管理员与平台账号,保存记录操作者、前后值快照并登记统一审计 - tasks 7.1–7.15 全部验证通过(本机隔离 PostgreSQL/Redis,零外部渠道调用)
This commit is contained in:
@@ -106,6 +106,9 @@ func RegisterAdminRoutes(router fiber.Router, handlers *bootstrap.Handlers, midd
|
||||
if handlers.PackageTrafficAlert != nil {
|
||||
registerPackageTrafficAlertRoutes(authGroup, handlers.PackageTrafficAlert, doc, basePath)
|
||||
}
|
||||
if handlers.AssetAutoRenewal != nil {
|
||||
registerAssetAutoRenewalRoutes(authGroup, handlers.AssetAutoRenewal, doc, basePath)
|
||||
}
|
||||
if handlers.ShopPackageBatchAllocation != nil {
|
||||
registerShopPackageBatchAllocationRoutes(authGroup, handlers.ShopPackageBatchAllocation, doc, basePath)
|
||||
}
|
||||
|
||||
43
internal/routes/asset_auto_renewal.go
Normal file
43
internal/routes/asset_auto_renewal.go
Normal file
@@ -0,0 +1,43 @@
|
||||
package routes
|
||||
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
|
||||
"github.com/break/junhong_cmp_fiber/internal/handler/admin"
|
||||
"github.com/break/junhong_cmp_fiber/internal/model/dto"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/constants"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/errors"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/middleware"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/openapi"
|
||||
)
|
||||
|
||||
// registerAssetAutoRenewalRoutes 注册资产钱包自动续费配置的读写路由。
|
||||
// 沿用超管/平台路由组级 gate 先例:代理、企业与个人客户账号一律 403,无任何读取或修改入口。
|
||||
func registerAssetAutoRenewalRoutes(router fiber.Router, handler *admin.AssetAutoRenewalConfigHandler, doc *openapi.Generator, basePath string) {
|
||||
group := router.Group("", func(c *fiber.Ctx) error {
|
||||
userType := middleware.GetUserTypeFromContext(c.UserContext())
|
||||
if userType != constants.UserTypeSuperAdmin && userType != constants.UserTypePlatform {
|
||||
return errors.New(errors.CodeForbidden, constants.PlatformManagementForbiddenMessage)
|
||||
}
|
||||
return c.Next()
|
||||
})
|
||||
|
||||
path := basePath + "/asset-auto-renewal-config"
|
||||
|
||||
Register(group, doc, path, "GET", "", handler.GetConfig, RouteSpec{
|
||||
Summary: "查询资产钱包自动续费配置",
|
||||
Description: "返回唯一一份全局配置的总开关、适用范围、指定主套餐集合、到期前天数与配置版本;仅超级管理员与平台账号可访问",
|
||||
Tags: []string{"资产钱包"},
|
||||
Output: new(dto.AssetAutoRenewalConfigResponse),
|
||||
Auth: true,
|
||||
})
|
||||
|
||||
Register(group, doc, path, "PUT", "", handler.UpdateConfig, RouteSpec{
|
||||
Summary: "保存资产钱包自动续费配置",
|
||||
Description: "指定范围时集合必须非空且只能选择当前可售主套餐;保存记录操作者与前后值快照并递增配置版本,只影响后续扫描",
|
||||
Tags: []string{"资产钱包"},
|
||||
Body: new(dto.UpdateAssetAutoRenewalConfigRequest),
|
||||
Output: new(dto.AssetAutoRenewalConfigResponse),
|
||||
Auth: true,
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user