All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m17s
## 变更概述 将统一钱包系统拆分为代理钱包和卡钱包两个独立系统,实现数据表和代码层面的完全隔离。 ## 数据库变更 - 新增 6 张表:tb_agent_wallet、tb_agent_wallet_transaction、tb_agent_recharge_record、tb_card_wallet、tb_card_wallet_transaction、tb_card_recharge_record - 删除 3 张旧表:tb_wallet、tb_wallet_transaction、tb_recharge_record - 代理钱包:按 (shop_id, wallet_type) 唯一标识,支持主钱包和分佣钱包 - 卡钱包:按 (resource_type, resource_id) 唯一标识,支持物联网卡和设备 ## 代码变更 - Model 层:新增 AgentWallet、AgentWalletTransaction、AgentRechargeRecord、CardWallet、CardWalletTransaction、CardRechargeRecord 模型 - Store 层:新增 6 个独立 Store,支持事务、乐观锁、Redis 缓存 - Service 层:重构 commission_calculation、commission_withdrawal、order、recharge 等 8 个服务 - Bootstrap 层:更新 Store 和 Service 依赖注入 - 常量层:按钱包类型重新组织常量和 Redis Key 生成函数 ## 技术特性 - 乐观锁:使用 version 字段防止并发冲突 - 多租户:支持 shop_id_tag 和 enterprise_id_tag 过滤 - 事务管理:所有余额变动使用事务保证 ACID - 缓存策略:Cache-Aside 模式,余额变动后删除缓存 ## 业务影响 - 代理钱包和卡钱包业务完全隔离,互不影响 - 为独立监控、优化、扩展打下基础 - 提升代理钱包的稳定性和独立性 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
153 lines
12 KiB
Go
153 lines
12 KiB
Go
package model
|
||
|
||
import (
|
||
"time"
|
||
)
|
||
|
||
// PollingConfig 轮询配置表
|
||
type PollingConfig struct {
|
||
ID uint `gorm:"column:id;primaryKey;autoIncrement" json:"id"`
|
||
ConfigName string `gorm:"column:config_name;type:varchar(100);not null;comment:配置名称" json:"config_name"`
|
||
CardCondition string `gorm:"column:card_condition;type:varchar(50);comment:卡状态条件:not_real_name/real_name/activated/suspended" json:"card_condition"`
|
||
CardCategory string `gorm:"column:card_category;type:varchar(50);comment:卡业务类型:normal/industry" json:"card_category"`
|
||
CarrierID *uint `gorm:"column:carrier_id;comment:运营商ID(可选,精确匹配)" json:"carrier_id"`
|
||
Priority int `gorm:"column:priority;not null;default:100;comment:优先级(数字越小优先级越高)" json:"priority"`
|
||
RealnameCheckInterval *int `gorm:"column:realname_check_interval;comment:实名检查间隔(秒),NULL表示不检查" json:"realname_check_interval"`
|
||
CarddataCheckInterval *int `gorm:"column:carddata_check_interval;comment:流量检查间隔(秒),NULL表示不检查" json:"carddata_check_interval"`
|
||
PackageCheckInterval *int `gorm:"column:package_check_interval;comment:套餐检查间隔(秒),NULL表示不检查" json:"package_check_interval"`
|
||
Status int16 `gorm:"column:status;type:smallint;not null;default:1;comment:状态:0-禁用,1-启用" json:"status"`
|
||
Description string `gorm:"column:description;type:text;comment:配置说明" json:"description"`
|
||
CreatedAt time.Time `gorm:"column:created_at;not null;default:CURRENT_TIMESTAMP;comment:创建时间" json:"created_at"`
|
||
UpdatedAt time.Time `gorm:"column:updated_at;not null;default:CURRENT_TIMESTAMP;comment:更新时间" json:"updated_at"`
|
||
CreatedBy *uint `gorm:"column:created_by;comment:创建人ID" json:"created_by"`
|
||
UpdatedBy *uint `gorm:"column:updated_by;comment:更新人ID" json:"updated_by"`
|
||
}
|
||
|
||
// TableName 指定表名
|
||
func (PollingConfig) TableName() string {
|
||
return "tb_polling_config"
|
||
}
|
||
|
||
// PollingConcurrencyConfig 并发控制配置表
|
||
type PollingConcurrencyConfig struct {
|
||
ID uint `gorm:"column:id;primaryKey;autoIncrement" json:"id"`
|
||
TaskType string `gorm:"column:task_type;type:varchar(50);uniqueIndex;not null;comment:任务类型:realname/carddata/package/stop_start" json:"task_type"`
|
||
MaxConcurrency int `gorm:"column:max_concurrency;not null;default:50;comment:最大并发数" json:"max_concurrency"`
|
||
Description string `gorm:"column:description;type:text;comment:配置说明" json:"description"`
|
||
CreatedAt time.Time `gorm:"column:created_at;not null;default:CURRENT_TIMESTAMP;comment:创建时间" json:"created_at"`
|
||
UpdatedAt time.Time `gorm:"column:updated_at;not null;default:CURRENT_TIMESTAMP;comment:更新时间" json:"updated_at"`
|
||
UpdatedBy *uint `gorm:"column:updated_by;comment:更新人ID" json:"updated_by"`
|
||
}
|
||
|
||
// TableName 指定表名
|
||
func (PollingConcurrencyConfig) TableName() string {
|
||
return "tb_polling_concurrency_config"
|
||
}
|
||
|
||
// PollingAlertRule 告警规则表
|
||
type PollingAlertRule struct {
|
||
ID uint `gorm:"column:id;primaryKey;autoIncrement" json:"id"`
|
||
RuleName string `gorm:"column:rule_name;type:varchar(100);not null;comment:规则名称" json:"rule_name"`
|
||
TaskType string `gorm:"column:task_type;type:varchar(50);not null;comment:任务类型:realname/carddata/package" json:"task_type"`
|
||
MetricType string `gorm:"column:metric_type;type:varchar(50);not null;comment:指标类型:queue_size/success_rate/avg_duration/concurrency" json:"metric_type"`
|
||
Operator string `gorm:"column:operator;type:varchar(20);not null;comment:比较运算符:gt/lt/gte/lte/eq" json:"operator"`
|
||
Threshold float64 `gorm:"column:threshold;type:decimal(10,2);not null;comment:阈值" json:"threshold"`
|
||
DurationMinutes int `gorm:"column:duration_minutes;not null;default:5;comment:持续时长(分钟),避免短暂波动" json:"duration_minutes"`
|
||
AlertLevel string `gorm:"column:alert_level;type:varchar(20);not null;default:'warning';comment:告警级别:info/warning/error/critical" json:"alert_level"`
|
||
NotificationChannels string `gorm:"column:notification_channels;type:text;comment:通知渠道(JSON数组):[\"email\",\"sms\",\"webhook\"]" json:"notification_channels"`
|
||
NotificationConfig string `gorm:"column:notification_config;type:text;comment:通知配置(JSON)" json:"notification_config"`
|
||
Status int16 `gorm:"column:status;type:smallint;not null;default:1;comment:状态:0-禁用,1-启用" json:"status"`
|
||
CooldownMinutes int `gorm:"column:cooldown_minutes;not null;default:5;comment:冷却期(分钟),避免重复告警" json:"cooldown_minutes"`
|
||
Description string `gorm:"column:description;type:text;comment:规则说明" json:"description"`
|
||
CreatedAt time.Time `gorm:"column:created_at;not null;default:CURRENT_TIMESTAMP;comment:创建时间" json:"created_at"`
|
||
UpdatedAt time.Time `gorm:"column:updated_at;not null;default:CURRENT_TIMESTAMP;comment:更新时间" json:"updated_at"`
|
||
CreatedBy *uint `gorm:"column:created_by;comment:创建人ID" json:"created_by"`
|
||
UpdatedBy *uint `gorm:"column:updated_by;comment:更新人ID" json:"updated_by"`
|
||
}
|
||
|
||
// TableName 指定表名
|
||
func (PollingAlertRule) TableName() string {
|
||
return "tb_polling_alert_rule"
|
||
}
|
||
|
||
// PollingAlertHistory 告警历史表
|
||
type PollingAlertHistory struct {
|
||
ID uint `gorm:"column:id;primaryKey;autoIncrement" json:"id"`
|
||
RuleID uint `gorm:"column:rule_id;not null;comment:告警规则ID" json:"rule_id"`
|
||
TaskType string `gorm:"column:task_type;type:varchar(50);not null;comment:任务类型" json:"task_type"`
|
||
MetricType string `gorm:"column:metric_type;type:varchar(50);not null;comment:指标类型" json:"metric_type"`
|
||
AlertLevel string `gorm:"column:alert_level;type:varchar(20);not null;comment:告警级别" json:"alert_level"`
|
||
CurrentValue float64 `gorm:"column:current_value;type:decimal(10,2);not null;comment:当前值" json:"current_value"`
|
||
Threshold float64 `gorm:"column:threshold;type:decimal(10,2);not null;comment:阈值" json:"threshold"`
|
||
AlertMessage string `gorm:"column:alert_message;type:text;not null;comment:告警消息" json:"alert_message"`
|
||
NotificationChannels string `gorm:"column:notification_channels;type:text;comment:通知渠道(JSON数组)" json:"notification_channels"`
|
||
NotificationStatus string `gorm:"column:notification_status;type:varchar(20);comment:通知状态:pending/sent/failed" json:"notification_status"`
|
||
NotificationResult string `gorm:"column:notification_result;type:text;comment:通知结果(JSON)" json:"notification_result"`
|
||
CreatedAt time.Time `gorm:"column:created_at;not null;default:CURRENT_TIMESTAMP;comment:告警时间" json:"created_at"`
|
||
}
|
||
|
||
// TableName 指定表名
|
||
func (PollingAlertHistory) TableName() string {
|
||
return "tb_polling_alert_history"
|
||
}
|
||
|
||
// DataCleanupConfig 数据清理配置表
|
||
type DataCleanupConfig struct {
|
||
ID uint `gorm:"column:id;primaryKey;autoIncrement" json:"id"`
|
||
TargetTable string `gorm:"column:table_name;type:varchar(100);uniqueIndex;not null;comment:表名" json:"table_name"`
|
||
RetentionDays int `gorm:"column:retention_days;not null;comment:保留天数" json:"retention_days"`
|
||
Enabled int16 `gorm:"column:enabled;type:smallint;not null;default:1;comment:是否启用:0-禁用,1-启用" json:"enabled"`
|
||
BatchSize int `gorm:"column:batch_size;not null;default:10000;comment:每批删除条数" json:"batch_size"`
|
||
Description string `gorm:"column:description;type:text;comment:配置说明" json:"description"`
|
||
CreatedAt time.Time `gorm:"column:created_at;not null;default:CURRENT_TIMESTAMP;comment:创建时间" json:"created_at"`
|
||
UpdatedAt time.Time `gorm:"column:updated_at;not null;default:CURRENT_TIMESTAMP;comment:更新时间" json:"updated_at"`
|
||
UpdatedBy *uint `gorm:"column:updated_by;comment:更新人ID" json:"updated_by"`
|
||
}
|
||
|
||
// TableName 指定表名
|
||
func (DataCleanupConfig) TableName() string {
|
||
return "tb_data_cleanup_config"
|
||
}
|
||
|
||
// DataCleanupLog 数据清理日志表
|
||
type DataCleanupLog struct {
|
||
ID uint `gorm:"column:id;primaryKey;autoIncrement" json:"id"`
|
||
TargetTable string `gorm:"column:table_name;type:varchar(100);not null;comment:表名" json:"table_name"`
|
||
CleanupType string `gorm:"column:cleanup_type;type:varchar(50);not null;comment:清理类型:scheduled/manual" json:"cleanup_type"`
|
||
RetentionDays int `gorm:"column:retention_days;not null;comment:保留天数" json:"retention_days"`
|
||
DeletedCount int64 `gorm:"column:deleted_count;not null;default:0;comment:删除记录数" json:"deleted_count"`
|
||
DurationMs int64 `gorm:"column:duration_ms;not null;default:0;comment:执行耗时(毫秒)" json:"duration_ms"`
|
||
Status string `gorm:"column:status;type:varchar(20);not null;comment:状态:success/failed/running" json:"status"`
|
||
ErrorMessage string `gorm:"column:error_message;type:text;comment:错误信息" json:"error_message"`
|
||
StartedAt time.Time `gorm:"column:started_at;not null;comment:开始时间" json:"started_at"`
|
||
CompletedAt *time.Time `gorm:"column:completed_at;comment:完成时间" json:"completed_at"`
|
||
TriggeredBy *uint `gorm:"column:triggered_by;comment:触发人ID(手动触发时)" json:"triggered_by"`
|
||
}
|
||
|
||
// TableName 指定表名
|
||
func (DataCleanupLog) TableName() string {
|
||
return "tb_data_cleanup_log"
|
||
}
|
||
|
||
// PollingManualTriggerLog 手动触发日志表
|
||
type PollingManualTriggerLog struct {
|
||
ID uint `gorm:"column:id;primaryKey;autoIncrement" json:"id"`
|
||
TaskType string `gorm:"column:task_type;type:varchar(50);not null;comment:任务类型:realname/carddata/package" json:"task_type"`
|
||
TriggerType string `gorm:"column:trigger_type;type:varchar(50);not null;comment:触发类型:single/batch/by_condition" json:"trigger_type"`
|
||
CardIDs string `gorm:"column:card_ids;type:text;comment:卡ID列表(JSON数组)" json:"card_ids"`
|
||
ConditionFilter string `gorm:"column:condition_filter;type:text;comment:筛选条件(JSON)" json:"condition_filter"`
|
||
TotalCount int `gorm:"column:total_count;not null;default:0;comment:总卡数" json:"total_count"`
|
||
ProcessedCount int `gorm:"column:processed_count;not null;default:0;comment:已处理数" json:"processed_count"`
|
||
SuccessCount int `gorm:"column:success_count;not null;default:0;comment:成功数" json:"success_count"`
|
||
FailedCount int `gorm:"column:failed_count;not null;default:0;comment:失败数" json:"failed_count"`
|
||
Status string `gorm:"column:status;type:varchar(20);not null;comment:状态:pending/processing/completed/cancelled" json:"status"`
|
||
TriggeredBy uint `gorm:"column:triggered_by;not null;comment:触发人ID" json:"triggered_by"`
|
||
TriggeredAt time.Time `gorm:"column:triggered_at;not null;default:CURRENT_TIMESTAMP;comment:触发时间" json:"triggered_at"`
|
||
CompletedAt *time.Time `gorm:"column:completed_at;comment:完成时间" json:"completed_at"`
|
||
}
|
||
|
||
// TableName 指定表名
|
||
func (PollingManualTriggerLog) TableName() string {
|
||
return "tb_polling_manual_trigger_log"
|
||
}
|