Files
junhong_cmp_fiber/internal/infrastructure/assetautorenewal/commander.go
break d52be16802
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 10m15s
feat(资产钱包自动续费): 新增全局配置、每日扫描续购与可靠复机
- 新增单行配置表 tb_asset_auto_renewal_config 与尝试记录表 tb_asset_auto_renewal_attempt(迁移 000229/000230)
- 每日按上海自然日扫描,窗口内以同一资产钱包可用余额续购当前主套餐,资金/订单/套餐/审计同一事务闭合
- 唯一键保证每资产每日至多一次尝试,占位中断由后续扫描收敛,当日不重试
- 四类失败原因向客户与店铺各投递每日至多一条站内通知,并注册通知类型与个人客户白名单
- 续费成功后按条件经 Outbox 可靠投递复机,新增恢复扫描只查询回填,不使用即发即弃调用
- 配置读写仅超级管理员与平台账号,保存记录操作者、前后值快照并登记统一审计
- tasks 7.1–7.15 全部验证通过(本机隔离 PostgreSQL/Redis,零外部渠道调用)
2026-09-17 16:39:26 +08:00

57 lines
2.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Package assetautorenewal 提供资产钱包自动续费的停复机执行适配与异步任务入口。
package assetautorenewal
import (
"context"
assetAutoRenewalApp "github.com/break/junhong_cmp_fiber/internal/application/assetautorenewal"
iotCardSvc "github.com/break/junhong_cmp_fiber/internal/service/iot_card"
"github.com/break/junhong_cmp_fiber/pkg/errors"
)
// CardCommander 把自动续费复机端口转发到既有停复机单一事实源。
//
// 它只做类型与结果分类的转换判定规则、重试、Integration Log、统一审计与观测序列全部由
// internal/service/iot_card 提供,本适配器不复制任何规则,也不直接调用运营商接口。
type CardCommander struct {
service *iotCardSvc.StopResumeService
}
// NewCardCommander 创建自动续费复机执行适配器。
func NewCardCommander(service *iotCardSvc.StopResumeService) *CardCommander {
return &CardCommander{service: service}
}
// AutoRenewalResumeReady 判断该资产是否满足自动复机条件。
func (c *CardCommander) AutoRenewalResumeReady(ctx context.Context, assetType string, assetID uint) (bool, string, error) {
if c == nil || c.service == nil {
return false, "", errCommanderUnavailable()
}
return c.service.AutoRenewalResumeReady(ctx, assetType, assetID)
}
// ResumeAssetForAutoRenewal 执行复机并把结果转换为本用例的结果摘要。
func (c *CardCommander) ResumeAssetForAutoRenewal(ctx context.Context, assetType string, assetID uint) (assetAutoRenewalApp.ResumeOutcome, error) {
if c == nil || c.service == nil {
return assetAutoRenewalApp.ResumeOutcome{}, errCommanderUnavailable()
}
outcome, err := c.service.ResumeAssetForAutoRenewal(ctx, assetType, assetID)
return assetAutoRenewalApp.ResumeOutcome{
Applied: outcome.Applied, IntegrationID: outcome.IntegrationID,
Result: outcome.Result, SafeReason: outcome.SafeReason,
}, err
}
// QueryAutoRenewalResumeState 只查询运营商卡状态,供恢复扫描回填复机结果。
func (c *CardCommander) QueryAutoRenewalResumeState(ctx context.Context, assetType string, assetID uint) (bool, bool, string, error) {
if c == nil || c.service == nil {
return false, false, "", errCommanderUnavailable()
}
return c.service.QueryAutoRenewalResumeState(ctx, assetType, assetID)
}
// errCommanderUnavailable 返回复机执行端口未配置的稳定错误。
func errCommanderUnavailable() error {
return errors.New(errors.CodeServiceUnavailable, "自动续费复机执行能力未配置")
}