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:
@@ -436,9 +436,18 @@ func NewRegistry() *Registry {
|
||||
constants.AuditActionCommissionWithdrawalAttemptRejected, "提现提交被拒绝", constants.AuditResourceShop)
|
||||
qualificationSubmitRejected := distributionAction(
|
||||
constants.AuditActionWithdrawalQualificationSubmitRejected, "资格提交被拒绝", constants.AuditResourceShop)
|
||||
// 资产钱包自动续费:配置保存是运营账号行为,续费与失败是系统任务行为,三者主资源不同。
|
||||
assetAutoRenewalConfigUpdated := packageConfigAction(
|
||||
constants.AuditActionAssetAutoRenewalConfigUpdated, "保存资产钱包自动续费配置",
|
||||
constants.AuditResourceAssetAutoRenewalConfig, constants.AuditRiskHigh)
|
||||
assetAutoRenewalRenewed := assetAutoRenewalAction(
|
||||
constants.AuditActionAssetAutoRenewalRenewed, "资产钱包自动续费完成", constants.AuditRiskHigh)
|
||||
assetAutoRenewalFailed := assetAutoRenewalAction(
|
||||
constants.AuditActionAssetAutoRenewalFailed, "资产钱包自动续费失败或跳过", constants.AuditRiskNormal)
|
||||
return &Registry{
|
||||
actionsByOperation: map[string]ActionDefinition{
|
||||
constants.AuditOperationSystemConfigUpdate: systemConfigUpdated,
|
||||
constants.AuditOperationAssetAutoRenewalConfigUpdate: assetAutoRenewalConfigUpdated,
|
||||
constants.AuditOperationPaymentConfigCreate: paymentConfigCreated,
|
||||
constants.AuditOperationPaymentConfigUpdate: paymentConfigUpdated,
|
||||
constants.AuditOperationPaymentConfigDelete: paymentConfigDeleted,
|
||||
@@ -748,6 +757,9 @@ func NewRegistry() *Registry {
|
||||
constants.AuditActionWithdrawalQualificationInvalidated: qualificationInvalidated,
|
||||
constants.AuditActionCommissionWithdrawalAttemptRejected: withdrawalAttemptRejected,
|
||||
constants.AuditActionWithdrawalQualificationSubmitRejected: qualificationSubmitRejected,
|
||||
constants.AuditActionAssetAutoRenewalConfigUpdated: assetAutoRenewalConfigUpdated,
|
||||
constants.AuditActionAssetAutoRenewalRenewed: assetAutoRenewalRenewed,
|
||||
constants.AuditActionAssetAutoRenewalFailed: assetAutoRenewalFailed,
|
||||
},
|
||||
resources: map[string]ResourceDefinition{
|
||||
constants.AuditResourceAccount: {
|
||||
@@ -822,6 +834,19 @@ func NewRegistry() *Registry {
|
||||
Type: constants.AuditResourceLogArchiveMonth, Name: "日志归档自然月",
|
||||
IdentityFields: []string{"month", "timezone", "range_start", "range_end"},
|
||||
},
|
||||
constants.AuditResourceAssetAutoRenewalConfig: {
|
||||
Type: constants.AuditResourceAssetAutoRenewalConfig, Name: "资产钱包自动续费配置",
|
||||
IdentityFields: []string{"id", "enabled", "scope", "package_ids", "days_before_expiry", "config_version"},
|
||||
},
|
||||
constants.AuditResourceAssetAutoRenewalAttempt: {
|
||||
Type: constants.AuditResourceAssetAutoRenewalAttempt, Name: "资产钱包自动续费尝试",
|
||||
IdentityFields: []string{
|
||||
"id", "asset_type", "asset_id", "trigger_date", "status", "failure_reason", "skip_reason",
|
||||
"current_usage_id", "current_package_id", "renew_package_id", "renew_price",
|
||||
"wallet_id", "wallet_transaction_id", "deduct_amount", "balance_before", "balance_after",
|
||||
"order_id", "order_no", "resume_status", "resume_integration_id", "attempt_seq",
|
||||
},
|
||||
},
|
||||
constants.AuditResourceDeviceBatchTask: {
|
||||
Type: constants.AuditResourceDeviceBatchTask, Name: "设备批量分配任务",
|
||||
IdentityFields: []string{"task_no", "operation_type"},
|
||||
@@ -1168,6 +1193,23 @@ func customerAssetAdminAction(code, name string) ActionDefinition {
|
||||
}
|
||||
}
|
||||
|
||||
// assetAutoRenewalAction 是资产钱包自动续费系统动作的注册模板。
|
||||
//
|
||||
// 续费与失败都由计划任务或 Worker 系统任务产生,主资源是本表新登记的自动续费尝试记录,
|
||||
// 因此不设 AllowedActor/Source 单一来源,改用 AllowedOrigins 同时接受两个系统入口。
|
||||
func assetAutoRenewalAction(code, name, risk string) ActionDefinition {
|
||||
return ActionDefinition{
|
||||
Code: code, Name: name, Category: constants.AuditCategoryAsset, Risk: risk,
|
||||
PrimaryResource: constants.AuditResourceAssetAutoRenewalAttempt, RequireTransaction: true,
|
||||
DefaultVisibility: constants.AuditSubjectInternalOnly,
|
||||
AllowedVisibility: []string{constants.AuditSubjectInternalOnly},
|
||||
AllowedOrigins: []ActionOrigin{
|
||||
{Actor: constants.AuditActorScheduledJob, Source: constants.AuditSourceScheduler},
|
||||
{Actor: constants.AuditActorSystemTask, Source: constants.AuditSourceWorker},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func packageConfigAction(code, name, primaryResource, risk string) ActionDefinition {
|
||||
return ActionDefinition{
|
||||
Code: code, Name: name, Category: constants.AuditCategoryConfiguration, Risk: risk,
|
||||
|
||||
Reference in New Issue
Block a user