暂存一下,防止丢失

This commit is contained in:
2026-07-24 16:07:18 +08:00
parent 5d6e23f1a5
commit a18ed8bc8d
180 changed files with 13597 additions and 1986 deletions

107
pkg/constants/approval.go Normal file
View File

@@ -0,0 +1,107 @@
package constants
import "time"
const (
// ApprovalStatusSubmitting 表示审批申请等待渠道提交。
ApprovalStatusSubmitting = 0
// ApprovalStatusPending 表示审批申请已进入渠道审批。
ApprovalStatusPending = 1
// ApprovalStatusApproved 表示审批已通过。
ApprovalStatusApproved = 2
// ApprovalStatusRejected 表示审批已拒绝。
ApprovalStatusRejected = 3
// ApprovalStatusCancelled 表示审批已撤销。
ApprovalStatusCancelled = 4
// ApprovalStatusRevokedAfterApproved 表示审批通过后被撤销。
ApprovalStatusRevokedAfterApproved = 5
// ApprovalStatusDeleted 表示审批已删除。
ApprovalStatusDeleted = 6
// ApprovalStatusSubmissionFailed 表示渠道明确确认审批提交失败。
ApprovalStatusSubmissionFailed = 7
// ApprovalStatusSubmissionUnknown 表示审批提交请求已发出但结果未知。
ApprovalStatusSubmissionUnknown = 8
)
const (
// ApprovalDecisionApproved 表示标准审批通过决策。
ApprovalDecisionApproved = "approved"
// ApprovalDecisionRejected 表示标准审批拒绝决策。
ApprovalDecisionRejected = "rejected"
// ApprovalDecisionCancelled 表示标准审批撤销决策。
ApprovalDecisionCancelled = "cancelled"
// ApprovalDecisionDeleted 表示标准审批删除决策。
ApprovalDecisionDeleted = "deleted"
// ApprovalDecisionRevokedAfterApproved 表示标准审批通过后撤销决策。
ApprovalDecisionRevokedAfterApproved = "revoked_after_approved"
)
const (
// ApprovalInitialVersion 表示通用审批实例的初始乐观锁版本。
ApprovalInitialVersion = 1
// ApprovalQueryMaxBatchSize 表示通用审批摘要单次批量投影上限。
ApprovalQueryMaxBatchSize = 100
// ApprovalUnknownSubmitterName 表示提交人名称快照无法解析。
ApprovalUnknownSubmitterName = "未知账号"
// ApprovalDecisionDeliveryLeaseDuration 表示标准决策消费者的单次处理租约时长。
ApprovalDecisionDeliveryLeaseDuration = 5 * time.Minute
// ApprovalPreparationTTL 表示事务前审批可用性结果允许复用的最长期限。
ApprovalPreparationTTL = 30 * time.Second
)
const (
// ApprovalDecisionDeliveryPending 表示标准决策等待业务消费。
ApprovalDecisionDeliveryPending = 0
// ApprovalDecisionDeliveryProcessing 表示标准决策已被消费者租约领取。
ApprovalDecisionDeliveryProcessing = 1
// ApprovalDecisionDeliverySucceeded 表示标准决策已被业务幂等处理。
ApprovalDecisionDeliverySucceeded = 2
// ApprovalDecisionDeliveryFailed 表示标准决策消费失败并等待重试。
ApprovalDecisionDeliveryFailed = 3
)
const (
// OutboxEventTypeApprovalTerminalDecision 表示通用审批标准终态已记录。
OutboxEventTypeApprovalTerminalDecision = "approval.terminal_decision.recorded"
// OutboxEventTypeApprovalSubmissionRequested 表示通用审批实例等待渠道提交。
OutboxEventTypeApprovalSubmissionRequested = "approval.submission.requested"
// ApprovalTerminalDecisionPayloadVersionV1 表示标准终态事件载荷第一版。
ApprovalTerminalDecisionPayloadVersionV1 = 1
// ApprovalSubmissionPayloadVersionV1 表示审批申请提交事件载荷第一版。
ApprovalSubmissionPayloadVersionV1 = 1
)
const (
// ApprovalSyncSourceCallback 表示由第三方审批回调触发权威同步。
ApprovalSyncSourceCallback = "callback"
// ApprovalSyncSourcePolling 表示由定时兜底轮询触发权威同步。
ApprovalSyncSourcePolling = "polling"
// ApprovalSyncSourceManual 表示由受控人工动作触发权威同步。
ApprovalSyncSourceManual = "manual"
)
// GetApprovalStatusName 返回通用审批状态的中文名称。
func GetApprovalStatusName(status int) string {
switch status {
case ApprovalStatusSubmitting:
return "提交中"
case ApprovalStatusPending:
return "审批中"
case ApprovalStatusApproved:
return "已通过"
case ApprovalStatusRejected:
return "已拒绝"
case ApprovalStatusCancelled:
return "已撤销"
case ApprovalStatusRevokedAfterApproved:
return "通过后撤销"
case ApprovalStatusDeleted:
return "已删除"
case ApprovalStatusSubmissionFailed:
return "提交失败"
case ApprovalStatusSubmissionUnknown:
return "提交结果未知"
default:
return "未知"
}
}

View File

@@ -0,0 +1,90 @@
package constants
import "time"
// 卡实名观测来源
const (
CardObservationSourcePolling = "polling" // 周期轮询
CardObservationSourceManualSync = "manual_sync" // 手动同步
CardObservationSourceManualOverride = "manual_override" // 人工纠偏
CardObservationSourceCarrierCallback = "carrier_callback" // 运营商回调
CardObservationSourceBusinessEvent = "business_event" // 业务成功后的观测
)
// 卡观测事件序列同步类型。
const (
CardObservationSyncTypeRealname = "realname" // 实名状态
CardObservationSyncTypeTraffic = "traffic" // 流量读数
CardObservationSyncTypeNetwork = "network" // 网络状态
CardObservationSyncTypeDeviceInfo = "device_info" // 设备信息
)
// 卡观测事件序列资源类型。
const (
CardObservationResourceTypeCard = "iot_card" // IoT 卡
CardObservationResourceTypeDevice = "device" // 设备
)
// 卡观测事件序列执行参数。
const (
CardObservationSeriesAttemptCount = 3 // 每个序列固定尝试次数
CardObservationSeriesTTL = 7 * time.Minute // 活跃序列覆盖最后一次任务及缓冲
CardObservationSeriesResultTTL = 24 * time.Hour // 尝试幂等与提前完成结果保留时间
CardObservationGatewayLockTTL = 70 * time.Second // Gateway 请求互斥超时加安全余量
CardObservationGatewayMinInterval = 10 * time.Second // 未配置时的运营商最小请求间隔
)
// CardObservationAttemptDelay 返回固定的立即、3 分钟、5 分钟阶梯延迟。
func CardObservationAttemptDelay(attempt int) time.Duration {
switch attempt {
case 1:
return 0
case 2:
return 3 * time.Minute
case 3:
return 5 * time.Minute
default:
return 0
}
}
// 卡观测副作用消费状态
const (
CardObservationEffectStatusPending = 0 // 等待处理
CardObservationEffectStatusProcessing = 1 // 正在处理或结果未知
CardObservationEffectStatusDailySaved = 2 // 日流量缓冲已记录
CardObservationEffectStatusDeducted = 3 // 套餐流量已扣减
CardObservationEffectStatusCompleted = 4 // 全部副作用已完成
)
// 卡观测副作用类型
const (
CardObservationEffectTypeTrafficIncrement = "traffic_increment" // 流量正增量副作用
)
// Gateway 轮询 Integration Log 操作编码。
const (
IntegrationProviderGateway = "gateway" // Gateway 外部系统
IntegrationOperationGatewayRealname = "query_realname_status" // 查询实名状态
IntegrationOperationGatewayTraffic = "query_flow" // 查询流量
IntegrationOperationGatewayNetwork = "query_card_status" // 查询网络状态
)
// 卡实名观测场景
const (
CardObservationSceneRealnamePolling = "realname_polling" // 实名轮询
CardObservationSceneTrafficPolling = "traffic_polling" // 流量轮询
CardObservationSceneNetworkPolling = "network_polling" // 网络状态轮询
CardObservationSceneManualRefresh = "manual_refresh" // 手动刷新
CardObservationSceneCarrierCallback = "carrier_realname_callback" // 运营商实名回调
)
// 卡实名状态变更 Outbox 事件
const (
OutboxEventTypeCardRealnameChanged = "card.realname.changed" // 卡实名状态变化
CardRealnameChangedPayloadVersionV1 = 1 // 卡实名状态变化载荷版本
OutboxEventTypeCardTrafficIncremented = "card.traffic.incremented" // 卡流量正增量
CardTrafficIncrementedPayloadVersionV1 = 1 // 卡流量正增量载荷版本
OutboxEventTypeCardNetworkChanged = "card.network.changed" // 卡网络状态变化
CardNetworkChangedPayloadVersionV1 = 1 // 卡网络状态变化载荷版本
)

View File

@@ -80,10 +80,12 @@ const (
TaskTypeAutoPurchaseAfterRecharge = "task:auto_purchase_after_recharge" // 充值后自动购包
// 定时任务类型(由 Asynq Scheduler 调度)
TaskTypeAlertCheck = "alert:check" // 告警检查
TaskTypeDataCleanup = "data:cleanup" // 数据清理
TaskTypeDailyTrafficFlush = "traffic:daily:flush" // 每日流量落盘
TaskTypeOutboxDeliver = "outbox:deliver" // 公共 Outbox 事件投递
TaskTypeAlertCheck = "alert:check" // 告警检查
TaskTypeDataCleanup = "data:cleanup" // 数据清理
TaskTypeNotificationCleanup = "notification:cleanup" // 站内通知保留清理
TaskTypeDailyTrafficFlush = "traffic:daily:flush" // 每日流量落盘
TaskTypeOutboxDeliver = "outbox:deliver" // 公共 Outbox 事件投递
TaskTypeCardObservationSeries = "card_observation:series" // 卡观测事件序列尝试
)
// 用户状态常量
@@ -225,6 +227,7 @@ const (
QueueDataCleanup = TaskTypeDataCleanup // 数据清理任务队列
QueueDailyTrafficFlush = TaskTypeDailyTrafficFlush // 每日流量落盘任务队列
QueueOutboxDeliver = TaskTypeOutboxDeliver // 公共 Outbox 投递队列
QueueCardObservationSeries = TaskTypeCardObservationSeries // 卡观测事件序列队列
DefaultRetryMax = 5 // 默认任务最大重试次数
DefaultTimeout = 10 * time.Minute // 默认任务超时时间
@@ -280,10 +283,14 @@ func QueueForTaskType(taskType string) string {
return QueueAlertCheck
case TaskTypeDataCleanup:
return QueueDataCleanup
case TaskTypeNotificationCleanup:
return QueueDataCleanup
case TaskTypeDailyTrafficFlush:
return QueueDailyTrafficFlush
case TaskTypeOutboxDeliver:
return QueueOutboxDeliver
case TaskTypeCardObservationSeries:
return QueueCardObservationSeries
default:
return QueueDefault
}
@@ -318,6 +325,7 @@ func DefaultTaskQueueWeights() map[string]int {
QueueDataCleanup: 1,
QueueDailyTrafficFlush: 1,
QueueOutboxDeliver: 4,
QueueCardObservationSeries: 2,
QueueDefault: 1,
QueueLow: 1,
}

View File

@@ -233,13 +233,6 @@ const (
ApprovalTypeManual = "manual" // 人工([预留]
)
// 审批状态([预留] 用于审批流程功能,待产品规划)
const (
ApprovalStatusPending = 1 // 待审批([预留]
ApprovalStatusApproved = 2 // 已通过([预留]
ApprovalStatusRejected = 3 // 已拒绝([预留]
)
// ========================================
// 4. 财务管理常量
// ========================================

View File

@@ -0,0 +1,119 @@
package constants
const (
// NotificationRecipientKindAccount 表示后台账号接收人。
NotificationRecipientKindAccount = "account"
// NotificationRecipientKindPersonalCustomer 表示个人客户接收人。
NotificationRecipientKindPersonalCustomer = "personal_customer"
// NotificationTargetKindAccount 表示由稳定后台账号 ID 解析接收人。
NotificationTargetKindAccount = "account"
// NotificationTargetKindPlatformRole 表示由当前平台角色解析接收人。
NotificationTargetKindPlatformRole = "platform_role"
// NotificationTargetKindShop 表示由目标店铺解析主账号和当前业务员。
NotificationTargetKindShop = "shop"
// NotificationCategoryApproval 表示审批类通知。
NotificationCategoryApproval = "approval"
// NotificationCategoryExpiry 表示临期类通知。
NotificationCategoryExpiry = "expiry"
// NotificationCategorySync 表示同步类通知。
NotificationCategorySync = "sync"
// NotificationCategorySystem 表示系统类通知。
NotificationCategorySystem = "system"
// NotificationSeverityInfo 表示普通提示。
NotificationSeverityInfo = "info"
// NotificationSeverityWarning 表示需要关注的警告。
NotificationSeverityWarning = "warning"
// NotificationSeverityError 表示处理失败。
NotificationSeverityError = "error"
// NotificationSeverityCritical 表示严重系统异常。
NotificationSeverityCritical = "critical"
// NotificationTypeSystemNotice 表示受控通用系统通知。
NotificationTypeSystemNotice = "system.notice"
// NotificationTypePackageExpiring 表示个人客户套餐临期提醒。
NotificationTypePackageExpiring = "package.expiring"
// NotificationRefTypeSystemConfig 表示系统配置资源引用。
NotificationRefTypeSystemConfig = "system_config"
// NotificationRefTypeIntegrationLog 表示外部集成日志资源引用。
NotificationRefTypeIntegrationLog = "integration_log"
// NotificationRefTypePackage 表示套餐资源引用。
NotificationRefTypePackage = "package"
// NotificationRefTypeAsset 表示个人客户资产资源引用。
NotificationRefTypeAsset = "asset"
// NotificationRefTypeRefund 表示退款详情资源引用。
NotificationRefTypeRefund = "refund"
// NotificationRefTypeAgentRecharge 表示代理充值详情资源引用。
NotificationRefTypeAgentRecharge = "agent_recharge"
// NotificationRefTypeWeComApproval 表示企微审批详情资源引用。
NotificationRefTypeWeComApproval = "wecom_approval"
// NotificationRefTypeIotCard 表示物联网卡详情资源引用。
NotificationRefTypeIotCard = "iot_card"
// NotificationRefTypeDevice 表示设备详情资源引用。
NotificationRefTypeDevice = "device"
// NotificationRefTypeExpiringAsset 表示临期资产列表资源引用。
NotificationRefTypeExpiringAsset = "expiring_asset"
// NotificationRefTypeShopFund 表示店铺资金概况资源引用。
NotificationRefTypeShopFund = "shop_fund"
// NotificationRefTypeCardSync 表示卡同步外部集成资源引用。
NotificationRefTypeCardSync = "card_sync"
// NotificationTargetTypeRefundDetail 表示退款详情前端目标。
NotificationTargetTypeRefundDetail = "refund_detail"
// NotificationTargetTypeAgentRechargeDetail 表示代理充值详情前端目标。
NotificationTargetTypeAgentRechargeDetail = "agent_recharge_detail"
// NotificationTargetTypeWeComApprovalDetail 表示企微审批详情前端目标。
NotificationTargetTypeWeComApprovalDetail = "wecom_approval_detail"
// NotificationTargetTypeIotCardDetail 表示物联网卡详情前端目标。
NotificationTargetTypeIotCardDetail = "iot_card_detail"
// NotificationTargetTypeDeviceDetail 表示设备详情前端目标。
NotificationTargetTypeDeviceDetail = "device_detail"
// NotificationTargetTypeExpiringAssetList 表示临期资产列表前端目标。
NotificationTargetTypeExpiringAssetList = "expiring_asset_list"
// NotificationTargetTypeShopFundSummary 表示店铺资金概况前端目标。
NotificationTargetTypeShopFundSummary = "shop_fund_summary"
// NotificationTargetTypeIntegrationLog 表示统一外部集成前端目标。
NotificationTargetTypeIntegrationLog = "integration_log"
// NotificationTargetTypeSystemConfig 表示受控系统配置前端目标。
NotificationTargetTypeSystemConfig = "system_config"
// OutboxEventTypeAdminDirectNotification 表示向明确后台账号投递通知的稳定事件类型。
OutboxEventTypeAdminDirectNotification = "notification.admin.direct.requested"
// OutboxEventTypePersonalCustomerDirectNotification 表示向明确个人客户投递通知的稳定事件类型。
OutboxEventTypePersonalCustomerDirectNotification = "notification.personal_customer.direct.requested"
// OutboxEventTypeAdminDynamicNotification 表示按账号、平台角色或店铺动态解析后台接收人的事件类型。
OutboxEventTypeAdminDynamicNotification = "notification.admin.dynamic.requested"
// NotificationPayloadVersionV1 表示明确后台账号通知载荷第一版。
NotificationPayloadVersionV1 = 1
// NotificationDefaultPageSize 表示后台通知默认每页数量。
NotificationDefaultPageSize = 20
// NotificationMaxPageSize 表示后台通知每页最大数量。
NotificationMaxPageSize = 50
// NotificationMaxPage 表示通知列表允许查询的最大页码,避免无界偏移。
NotificationMaxPage = 10000
// NotificationMaxTitleLength 表示通知纯文本标题最大字符数。
NotificationMaxTitleLength = 200
// NotificationMaxBodyLength 表示通知纯文本正文最大字符数。
NotificationMaxBodyLength = 2000
// NotificationExpiryRetentionDays 表示临期通知数据保留天数。
NotificationExpiryRetentionDays = 180
// NotificationApprovalRetentionDays 表示审批结果通知数据保留天数。
NotificationApprovalRetentionDays = 365
// NotificationSyncDisplayDays 表示同步异常默认展示天数。
NotificationSyncDisplayDays = 30
// NotificationSyncRetentionDays 表示同步异常通知数据保留天数。
NotificationSyncRetentionDays = 180
// NotificationSystemDefaultDisplayDays 表示系统告警默认展示天数。
NotificationSystemDefaultDisplayDays = 30
// NotificationSystemMaxDisplayDays 表示系统告警最长展示天数。
NotificationSystemMaxDisplayDays = 365
// NotificationSystemRetentionDays 表示系统告警数据保留天数。
NotificationSystemRetentionDays = 365
// NotificationCleanupBatchSize 表示单批清理通知数量。
NotificationCleanupBatchSize = 500
// NotificationCleanupMaxBatches 表示每类通知单次任务最多清理批次数。
NotificationCleanupMaxBatches = 20
)

View File

@@ -474,6 +474,36 @@ func RedisPollingRealnameReversalCountKey(cardID uint) string {
return fmt.Sprintf("polling:card:realname:reversal:%d", cardID)
}
// RedisCardObservationSeriesKey 返回同场景观测序列合并键。
func RedisCardObservationSeriesKey(scene, resourceType, resourceID, syncType string) string {
return fmt.Sprintf("cardsync:series:%s:%s:%s:%s", scene, resourceType, resourceID, syncType)
}
// RedisCardObservationSeriesIndexKey 返回同资源、同步类型的活跃序列索引键。
func RedisCardObservationSeriesIndexKey(resourceType, resourceID, syncType string) string {
return fmt.Sprintf("cardsync:series:index:%s:%s:%s", resourceType, resourceID, syncType)
}
// RedisCardObservationSeriesCompletedKey 返回序列提前完成标记键。
func RedisCardObservationSeriesCompletedKey(seriesID string) string {
return fmt.Sprintf("cardsync:series:completed:%s", seriesID)
}
// RedisCardObservationAttemptKey 返回 series_id + attempt 幂等键。
func RedisCardObservationAttemptKey(seriesID string, attempt int) string {
return fmt.Sprintf("cardsync:attempt:%s:%d", seriesID, attempt)
}
// RedisCardObservationInflightKey 返回一次实际 Gateway 请求的互斥键。
func RedisCardObservationInflightKey(provider, syncType, resourceID string) string {
return fmt.Sprintf("cardsync:inflight:%s:%s:%s", provider, syncType, resourceID)
}
// RedisCardObservationLastRequestKey 返回运营商接入与同步类型的最近请求时间键。
func RedisCardObservationLastRequestKey(provider, syncType, resourceID string) string {
return fmt.Sprintf("cardsync:last_request:%s:%s:%s", provider, syncType, resourceID)
}
// RedisPollingDeviceOpLockKey 设备维度停复机操作锁 Key
// 防止设备下多张卡并发触发 EvaluateAndAct 导致重复 Gateway 调用
// TTL 建议 30 秒(覆盖 stopDeviceCards/resumeDeviceCards 最长执行时间)

View File

@@ -14,6 +14,15 @@ const (
AgentWalletTypeCommission = "commission" // 分佣钱包
)
// 代理主钱包信用管理权限
const (
PermissionRoleDefaultCreditManage = "role:default-credit:manage" // 配置客户角色的新建代理默认信用模板
PermissionShopCreditLimitManage = "shop:credit-limit:manage" // 前端控制店铺实际信用额度按钮显示
)
// AgentFundManagementForbiddenMessage 是企业账号访问代理资金功能时的统一拒绝提示。
const AgentFundManagementForbiddenMessage = "企业账号无权访问代理资金功能"
// 代理钱包状态
const (
AgentWalletStatusNormal = 1 // 正常
@@ -29,12 +38,37 @@ const (
AgentTransactionTypeCommission = "commission" // 分佣
AgentTransactionTypeWithdrawal = "withdrawal" // 提现
AgentTransactionTypeCommissionDeduct = "commission_deduct" // 退款佣金回扣
AgentTransactionTypeAdjustment = "adjustment" // 人工余额调整
)
// 代理钱包交易子类型(当 transaction_type = "deduct" 用于订单支付时)
const (
WalletTransactionSubtypeSelfPurchase = "self_purchase" // 自购
WalletTransactionSubtypePurchaseForSubordinate = "purchase_for_subordinate" // 给下级代理购买
// OutboxEventTypeAgentMainWalletDebited 表示代理主钱包订单扣款已提交。
OutboxEventTypeAgentMainWalletDebited = "wallet.agent_main.debited"
// AgentMainWalletDebitedPayloadVersionV1 是代理主钱包扣款事件载荷版本。
AgentMainWalletDebitedPayloadVersionV1 = 1
// OutboxEventTypeAgentMainWalletReservationChanged 表示代理主钱包预占状态已变化。
OutboxEventTypeAgentMainWalletReservationChanged = "wallet.agent_main.reservation.changed"
// AgentMainWalletReservationPayloadVersionV1 是代理主钱包预占事件载荷版本。
AgentMainWalletReservationPayloadVersionV1 = 1
// OutboxEventTypeAgentMainWalletCredited 表示代理主钱包正向入账已提交。
OutboxEventTypeAgentMainWalletCredited = "wallet.agent_main.credited"
// AgentMainWalletCreditedPayloadVersionV1 是代理主钱包入账事件载荷版本。
AgentMainWalletCreditedPayloadVersionV1 = 1
// OutboxEventTypeAgentMainWalletRefunded 表示代理主钱包订单退款回充已提交。
OutboxEventTypeAgentMainWalletRefunded = "wallet.agent_main.refunded"
// AgentMainWalletRefundedPayloadVersionV1 是代理主钱包退款回充事件载荷版本。
AgentMainWalletRefundedPayloadVersionV1 = 1
)
// 代理主钱包预占状态
const (
AgentWalletReservationStatusFrozen = 1 // 已冻结
AgentWalletReservationStatusReleased = 2 // 已释放
AgentWalletReservationStatusCompleted = 3 // 已完成扣除
)
// 代理充值订单号前缀
@@ -111,12 +145,13 @@ const (
// 关联业务类型
const (
ReferenceTypeOrder = "order" // 订单
ReferenceTypeCommission = "commission" // 分佣
ReferenceTypeWithdrawal = "withdrawal" // 提现
ReferenceTypeTopup = "topup" // 充值
ReferenceTypeRefund = "refund" // 退款
ReferenceTypeExchange = "exchange" // 换货
ReferenceTypeOrder = "order" // 订单
ReferenceTypeCommission = "commission" // 分佣
ReferenceTypeWithdrawal = "withdrawal" // 提现
ReferenceTypeTopup = "topup" // 充值
ReferenceTypeRefund = "refund" // 退款
ReferenceTypeExchange = "exchange" // 换货
ReferenceTypeManualAdjustment = "manual_adjustment" // 人工余额调整
)
// ========== Redis Key 生成函数 ==========

View File

@@ -25,6 +25,7 @@ func BuildDocHandlers() *bootstrap.Handlers {
ClientRealname: app.NewClientRealnameHandler(nil, nil, nil, nil, nil, nil, nil, nil),
ClientDevice: app.NewClientDeviceHandler(nil, nil, nil, nil, nil, nil, nil),
ClientRechargeOrder: app.NewClientRechargeOrderHandler(nil, nil, nil),
ClientNotification: app.NewClientNotificationHandler(nil, nil, nil),
Shop: admin.NewShopHandler(nil, nil),
ShopRole: admin.NewShopRoleHandler(nil),
AdminAuth: admin.NewAuthHandler(nil, nil),
@@ -38,6 +39,7 @@ func BuildDocHandlers() *bootstrap.Handlers {
IotCard: admin.NewIotCardHandler(nil),
IotCardImport: admin.NewIotCardImportHandler(nil),
ExportTask: admin.NewExportTaskHandler(nil),
Notification: admin.NewNotificationHandler(nil, nil, nil),
Device: admin.NewDeviceHandler(nil),
DeviceImport: admin.NewDeviceImportHandler(nil),
AssetAllocationRecord: admin.NewAssetAllocationRecordHandler(nil),

View File

@@ -0,0 +1,41 @@
package queue
import (
"context"
"errors"
"strconv"
"github.com/hibiken/asynq"
cardapp "github.com/break/junhong_cmp_fiber/internal/application/cardobservation"
"github.com/break/junhong_cmp_fiber/pkg/constants"
)
// CardObservationSeriesScheduler 将固定阶梯任务提交到独立队列。
type CardObservationSeriesScheduler struct {
client *Client
}
// NewCardObservationSeriesScheduler 创建卡观测序列任务调度器。
func NewCardObservationSeriesScheduler(client *Client) *CardObservationSeriesScheduler {
return &CardObservationSeriesScheduler{client: client}
}
// Enqueue 以稳定 series_id + attempt 任务 ID 零重试入队。
func (s *CardObservationSeriesScheduler) Enqueue(ctx context.Context, payload cardapp.SeriesTaskPayload) error {
taskID := "card-series-" + payload.SeriesID + "-" + strconv.Itoa(payload.Attempt)
err := s.client.EnqueueTask(
ctx,
constants.TaskTypeCardObservationSeries,
payload,
asynq.TaskID(taskID),
asynq.ProcessAt(payload.ScheduledAt),
asynq.MaxRetry(0),
)
if errors.Is(err, asynq.ErrTaskIDConflict) {
return nil
}
return err
}
var _ cardapp.SeriesScheduler = (*CardObservationSeriesScheduler)(nil)

View File

@@ -8,6 +8,8 @@ import (
"github.com/break/junhong_cmp_fiber/internal/exporter"
"github.com/break/junhong_cmp_fiber/internal/gateway"
"github.com/break/junhong_cmp_fiber/internal/infrastructure/integrationlog"
notification "github.com/break/junhong_cmp_fiber/internal/infrastructure/notification"
"github.com/break/junhong_cmp_fiber/internal/polling"
iot_card_svc "github.com/break/junhong_cmp_fiber/internal/service/iot_card"
"github.com/break/junhong_cmp_fiber/internal/store/postgres"
@@ -70,10 +72,12 @@ func (h *Handler) RegisterHandlers() *asynq.ServeMux {
h.registerCommissionStatsHandlers()
h.registerCommissionCalculationHandler()
h.registerPollingHandlers()
h.registerCardObservationSeriesHandler()
h.registerPackageActivationHandlers()
h.registerOrderExpireHandler()
h.registerAlertCheckHandler()
h.registerDataCleanupHandler()
h.registerNotificationCleanupHandler()
h.registerAutoPurchaseHandler()
h.registerDailyTrafficFlushHandler()
@@ -81,6 +85,12 @@ func (h *Handler) RegisterHandlers() *asynq.ServeMux {
return h.mux
}
func (h *Handler) registerCardObservationSeriesHandler() {
handler := task.NewCardObservationSeriesHandler(h.workerResult.Services.CardObservationSeries, h.logger)
h.mux.HandleFunc(constants.TaskTypeCardObservationSeries, handler.Handle)
h.logger.Info("注册卡观测事件序列任务处理器", zap.String("task_type", constants.TaskTypeCardObservationSeries))
}
func (h *Handler) registerIotCardImportHandler() {
iotCardImportHandler := task.NewIotCardImportHandler(
h.db,
@@ -208,13 +218,12 @@ func (h *Handler) registerCommissionCalculationHandler() {
}
func (h *Handler) registerPollingHandlers() {
integrationRepository := integrationlog.NewRepository(h.db)
realnameHandler := task.NewPollingRealnameHandler(
h.pollingBase, h.gatewayClient, h.workerResult.Stores.IotCard,
h.asynqClient, h.pollingStopResumeSvc, h.workerResult.Stores.DeviceSimBinding)
h.pollingBase, h.gatewayClient, h.workerResult.Services.CardObservation, integrationRepository)
carrierStore := postgres.NewCarrierStore(h.db)
carddataHandler := task.NewPollingCarddataHandler(
h.pollingBase, h.gatewayClient, h.workerResult.Stores.IotCard,
carrierStore, h.workerResult.Services.UsageService, h.pollingStopResumeSvc)
h.pollingBase, h.gatewayClient, carrierStore, h.workerResult.Services.CardObservation, integrationRepository)
packageHandler := task.NewPollingPackageHandler(
h.pollingBase, h.workerResult.Stores.IotCard,
h.pollingStopResumeSvc)
@@ -222,7 +231,7 @@ func (h *Handler) registerPollingHandlers() {
h.pollingBase, h.gatewayClient, h.workerResult.Stores.IotCard,
h.workerResult.Stores.DeviceSimBinding, h.pollingStopResumeSvc)
cardStatusHandler := task.NewPollingCardStatusHandler(
h.pollingBase, h.gatewayClient, h.workerResult.Stores.IotCard, h.pollingStopResumeSvc)
h.pollingBase, h.gatewayClient, h.workerResult.Services.CardObservation, integrationRepository)
h.mux.HandleFunc(constants.TaskTypePollingRealname, realnameHandler.Handle)
h.mux.HandleFunc(constants.TaskTypePollingCarddata, carddataHandler.Handle)
@@ -267,6 +276,13 @@ func (h *Handler) registerDataCleanupHandler() {
h.logger.Info("注册数据清理任务处理器", zap.String("task_type", constants.TaskTypeDataCleanup))
}
func (h *Handler) registerNotificationCleanupHandler() {
cleanupService := notification.NewCleanupService(h.db, h.logger)
cleanupHandler := task.NewNotificationCleanupHandler(cleanupService, h.logger)
h.mux.HandleFunc(constants.TaskTypeNotificationCleanup, cleanupHandler.Handle)
h.logger.Info("注册站内通知保留清理任务处理器", zap.String("task_type", constants.TaskTypeNotificationCleanup))
}
func (h *Handler) registerAutoPurchaseHandler() {
autoPurchaseHandler := task.NewAutoPurchaseHandler(
h.db,

View File

@@ -3,6 +3,7 @@ package queue
import (
"context"
cardObservationApp "github.com/break/junhong_cmp_fiber/internal/application/cardobservation"
"github.com/break/junhong_cmp_fiber/internal/service/commission_calculation"
"github.com/break/junhong_cmp_fiber/internal/service/commission_stats"
packagepkg "github.com/break/junhong_cmp_fiber/internal/service/package"
@@ -19,33 +20,33 @@ type OrderExpirer interface {
// WorkerStores Worker 侧所有 Store 的集合
type WorkerStores struct {
AssetOperationLog *postgres.AssetOperationLogStore
IotCardImportTask *postgres.IotCardImportTaskStore
IotCard *postgres.IotCardStore
DeviceImportTask *postgres.DeviceImportTaskStore
ExportTask *postgres.ExportTaskStore
ExportShardTask *postgres.ExportShardTaskStore
Device *postgres.DeviceStore
DeviceSimBinding *postgres.DeviceSimBindingStore
ShopSeriesCommissionStats *postgres.ShopSeriesCommissionStatsStore
ShopPackageAllocation *postgres.ShopPackageAllocationStore
CommissionRecord *postgres.CommissionRecordStore
Shop *postgres.ShopStore
ShopSeriesAllocation *postgres.ShopSeriesAllocationStore
PackageSeries *postgres.PackageSeriesStore
Order *postgres.OrderStore
OrderItem *postgres.OrderItemStore
Package *postgres.PackageStore
PackageUsage *postgres.PackageUsageStore
PackageUsageDailyRecord *postgres.PackageUsageDailyRecordStore
PollingAlertRule *postgres.PollingAlertRuleStore
PollingAlertHistory *postgres.PollingAlertHistoryStore
DataCleanupConfig *postgres.DataCleanupConfigStore
DataCleanupLog *postgres.DataCleanupLogStore
AgentWallet *postgres.AgentWalletStore
AgentWalletTransaction *postgres.AgentWalletTransactionStore
AssetWallet *postgres.AssetWalletStore
AssetIdentifier *postgres.AssetIdentifierStore
AssetOperationLog *postgres.AssetOperationLogStore
IotCardImportTask *postgres.IotCardImportTaskStore
IotCard *postgres.IotCardStore
DeviceImportTask *postgres.DeviceImportTaskStore
ExportTask *postgres.ExportTaskStore
ExportShardTask *postgres.ExportShardTaskStore
Device *postgres.DeviceStore
DeviceSimBinding *postgres.DeviceSimBindingStore
ShopSeriesCommissionStats *postgres.ShopSeriesCommissionStatsStore
ShopPackageAllocation *postgres.ShopPackageAllocationStore
CommissionRecord *postgres.CommissionRecordStore
Shop *postgres.ShopStore
ShopSeriesAllocation *postgres.ShopSeriesAllocationStore
PackageSeries *postgres.PackageSeriesStore
Order *postgres.OrderStore
OrderItem *postgres.OrderItemStore
Package *postgres.PackageStore
PackageUsage *postgres.PackageUsageStore
PackageUsageDailyRecord *postgres.PackageUsageDailyRecordStore
PollingAlertRule *postgres.PollingAlertRuleStore
PollingAlertHistory *postgres.PollingAlertHistoryStore
DataCleanupConfig *postgres.DataCleanupConfigStore
DataCleanupLog *postgres.DataCleanupLogStore
AgentWallet *postgres.AgentWalletStore
AgentWalletTransaction *postgres.AgentWalletTransactionStore
AssetWallet *postgres.AssetWalletStore
AssetIdentifier *postgres.AssetIdentifierStore
PersonalCustomer *postgres.PersonalCustomerStore
PersonalCustomerPhone *postgres.PersonalCustomerPhoneStore
OrderPackageInvalidateTask *postgres.OrderPackageInvalidateTaskStore
@@ -53,6 +54,8 @@ type WorkerStores struct {
// WorkerServices Worker 侧所有 Service 的集合
type WorkerServices struct {
CardObservation *cardObservationApp.Service
CardObservationSeries *cardObservationApp.SeriesAttemptService
CommissionCalculation *commission_calculation.Service
CommissionStats *commission_stats.Service
UsageService *packagepkg.UsageService