ShopSeriesAllocation 新增 commission_tiers_json(梯度模式专属阶梯 JSON)、enable_force_recharge(代理自设强充开关)、force_recharge_amount(强充金额,0 表示使用阈值)字段;移除与 PackageSeries 重复的三个字段。Package 模型补充 PackageSeriesID 字段,用于系列授权套餐归属校验。 Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
175 lines
11 KiB
Go
175 lines
11 KiB
Go
package model
|
||
|
||
import (
|
||
"encoding/json"
|
||
"time"
|
||
|
||
"gorm.io/gorm"
|
||
)
|
||
|
||
// PackageSeries 套餐系列模型
|
||
// 套餐的分组,用于一次性分佣规则配置
|
||
type PackageSeries struct {
|
||
gorm.Model
|
||
BaseModel `gorm:"embedded"`
|
||
SeriesCode string `gorm:"column:series_code;type:varchar(100);uniqueIndex:idx_package_series_code,where:deleted_at IS NULL;not null;comment:系列编码" json:"series_code"`
|
||
SeriesName string `gorm:"column:series_name;type:varchar(255);not null;comment:系列名称" json:"series_name"`
|
||
Description string `gorm:"column:description;type:text;comment:描述" json:"description"`
|
||
Status int `gorm:"column:status;type:int;default:1;not null;comment:状态 1-启用 2-禁用" json:"status"`
|
||
OneTimeCommissionConfigJSON string `gorm:"column:one_time_commission_config;type:jsonb;default:'{}';comment:一次性佣金规则配置" json:"-"`
|
||
EnableOneTimeCommission bool `gorm:"column:enable_one_time_commission;default:false;comment:是否启用一次性佣金(顶层字段,支持SQL索引)" json:"enable_one_time_commission"`
|
||
}
|
||
|
||
// TableName 指定表名
|
||
func (PackageSeries) TableName() string {
|
||
return "tb_package_series"
|
||
}
|
||
|
||
// Package 套餐模型
|
||
// 只适用于 IoT 卡,支持真流量/虚流量共存机制
|
||
type Package struct {
|
||
gorm.Model
|
||
BaseModel `gorm:"embedded"`
|
||
PackageCode string `gorm:"column:package_code;type:varchar(100);uniqueIndex:idx_package_code,where:deleted_at IS NULL;not null;comment:套餐编码" json:"package_code"`
|
||
PackageName string `gorm:"column:package_name;type:varchar(255);not null;comment:套餐名称" json:"package_name"`
|
||
SeriesID uint `gorm:"column:series_id;index;comment:套餐系列ID" json:"series_id"`
|
||
PackageType string `gorm:"column:package_type;type:varchar(50);not null;comment:套餐类型 formal-正式套餐 addon-附加套餐" json:"package_type"`
|
||
DurationMonths int `gorm:"column:duration_months;type:int;not null;comment:套餐时长(月数) 1-月套餐 12-年套餐" json:"duration_months"`
|
||
RealDataMB int64 `gorm:"column:real_data_mb;type:bigint;default:0;comment:真流量额度(MB)" json:"real_data_mb"`
|
||
VirtualDataMB int64 `gorm:"column:virtual_data_mb;type:bigint;default:0;comment:虚流量额度(MB,用于停机判断)" json:"virtual_data_mb"`
|
||
EnableVirtualData bool `gorm:"column:enable_virtual_data;type:boolean;default:false;not null;comment:是否启用虚流量" json:"enable_virtual_data"`
|
||
Status int `gorm:"column:status;type:int;default:1;not null;comment:状态 1-启用 2-禁用" json:"status"`
|
||
CostPrice int64 `gorm:"column:cost_price;type:bigint;default:0;comment:成本价(分为单位)" json:"cost_price"`
|
||
SuggestedRetailPrice int64 `gorm:"column:suggested_retail_price;type:bigint;default:0;comment:建议售价(分为单位)" json:"suggested_retail_price"`
|
||
ShelfStatus int `gorm:"column:shelf_status;type:int;default:2;not null;comment:上架状态 1-上架 2-下架" json:"shelf_status"`
|
||
CalendarType string `gorm:"column:calendar_type;type:varchar(20);default:'by_day';comment:套餐周期类型 natural_month-自然月 by_day-按天" json:"calendar_type"`
|
||
DurationDays int `gorm:"column:duration_days;type:int;comment:套餐天数(calendar_type=by_day时必填)" json:"duration_days"`
|
||
DataResetCycle string `gorm:"column:data_reset_cycle;type:varchar(20);default:'monthly';comment:流量重置周期 daily-每日 monthly-每月 yearly-每年 none-不重置" json:"data_reset_cycle"`
|
||
EnableRealnameActivation bool `gorm:"column:enable_realname_activation;type:boolean;default:true;comment:是否启用实名激活 true-需实名后激活 false-立即激活" json:"enable_realname_activation"`
|
||
}
|
||
|
||
// TableName 指定表名
|
||
func (Package) TableName() string {
|
||
return "tb_package"
|
||
}
|
||
|
||
// PackageUsage 套餐使用情况模型
|
||
// 跟踪单卡套餐和设备级套餐的流量使用
|
||
type PackageUsage struct {
|
||
gorm.Model
|
||
BaseModel `gorm:"embedded"`
|
||
OrderID uint `gorm:"column:order_id;index;not null;comment:订单ID" json:"order_id"`
|
||
PackageID uint `gorm:"column:package_id;index;not null;comment:套餐ID" json:"package_id"`
|
||
UsageType string `gorm:"column:usage_type;type:varchar(20);not null;comment:使用类型 single_card-单卡套餐 device-设备级套餐" json:"usage_type"`
|
||
IotCardID uint `gorm:"column:iot_card_id;index;comment:IoT卡ID(单卡套餐时有值)" json:"iot_card_id"`
|
||
DeviceID uint `gorm:"column:device_id;index;comment:设备ID(设备级套餐时有值)" json:"device_id"`
|
||
DataLimitMB int64 `gorm:"column:data_limit_mb;type:bigint;not null;comment:流量限额(MB)" json:"data_limit_mb"`
|
||
DataUsageMB int64 `gorm:"column:data_usage_mb;type:bigint;default:0;comment:已使用流量(MB)" json:"data_usage_mb"`
|
||
RealDataUsageMB int64 `gorm:"column:real_data_usage_mb;type:bigint;default:0;comment:真流量使用(MB)" json:"real_data_usage_mb"`
|
||
VirtualDataUsageMB int64 `gorm:"column:virtual_data_usage_mb;type:bigint;default:0;comment:虚流量使用(MB)" json:"virtual_data_usage_mb"`
|
||
ActivatedAt time.Time `gorm:"column:activated_at;not null;comment:套餐生效时间" json:"activated_at"`
|
||
ExpiresAt time.Time `gorm:"column:expires_at;not null;comment:套餐过期时间" json:"expires_at"`
|
||
Status int `gorm:"column:status;type:int;default:1;not null;comment:状态 0-待生效 1-生效中 2-已用完 3-已过期 4-已失效" json:"status"`
|
||
LastPackageCheckAt *time.Time `gorm:"column:last_package_check_at;comment:最后一次套餐流量检查时间" json:"last_package_check_at"`
|
||
Priority int `gorm:"column:priority;type:int;default:1;index:idx_package_usage_priority;comment:优先级(主套餐和加油包按此字段排队,数字越小优先级越高)" json:"priority"`
|
||
MasterUsageID *uint `gorm:"column:master_usage_id;type:bigint;index:idx_package_usage_master_usage_id;comment:主套餐使用记录ID(加油包关联主套餐,主套餐此字段为NULL)" json:"master_usage_id"`
|
||
HasIndependentExpiry bool `gorm:"column:has_independent_expiry;type:boolean;default:false;comment:加油包是否有独立有效期(true-有独立到期时间 false-跟随主套餐)" json:"has_independent_expiry"`
|
||
PendingRealnameActivation bool `gorm:"column:pending_realname_activation;type:boolean;default:false;comment:是否等待实名激活(true-待实名后激活 false-已激活或不需实名)" json:"pending_realname_activation"`
|
||
DataResetCycle string `gorm:"column:data_reset_cycle;type:varchar(20);comment:流量重置周期(从Package复制,用于历史记录)" json:"data_reset_cycle"`
|
||
LastResetAt *time.Time `gorm:"column:last_reset_at;comment:最后一次流量重置时间" json:"last_reset_at"`
|
||
NextResetAt *time.Time `gorm:"column:next_reset_at;index:idx_package_usage_next_reset_at;comment:下次流量重置时间(用于定时任务查询)" json:"next_reset_at"`
|
||
}
|
||
|
||
// TableName 指定表名
|
||
func (PackageUsage) TableName() string {
|
||
return "tb_package_usage"
|
||
}
|
||
|
||
// PackageUsageDailyRecord 套餐流量日记录模型
|
||
// 记录每个套餐每天的流量使用情况,用于流量详单查询
|
||
type PackageUsageDailyRecord struct {
|
||
ID uint `gorm:"column:id;primaryKey;autoIncrement" json:"id"`
|
||
PackageUsageID uint `gorm:"column:package_usage_id;not null;uniqueIndex:idx_package_usage_daily_record_unique;index:idx_package_usage_daily_record_date;comment:套餐使用记录ID" json:"package_usage_id"`
|
||
Date time.Time `gorm:"column:date;type:date;not null;uniqueIndex:idx_package_usage_daily_record_unique;comment:日期" json:"date"`
|
||
DailyUsageMB int `gorm:"column:daily_usage_mb;type:int;default:0;comment:当日流量使用量(MB)" json:"daily_usage_mb"`
|
||
CumulativeUsageMB int64 `gorm:"column:cumulative_usage_mb;type:bigint;default:0;comment:截止当日的累计流量(MB)" json:"cumulative_usage_mb"`
|
||
CreatedAt time.Time `gorm:"column:created_at;default:CURRENT_TIMESTAMP" json:"created_at"`
|
||
UpdatedAt time.Time `gorm:"column:updated_at;default:CURRENT_TIMESTAMP" json:"updated_at"`
|
||
}
|
||
|
||
// TableName 指定表名
|
||
func (PackageUsageDailyRecord) TableName() string {
|
||
return "tb_package_usage_daily_record"
|
||
}
|
||
|
||
// OneTimeCommissionConfig 一次性佣金规则配置
|
||
type OneTimeCommissionConfig struct {
|
||
Enable bool `json:"enable"`
|
||
TriggerType string `json:"trigger_type"`
|
||
Threshold int64 `json:"threshold"`
|
||
CommissionType string `json:"commission_type"`
|
||
CommissionAmount int64 `json:"commission_amount"`
|
||
Tiers []OneTimeCommissionTier `json:"tiers,omitempty"`
|
||
ValidityType string `json:"validity_type"`
|
||
ValidityValue string `json:"validity_value"`
|
||
EnableForceRecharge bool `json:"enable_force_recharge"`
|
||
ForceCalcType string `json:"force_calc_type"`
|
||
ForceAmount int64 `json:"force_amount"`
|
||
}
|
||
|
||
// OneTimeCommissionTier 一次性佣金梯度配置
|
||
type OneTimeCommissionTier struct {
|
||
Operator string `json:"operator"` // 阈值比较运算符:>、>=、<、<=,空值默认 >=
|
||
Dimension string `json:"dimension"`
|
||
StatScope string `json:"stat_scope"`
|
||
Threshold int64 `json:"threshold"`
|
||
Amount int64 `json:"amount"`
|
||
}
|
||
|
||
const (
|
||
OneTimeCommissionTriggerFirstRecharge = "first_recharge"
|
||
OneTimeCommissionTriggerAccumulatedRecharge = "accumulated_recharge"
|
||
|
||
OneTimeCommissionValidityPermanent = "permanent"
|
||
OneTimeCommissionValidityFixedDate = "fixed_date"
|
||
OneTimeCommissionValidityRelative = "relative"
|
||
|
||
OneTimeCommissionForceCalcFixed = "fixed"
|
||
OneTimeCommissionForceCalcDynamic = "dynamic"
|
||
|
||
OneTimeCommissionStatScopeSelf = "self"
|
||
OneTimeCommissionStatScopeSelfAndSub = "self_and_sub"
|
||
|
||
TierTypeSalesCount = "sales_count"
|
||
TierTypeSalesAmount = "sales_amount"
|
||
// 阈值运算符常量
|
||
TierOperatorGT = ">"
|
||
TierOperatorGTE = ">="
|
||
TierOperatorLT = "<"
|
||
TierOperatorLTE = "<="
|
||
)
|
||
|
||
func (ps *PackageSeries) GetOneTimeCommissionConfig() (*OneTimeCommissionConfig, error) {
|
||
if ps.OneTimeCommissionConfigJSON == "" {
|
||
return nil, nil
|
||
}
|
||
var config OneTimeCommissionConfig
|
||
if err := json.Unmarshal([]byte(ps.OneTimeCommissionConfigJSON), &config); err != nil {
|
||
return nil, err
|
||
}
|
||
return &config, nil
|
||
}
|
||
|
||
func (ps *PackageSeries) SetOneTimeCommissionConfig(config *OneTimeCommissionConfig) error {
|
||
if config == nil {
|
||
ps.OneTimeCommissionConfigJSON = ""
|
||
return nil
|
||
}
|
||
data, err := json.Marshal(config)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
ps.OneTimeCommissionConfigJSON = string(data)
|
||
return nil
|
||
}
|