refactor: 出库时间更名为首次购买套餐时间,换货新资产不再按换货完成时间记录
Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Failing after 38s

- 字段 outbound_at → first_purchase_at,记录表 tb_asset_outbound_record → tb_asset_first_purchase_record,接口 /outbound-records → /first-purchase-records,筛选参数与导出列同步更名
- 换货后的新资产不因换货写入,在当前世代真正支付套餐订单时才记录;记录来源只保留 order / backfill,去掉换货单字段
- 迁移 000266 重命名列、表、索引与约束;同步 Spec、设计、任务与前端接口变更说明

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
邹进
2026-10-27 16:47:02 +09:00
parent 909f4d0ec2
commit 62ec94adec
46 changed files with 570 additions and 560 deletions

View File

@@ -15,17 +15,17 @@ import (
// packageSilenceBundle 是沉默期相关用例的装配结果(API 与 Worker 共用)。
type packageSilenceBundle struct {
Switch *packagesilenceApp.Switch
Resolver *packagesilenceApp.Resolver
Setter *packagesilenceApp.Setter
Outbound *packagesilenceApp.OutboundRecorder
Switch *packagesilenceApp.Switch
Resolver *packagesilenceApp.Resolver
Setter *packagesilenceApp.Setter
FirstPurchase *packagesilenceApp.FirstPurchaseRecorder
// 以下仅 API 与 Worker 中延期相关入口装配
Extensions *packagesilenceApp.ExtensionService
Policies *packagesilenceApp.PolicyService
Switches *packagesilenceApp.SwitchService
}
// newPackageSilenceBundle 装配沉默期总开关、判定、设置与出库时间用例,并把激活闸门注入激活服务。
// newPackageSilenceBundle 装配沉默期总开关、判定、设置与首次购买套餐时间用例,并把激活闸门注入激活服务。
func newPackageSilenceBundle(db *gorm.DB, redisClient *redis.Client, logger *zap.Logger, auditWriter *auditInfra.Writer, activation *packageSvc.ActivationService) *packageSilenceBundle {
sw := packagesilenceApp.NewDefaultSwitch(db, redisClient, logger)
resolver := packagesilenceApp.NewResolver(db, sw, auditWriter, logger)
@@ -35,11 +35,11 @@ func newPackageSilenceBundle(db *gorm.DB, redisClient *redis.Client, logger *zap
}
return &packageSilenceBundle{
Switch: sw, Resolver: resolver,
Setter: packagesilenceApp.NewSetter(db, auditWriter),
Outbound: packagesilenceApp.NewOutboundRecorder(auditWriter),
Extensions: packagesilenceApp.NewExtensionService(db, resolver, auditWriter, logger),
Policies: packagesilenceApp.NewPolicyService(db, auditWriter),
Switches: packagesilenceApp.NewSwitchService(db, redisClient, sw, auditWriter),
Setter: packagesilenceApp.NewSetter(db, auditWriter),
FirstPurchase: packagesilenceApp.NewFirstPurchaseRecorder(auditWriter),
Extensions: packagesilenceApp.NewExtensionService(db, resolver, auditWriter, logger),
Policies: packagesilenceApp.NewPolicyService(db, auditWriter),
Switches: packagesilenceApp.NewSwitchService(db, redisClient, sw, auditWriter),
}
}

View File

@@ -342,7 +342,7 @@ func initServices(s *stores, deps *Dependencies) *services {
orderService.SetObservationSeriesEventWriter(observationSeriesEvents)
orderService.SetPriorityEventWriter(priorityEvents)
orderService.SetSilenceSetter(packageSilence.Setter)
orderService.SetOutboundRecorder(packageSilence.Outbound)
orderService.SetFirstPurchaseRecorder(packageSilence.FirstPurchase)
walletOutbox := outbox.NewRepository()
walletDebitEvents := walletinfra.NewDebitEventWriter(walletOutbox, auditWriter)
orderService.SetAgentWalletDebitService(walletapp.NewDebitService(walletDebitEvents, nil))
@@ -411,7 +411,7 @@ func initServices(s *stores, deps *Dependencies) *services {
exchangeService := exchangeSvc.New(deps.DB, s.ExchangeOrder, s.IotCard, s.Device, s.AssetWallet, s.AssetWalletTransaction, s.PackageUsage, s.PackageUsageDailyRecord, s.ResourceTag, customerBinding, deps.Logger)
exchangeService.SetShippingCreatedNotifier(exchangeApp.NewShippingCreatedNotifier(exchangeInfra.NewShippingNotificationWriter(outbox.NewRepository())))
exchangeService.SetAccessAudit(auditWriter)
exchangeService.SetSilenceHook(packagesilenceApp.NewExchangeHook(packageSilence.Setter, packageSilence.Outbound))
exchangeService.SetSilenceHook(packagesilenceApp.NewExchangeHook(packageSilence.Setter, packageSilence.FirstPurchase))
exchangeService.SetPhoneAssetAssociationStore(s.PhoneAssetAssociation)
assetService := assetSvc.New(deps.DB, s.Device, s.IotCard, s.PackageUsage, s.Package, s.PackageSeries, s.DeviceSimBinding, s.Shop, deps.Redis, iotCard, deps.GatewayClient, s.AssetIdentifier, s.Order, s.OrderItem, s.ExchangeOrder)
assetService.SetPhoneAssetAssociationStore(s.PhoneAssetAssociation)

View File

@@ -199,7 +199,7 @@ func initWorkerServices(stores *queue.WorkerStores, deps *WorkerDependencies) *q
orderService.SetObservationSeriesEventWriter(observationSeriesEvents)
orderService.SetPriorityEventWriter(priorityEvents)
orderService.SetSilenceSetter(packageSilence.Setter)
orderService.SetOutboundRecorder(packageSilence.Outbound)
orderService.SetFirstPurchaseRecorder(packageSilence.FirstPurchase)
// 创建停复机服务并注入回调:流量耗尽自动停机、套餐激活/重置/支付后自动复机
stopResumeService := iotCardSvc.NewStopResumeService(
@@ -232,7 +232,7 @@ func initWorkerServices(stores *queue.WorkerStores, deps *WorkerDependencies) *q
ObservationEvents: observationSeriesEvents,
PriorityEvents: priorityEvents,
})
assetAutoRenewalService.SetSilenceRecorder(packagesilenceApp.PurchaseRecorder{Setter: packageSilence.Setter, Outbound: packageSilence.Outbound})
assetAutoRenewalService.SetSilenceRecorder(packagesilenceApp.PurchaseRecorder{Setter: packageSilence.Setter, FirstPurchase: packageSilence.FirstPurchase})
activationService.SetObservationSeriesEventWriter(observationSeriesEvents)
activationService.SetPriorityEventWriter(priorityEvents)
usageService.SetStopResumeCallback(stopResumeService)
@@ -271,7 +271,7 @@ func initWorkerServices(stores *queue.WorkerStores, deps *WorkerDependencies) *q
SilenceSwitch: packageSilence.Switch,
SilenceResolver: packageSilence.Resolver,
SilenceSetter: packageSilence.Setter,
SilenceOutbound: packageSilence.Outbound,
SilenceFirstPurchase: packageSilence.FirstPurchase,
SilenceExtensions: packageSilence.Extensions,
}
}