refactor: 一次性佣金配置从套餐级别提升到系列级别
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 6m29s
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 6m29s
主要变更: - 新增 tb_shop_series_allocation 表,存储系列级别的一次性佣金配置 - ShopPackageAllocation 移除 one_time_commission_amount 字段 - PackageSeries 新增 enable_one_time_commission 字段控制是否启用一次性佣金 - 新增 /api/admin/shop-series-allocations CRUD 接口 - 佣金计算逻辑改为从 ShopSeriesAllocation 获取一次性佣金金额 - 删除废弃的 ShopSeriesOneTimeCommissionTier 模型 - OpenAPI Tag '系列分配' 和 '单套餐分配' 合并为 '套餐分配' 迁移脚本: - 000042: 重构佣金套餐模型 - 000043: 简化佣金分配 - 000044: 一次性佣金分配重构 - 000045: PackageSeries 添加 enable_one_time_commission 字段 测试: - 新增验收测试 (shop_series_allocation, commission_calculation) - 新增流程测试 (one_time_commission_chain) - 删除过时的单元测试(已被验收测试覆盖)
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
@@ -11,26 +13,126 @@ import (
|
||||
// 通过 shop_id 区分所有权:NULL=平台库存,有值=店铺所有
|
||||
type Device struct {
|
||||
gorm.Model
|
||||
BaseModel `gorm:"embedded"`
|
||||
DeviceNo string `gorm:"column:device_no;type:varchar(100);uniqueIndex:idx_device_no,where:deleted_at IS NULL;not null;comment:设备编号(唯一标识)" json:"device_no"`
|
||||
DeviceName string `gorm:"column:device_name;type:varchar(255);comment:设备名称" json:"device_name"`
|
||||
DeviceModel string `gorm:"column:device_model;type:varchar(100);comment:设备型号" json:"device_model"`
|
||||
DeviceType string `gorm:"column:device_type;type:varchar(50);comment:设备类型" json:"device_type"`
|
||||
MaxSimSlots int `gorm:"column:max_sim_slots;type:int;default:4;comment:最大插槽数量(默认4)" json:"max_sim_slots"`
|
||||
Manufacturer string `gorm:"column:manufacturer;type:varchar(255);comment:制造商" json:"manufacturer"`
|
||||
BatchNo string `gorm:"column:batch_no;type:varchar(100);comment:批次号" json:"batch_no"`
|
||||
ShopID *uint `gorm:"column:shop_id;index;comment:店铺ID(NULL=平台库存,有值=店铺所有)" json:"shop_id,omitempty"`
|
||||
Status int `gorm:"column:status;type:int;default:1;not null;comment:状态 1-在库 2-已分销 3-已激活 4-已停用" json:"status"`
|
||||
ActivatedAt *time.Time `gorm:"column:activated_at;comment:激活时间" json:"activated_at"`
|
||||
DeviceUsername string `gorm:"column:device_username;type:varchar(100);comment:设备登录用户名" json:"device_username"`
|
||||
DevicePasswordEncrypted string `gorm:"column:device_password_encrypted;type:varchar(255);comment:设备登录密码(加密)" json:"device_password_encrypted"`
|
||||
DeviceAPIEndpoint string `gorm:"column:device_api_endpoint;type:varchar(500);comment:设备API端点" json:"device_api_endpoint"`
|
||||
SeriesID *uint `gorm:"column:series_id;index;comment:套餐系列ID(关联PackageSeries)" json:"series_id,omitempty"`
|
||||
FirstCommissionPaid bool `gorm:"column:first_commission_paid;type:boolean;default:false;comment:一次性佣金是否已发放" json:"first_commission_paid"`
|
||||
AccumulatedRecharge int64 `gorm:"column:accumulated_recharge;type:bigint;default:0;comment:累计充值金额(分)" json:"accumulated_recharge"`
|
||||
BaseModel `gorm:"embedded"`
|
||||
DeviceNo string `gorm:"column:device_no;type:varchar(100);uniqueIndex:idx_device_no,where:deleted_at IS NULL;not null;comment:设备编号(唯一标识)" json:"device_no"`
|
||||
DeviceName string `gorm:"column:device_name;type:varchar(255);comment:设备名称" json:"device_name"`
|
||||
DeviceModel string `gorm:"column:device_model;type:varchar(100);comment:设备型号" json:"device_model"`
|
||||
DeviceType string `gorm:"column:device_type;type:varchar(50);comment:设备类型" json:"device_type"`
|
||||
MaxSimSlots int `gorm:"column:max_sim_slots;type:int;default:4;comment:最大插槽数量(默认4)" json:"max_sim_slots"`
|
||||
Manufacturer string `gorm:"column:manufacturer;type:varchar(255);comment:制造商" json:"manufacturer"`
|
||||
BatchNo string `gorm:"column:batch_no;type:varchar(100);comment:批次号" json:"batch_no"`
|
||||
ShopID *uint `gorm:"column:shop_id;index;comment:店铺ID(NULL=平台库存,有值=店铺所有)" json:"shop_id,omitempty"`
|
||||
Status int `gorm:"column:status;type:int;default:1;not null;comment:状态 1-在库 2-已分销 3-已激活 4-已停用" json:"status"`
|
||||
ActivatedAt *time.Time `gorm:"column:activated_at;comment:激活时间" json:"activated_at"`
|
||||
DeviceUsername string `gorm:"column:device_username;type:varchar(100);comment:设备登录用户名" json:"device_username"`
|
||||
DevicePasswordEncrypted string `gorm:"column:device_password_encrypted;type:varchar(255);comment:设备登录密码(加密)" json:"device_password_encrypted"`
|
||||
DeviceAPIEndpoint string `gorm:"column:device_api_endpoint;type:varchar(500);comment:设备API端点" json:"device_api_endpoint"`
|
||||
SeriesID *uint `gorm:"column:series_id;index;comment:套餐系列ID(关联PackageSeries)" json:"series_id,omitempty"`
|
||||
FirstCommissionPaid bool `gorm:"column:first_commission_paid;type:boolean;default:false;comment:一次性佣金是否已发放(废弃,使用按系列追踪)" json:"first_commission_paid"`
|
||||
AccumulatedRecharge int64 `gorm:"column:accumulated_recharge;type:bigint;default:0;comment:累计充值金额(分,废弃,使用按系列追踪)" json:"accumulated_recharge"`
|
||||
AccumulatedRechargeBySeriesJSON string `gorm:"column:accumulated_recharge_by_series;type:jsonb;default:'{}';comment:按套餐系列追踪的累计充值金额" json:"-"`
|
||||
FirstRechargeTriggeredBySeriesJSON string `gorm:"column:first_recharge_triggered_by_series;type:jsonb;default:'{}';comment:按套餐系列追踪的首充触发状态" json:"-"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (Device) TableName() string {
|
||||
return "tb_device"
|
||||
}
|
||||
|
||||
func (d *Device) GetAccumulatedRechargeBySeriesMap() (map[uint]int64, error) {
|
||||
result := make(map[uint]int64)
|
||||
if d.AccumulatedRechargeBySeriesJSON == "" || d.AccumulatedRechargeBySeriesJSON == "{}" {
|
||||
return result, nil
|
||||
}
|
||||
var raw map[string]int64
|
||||
if err := json.Unmarshal([]byte(d.AccumulatedRechargeBySeriesJSON), &raw); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for k, v := range raw {
|
||||
id, err := strconv.ParseUint(k, 10, 64)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
result[uint(id)] = v
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (d *Device) SetAccumulatedRechargeBySeriesMap(m map[uint]int64) error {
|
||||
raw := make(map[string]int64)
|
||||
for k, v := range m {
|
||||
raw[strconv.FormatUint(uint64(k), 10)] = v
|
||||
}
|
||||
data, err := json.Marshal(raw)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
d.AccumulatedRechargeBySeriesJSON = string(data)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Device) GetAccumulatedRechargeBySeries(seriesID uint) int64 {
|
||||
m, err := d.GetAccumulatedRechargeBySeriesMap()
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return m[seriesID]
|
||||
}
|
||||
|
||||
func (d *Device) AddAccumulatedRechargeBySeries(seriesID uint, amount int64) error {
|
||||
m, err := d.GetAccumulatedRechargeBySeriesMap()
|
||||
if err != nil {
|
||||
m = make(map[uint]int64)
|
||||
}
|
||||
m[seriesID] += amount
|
||||
return d.SetAccumulatedRechargeBySeriesMap(m)
|
||||
}
|
||||
|
||||
func (d *Device) GetFirstRechargeTriggeredBySeriesMap() (map[uint]bool, error) {
|
||||
result := make(map[uint]bool)
|
||||
if d.FirstRechargeTriggeredBySeriesJSON == "" || d.FirstRechargeTriggeredBySeriesJSON == "{}" {
|
||||
return result, nil
|
||||
}
|
||||
var raw map[string]bool
|
||||
if err := json.Unmarshal([]byte(d.FirstRechargeTriggeredBySeriesJSON), &raw); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for k, v := range raw {
|
||||
id, err := strconv.ParseUint(k, 10, 64)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
result[uint(id)] = v
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (d *Device) SetFirstRechargeTriggeredBySeriesMap(m map[uint]bool) error {
|
||||
raw := make(map[string]bool)
|
||||
for k, v := range m {
|
||||
raw[strconv.FormatUint(uint64(k), 10)] = v
|
||||
}
|
||||
data, err := json.Marshal(raw)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
d.FirstRechargeTriggeredBySeriesJSON = string(data)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Device) IsFirstRechargeTriggeredBySeries(seriesID uint) bool {
|
||||
m, err := d.GetFirstRechargeTriggeredBySeriesMap()
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return m[seriesID]
|
||||
}
|
||||
|
||||
func (d *Device) SetFirstRechargeTriggeredBySeries(seriesID uint, triggered bool) error {
|
||||
m, err := d.GetFirstRechargeTriggeredBySeriesMap()
|
||||
if err != nil {
|
||||
m = make(map[uint]bool)
|
||||
}
|
||||
m[seriesID] = triggered
|
||||
return d.SetFirstRechargeTriggeredBySeriesMap(m)
|
||||
}
|
||||
|
||||
@@ -2,18 +2,16 @@ package dto
|
||||
|
||||
// CreatePackageRequest 创建套餐请求
|
||||
type CreatePackageRequest struct {
|
||||
PackageCode string `json:"package_code" validate:"required,min=1,max=100" required:"true" minLength:"1" maxLength:"100" description:"套餐编码"`
|
||||
PackageName string `json:"package_name" validate:"required,min=1,max=255" required:"true" minLength:"1" maxLength:"255" description:"套餐名称"`
|
||||
SeriesID *uint `json:"series_id" validate:"omitempty" description:"套餐系列ID"`
|
||||
PackageType string `json:"package_type" validate:"required,oneof=formal addon" required:"true" description:"套餐类型 (formal:正式套餐, addon:附加套餐)"`
|
||||
DurationMonths int `json:"duration_months" validate:"required,min=1,max=120" required:"true" minimum:"1" maximum:"120" description:"套餐时长(月数)"`
|
||||
DataType *string `json:"data_type" validate:"omitempty,oneof=real virtual" description:"流量类型 (real:真流量, virtual:虚流量)"`
|
||||
RealDataMB *int64 `json:"real_data_mb" validate:"omitempty,min=0" minimum:"0" description:"真流量额度(MB)"`
|
||||
VirtualDataMB *int64 `json:"virtual_data_mb" validate:"omitempty,min=0" minimum:"0" description:"虚流量额度(MB)"`
|
||||
DataAmountMB *int64 `json:"data_amount_mb" validate:"omitempty,min=0" minimum:"0" description:"总流量额度(MB)"`
|
||||
Price int64 `json:"price" validate:"required,min=0" required:"true" minimum:"0" description:"套餐价格(分)"`
|
||||
SuggestedCostPrice *int64 `json:"suggested_cost_price" validate:"omitempty,min=0" minimum:"0" description:"建议成本价(分)"`
|
||||
SuggestedRetailPrice *int64 `json:"suggested_retail_price" validate:"omitempty,min=0" minimum:"0" description:"建议售价(分)"`
|
||||
PackageCode string `json:"package_code" validate:"required,min=1,max=100" required:"true" minLength:"1" maxLength:"100" description:"套餐编码"`
|
||||
PackageName string `json:"package_name" validate:"required,min=1,max=255" required:"true" minLength:"1" maxLength:"255" description:"套餐名称"`
|
||||
SeriesID *uint `json:"series_id" validate:"omitempty" description:"套餐系列ID"`
|
||||
PackageType string `json:"package_type" validate:"required,oneof=formal addon" required:"true" description:"套餐类型 (formal:正式套餐, addon:附加套餐)"`
|
||||
DurationMonths int `json:"duration_months" validate:"required,min=1,max=120" required:"true" minimum:"1" maximum:"120" description:"套餐时长(月数)"`
|
||||
RealDataMB *int64 `json:"real_data_mb" validate:"omitempty,min=0" minimum:"0" description:"真流量额度(MB)"`
|
||||
VirtualDataMB *int64 `json:"virtual_data_mb" validate:"omitempty,min=0" minimum:"0" description:"虚流量额度(MB)"`
|
||||
EnableVirtualData bool `json:"enable_virtual_data" description:"是否启用虚流量"`
|
||||
SuggestedRetailPrice *int64 `json:"suggested_retail_price" validate:"omitempty,min=0" minimum:"0" description:"建议售价(分)"`
|
||||
CostPrice int64 `json:"cost_price" validate:"required,min=0" required:"true" minimum:"0" description:"成本价(分)"`
|
||||
}
|
||||
|
||||
// UpdatePackageRequest 更新套餐请求
|
||||
@@ -22,13 +20,11 @@ type UpdatePackageRequest struct {
|
||||
SeriesID *uint `json:"series_id" validate:"omitempty" description:"套餐系列ID"`
|
||||
PackageType *string `json:"package_type" validate:"omitempty,oneof=formal addon" description:"套餐类型 (formal:正式套餐, addon:附加套餐)"`
|
||||
DurationMonths *int `json:"duration_months" validate:"omitempty,min=1,max=120" minimum:"1" maximum:"120" description:"套餐时长(月数)"`
|
||||
DataType *string `json:"data_type" validate:"omitempty,oneof=real virtual" description:"流量类型 (real:真流量, virtual:虚流量)"`
|
||||
RealDataMB *int64 `json:"real_data_mb" validate:"omitempty,min=0" minimum:"0" description:"真流量额度(MB)"`
|
||||
VirtualDataMB *int64 `json:"virtual_data_mb" validate:"omitempty,min=0" minimum:"0" description:"虚流量额度(MB)"`
|
||||
DataAmountMB *int64 `json:"data_amount_mb" validate:"omitempty,min=0" minimum:"0" description:"总流量额度(MB)"`
|
||||
Price *int64 `json:"price" validate:"omitempty,min=0" minimum:"0" description:"套餐价格(分)"`
|
||||
SuggestedCostPrice *int64 `json:"suggested_cost_price" validate:"omitempty,min=0" minimum:"0" description:"建议成本价(分)"`
|
||||
EnableVirtualData *bool `json:"enable_virtual_data" description:"是否启用虚流量"`
|
||||
SuggestedRetailPrice *int64 `json:"suggested_retail_price" validate:"omitempty,min=0" minimum:"0" description:"建议售价(分)"`
|
||||
CostPrice *int64 `json:"cost_price" validate:"omitempty,min=0" minimum:"0" description:"成本价(分)"`
|
||||
}
|
||||
|
||||
// PackageListRequest 套餐列表请求
|
||||
@@ -61,28 +57,26 @@ type CommissionTierInfo struct {
|
||||
|
||||
// PackageResponse 套餐响应
|
||||
type PackageResponse struct {
|
||||
ID uint `json:"id" description:"套餐ID"`
|
||||
PackageCode string `json:"package_code" description:"套餐编码"`
|
||||
PackageName string `json:"package_name" description:"套餐名称"`
|
||||
SeriesID *uint `json:"series_id" description:"套餐系列ID"`
|
||||
SeriesName *string `json:"series_name" description:"套餐系列名称"`
|
||||
PackageType string `json:"package_type" description:"套餐类型 (formal:正式套餐, addon:附加套餐)"`
|
||||
DurationMonths int `json:"duration_months" description:"套餐时长(月数)"`
|
||||
DataType string `json:"data_type" description:"流量类型 (real:真流量, virtual:虚流量)"`
|
||||
RealDataMB int64 `json:"real_data_mb" description:"真流量额度(MB)"`
|
||||
VirtualDataMB int64 `json:"virtual_data_mb" description:"虚流量额度(MB)"`
|
||||
DataAmountMB int64 `json:"data_amount_mb" description:"总流量额度(MB)"`
|
||||
Price int64 `json:"price" description:"套餐价格(分)"`
|
||||
SuggestedCostPrice int64 `json:"suggested_cost_price" description:"建议成本价(分)"`
|
||||
SuggestedRetailPrice int64 `json:"suggested_retail_price" description:"建议售价(分)"`
|
||||
Status int `json:"status" description:"状态 (1:启用, 2:禁用)"`
|
||||
ShelfStatus int `json:"shelf_status" description:"上架状态 (1:上架, 2:下架)"`
|
||||
CreatedAt string `json:"created_at" description:"创建时间"`
|
||||
UpdatedAt string `json:"updated_at" description:"更新时间"`
|
||||
CostPrice *int64 `json:"cost_price,omitempty" description:"成本价(分,仅代理用户可见)"`
|
||||
ProfitMargin *int64 `json:"profit_margin,omitempty" description:"利润空间(分,仅代理用户可见)"`
|
||||
CurrentCommissionRate string `json:"current_commission_rate,omitempty" description:"当前返佣比例(仅代理用户可见)"`
|
||||
TierInfo *CommissionTierInfo `json:"tier_info,omitempty" description:"梯度返佣信息(仅代理用户可见)"`
|
||||
ID uint `json:"id" description:"套餐ID"`
|
||||
PackageCode string `json:"package_code" description:"套餐编码"`
|
||||
PackageName string `json:"package_name" description:"套餐名称"`
|
||||
SeriesID *uint `json:"series_id" description:"套餐系列ID"`
|
||||
SeriesName *string `json:"series_name" description:"套餐系列名称"`
|
||||
PackageType string `json:"package_type" description:"套餐类型 (formal:正式套餐, addon:附加套餐)"`
|
||||
DurationMonths int `json:"duration_months" description:"套餐时长(月数)"`
|
||||
RealDataMB int64 `json:"real_data_mb" description:"真流量额度(MB)"`
|
||||
VirtualDataMB int64 `json:"virtual_data_mb" description:"虚流量额度(MB)"`
|
||||
EnableVirtualData bool `json:"enable_virtual_data" description:"是否启用虚流量"`
|
||||
SuggestedRetailPrice int64 `json:"suggested_retail_price" description:"建议售价(分)"`
|
||||
CostPrice int64 `json:"cost_price" description:"成本价(分)"`
|
||||
OneTimeCommissionAmount *int64 `json:"one_time_commission_amount,omitempty" description:"一次性佣金金额(分,代理视角)"`
|
||||
Status int `json:"status" description:"状态 (1:启用, 2:禁用)"`
|
||||
ShelfStatus int `json:"shelf_status" description:"上架状态 (1:上架, 2:下架)"`
|
||||
CreatedAt string `json:"created_at" description:"创建时间"`
|
||||
UpdatedAt string `json:"updated_at" description:"更新时间"`
|
||||
ProfitMargin *int64 `json:"profit_margin,omitempty" description:"利润空间(分,仅代理用户可见)"`
|
||||
CurrentCommissionRate string `json:"current_commission_rate,omitempty" description:"当前返佣比例(仅代理用户可见)"`
|
||||
TierInfo *CommissionTierInfo `json:"tier_info,omitempty" description:"梯度返佣信息(仅代理用户可见)"`
|
||||
}
|
||||
|
||||
// UpdatePackageParams 更新套餐聚合参数
|
||||
|
||||
@@ -1,24 +1,50 @@
|
||||
package dto
|
||||
|
||||
// OneTimeCommissionTierDTO 一次性佣金梯度配置
|
||||
type OneTimeCommissionTierDTO struct {
|
||||
Dimension string `json:"dimension" validate:"required,oneof=sales_count sales_amount" required:"true" description:"统计维度 (sales_count:销量, sales_amount:销售额)"`
|
||||
StatScope string `json:"stat_scope" validate:"omitempty,oneof=self self_and_sub" description:"统计范围 (self:仅自己, self_and_sub:自己+下级)"`
|
||||
Threshold int64 `json:"threshold" validate:"required,min=0" required:"true" minimum:"0" description:"达标阈值"`
|
||||
Amount int64 `json:"amount" validate:"required,min=0" required:"true" minimum:"0" description:"佣金金额(分)"`
|
||||
}
|
||||
|
||||
// SeriesOneTimeCommissionConfigDTO 一次性佣金规则配置
|
||||
type SeriesOneTimeCommissionConfigDTO struct {
|
||||
Enable bool `json:"enable" description:"是否启用一次性佣金"`
|
||||
TriggerType string `json:"trigger_type" validate:"omitempty,oneof=first_recharge accumulated_recharge" description:"触发类型 (first_recharge:首充, accumulated_recharge:累计充值)"`
|
||||
Threshold int64 `json:"threshold" validate:"omitempty,min=0" minimum:"0" description:"触发阈值(分)"`
|
||||
CommissionType string `json:"commission_type" validate:"omitempty,oneof=fixed tiered" description:"佣金类型 (fixed:固定, tiered:梯度)"`
|
||||
CommissionAmount int64 `json:"commission_amount" validate:"omitempty,min=0" minimum:"0" description:"固定佣金金额(分),commission_type=fixed时使用"`
|
||||
Tiers []OneTimeCommissionTierDTO `json:"tiers" validate:"omitempty,dive" description:"梯度配置列表,commission_type=tiered时使用"`
|
||||
ValidityType string `json:"validity_type" validate:"omitempty,oneof=permanent fixed_date relative" description:"时效类型 (permanent:永久, fixed_date:固定日期, relative:相对时长)"`
|
||||
ValidityValue string `json:"validity_value" validate:"omitempty" description:"时效值(日期或月数)"`
|
||||
EnableForceRecharge bool `json:"enable_force_recharge" description:"是否启用强充"`
|
||||
ForceCalcType string `json:"force_calc_type" validate:"omitempty,oneof=fixed dynamic" description:"强充计算类型 (fixed:固定, dynamic:动态)"`
|
||||
ForceAmount int64 `json:"force_amount" validate:"omitempty,min=0" minimum:"0" description:"强充金额(分)"`
|
||||
}
|
||||
|
||||
// CreatePackageSeriesRequest 创建套餐系列请求
|
||||
type CreatePackageSeriesRequest struct {
|
||||
SeriesCode string `json:"series_code" validate:"required,min=1,max=100" required:"true" minLength:"1" maxLength:"100" description:"系列编码"`
|
||||
SeriesName string `json:"series_name" validate:"required,min=1,max=255" required:"true" minLength:"1" maxLength:"255" description:"系列名称"`
|
||||
Description string `json:"description" validate:"omitempty,max=500" maxLength:"500" description:"描述"`
|
||||
SeriesCode string `json:"series_code" validate:"required,min=1,max=100" required:"true" minLength:"1" maxLength:"100" description:"系列编码"`
|
||||
SeriesName string `json:"series_name" validate:"required,min=1,max=255" required:"true" minLength:"1" maxLength:"255" description:"系列名称"`
|
||||
Description string `json:"description" validate:"omitempty,max=500" maxLength:"500" description:"描述"`
|
||||
OneTimeCommissionConfig *SeriesOneTimeCommissionConfigDTO `json:"one_time_commission_config" validate:"omitempty" description:"一次性佣金规则配置"`
|
||||
}
|
||||
|
||||
// UpdatePackageSeriesRequest 更新套餐系列请求
|
||||
type UpdatePackageSeriesRequest struct {
|
||||
SeriesName *string `json:"series_name" validate:"omitempty,min=1,max=255" minLength:"1" maxLength:"255" description:"系列名称"`
|
||||
Description *string `json:"description" validate:"omitempty,max=500" maxLength:"500" description:"描述"`
|
||||
SeriesName *string `json:"series_name" validate:"omitempty,min=1,max=255" minLength:"1" maxLength:"255" description:"系列名称"`
|
||||
Description *string `json:"description" validate:"omitempty,max=500" maxLength:"500" description:"描述"`
|
||||
OneTimeCommissionConfig *SeriesOneTimeCommissionConfigDTO `json:"one_time_commission_config" validate:"omitempty" description:"一次性佣金规则配置"`
|
||||
}
|
||||
|
||||
// PackageSeriesListRequest 套餐系列列表请求
|
||||
type PackageSeriesListRequest struct {
|
||||
Page int `json:"page" query:"page" validate:"omitempty,min=1" minimum:"1" description:"页码"`
|
||||
PageSize int `json:"page_size" query:"page_size" validate:"omitempty,min=1,max=100" minimum:"1" maximum:"100" description:"每页数量"`
|
||||
SeriesName *string `json:"series_name" query:"series_name" validate:"omitempty,max=255" maxLength:"255" description:"系列名称(模糊搜索)"`
|
||||
Status *int `json:"status" query:"status" validate:"omitempty,oneof=1 2" description:"状态 (1:启用, 2:禁用)"`
|
||||
Page int `json:"page" query:"page" validate:"omitempty,min=1" minimum:"1" description:"页码"`
|
||||
PageSize int `json:"page_size" query:"page_size" validate:"omitempty,min=1,max=100" minimum:"1" maximum:"100" description:"每页数量"`
|
||||
SeriesName *string `json:"series_name" query:"series_name" validate:"omitempty,max=255" maxLength:"255" description:"系列名称(模糊搜索)"`
|
||||
Status *int `json:"status" query:"status" validate:"omitempty,oneof=1 2" description:"状态 (1:启用, 2:禁用)"`
|
||||
EnableOneTimeCommission *bool `json:"enable_one_time_commission" query:"enable_one_time_commission" description:"是否启用一次性佣金"`
|
||||
}
|
||||
|
||||
// UpdatePackageSeriesStatusRequest 更新套餐系列状态请求
|
||||
@@ -28,13 +54,15 @@ type UpdatePackageSeriesStatusRequest struct {
|
||||
|
||||
// PackageSeriesResponse 套餐系列响应
|
||||
type PackageSeriesResponse struct {
|
||||
ID uint `json:"id" description:"系列ID"`
|
||||
SeriesCode string `json:"series_code" description:"系列编码"`
|
||||
SeriesName string `json:"series_name" description:"系列名称"`
|
||||
Description string `json:"description" description:"描述"`
|
||||
Status int `json:"status" description:"状态 (1:启用, 2:禁用)"`
|
||||
CreatedAt string `json:"created_at" description:"创建时间"`
|
||||
UpdatedAt string `json:"updated_at" description:"更新时间"`
|
||||
ID uint `json:"id" description:"系列ID"`
|
||||
SeriesCode string `json:"series_code" description:"系列编码"`
|
||||
SeriesName string `json:"series_name" description:"系列名称"`
|
||||
Description string `json:"description" description:"描述"`
|
||||
EnableOneTimeCommission bool `json:"enable_one_time_commission" description:"是否启用一次性佣金"`
|
||||
OneTimeCommissionConfig *SeriesOneTimeCommissionConfigDTO `json:"one_time_commission_config,omitempty" description:"一次性佣金规则配置"`
|
||||
Status int `json:"status" description:"状态 (1:启用, 2:禁用)"`
|
||||
CreatedAt string `json:"created_at" description:"创建时间"`
|
||||
UpdatedAt string `json:"updated_at" description:"更新时间"`
|
||||
}
|
||||
|
||||
// UpdatePackageSeriesParams 更新套餐系列聚合参数
|
||||
|
||||
@@ -1,24 +1,23 @@
|
||||
package dto
|
||||
|
||||
// CreateShopPackageAllocationRequest 创建单套餐分配请求
|
||||
type CreateShopPackageAllocationRequest struct {
|
||||
ShopID uint `json:"shop_id" validate:"required" required:"true" description:"被分配的店铺ID"`
|
||||
PackageID uint `json:"package_id" validate:"required" required:"true" description:"套餐ID"`
|
||||
CostPrice int64 `json:"cost_price" validate:"required,min=0" required:"true" minimum:"0" description:"覆盖的成本价(分)"`
|
||||
CostPrice int64 `json:"cost_price" validate:"required,min=0" required:"true" minimum:"0" description:"该代理的成本价(分)"`
|
||||
}
|
||||
|
||||
// UpdateShopPackageAllocationRequest 更新单套餐分配请求
|
||||
type UpdateShopPackageAllocationRequest struct {
|
||||
CostPrice *int64 `json:"cost_price" validate:"omitempty,min=0" minimum:"0" description:"覆盖的成本价(分)"`
|
||||
CostPrice *int64 `json:"cost_price" validate:"omitempty,min=0" minimum:"0" description:"该代理的成本价(分)"`
|
||||
}
|
||||
|
||||
// ShopPackageAllocationListRequest 单套餐分配列表请求
|
||||
type ShopPackageAllocationListRequest struct {
|
||||
Page int `json:"page" query:"page" validate:"omitempty,min=1" minimum:"1" description:"页码"`
|
||||
PageSize int `json:"page_size" query:"page_size" validate:"omitempty,min=1,max=100" minimum:"1" maximum:"100" description:"每页数量"`
|
||||
ShopID *uint `json:"shop_id" query:"shop_id" validate:"omitempty" description:"被分配的店铺ID"`
|
||||
PackageID *uint `json:"package_id" query:"package_id" validate:"omitempty" description:"套餐ID"`
|
||||
Status *int `json:"status" query:"status" validate:"omitempty,oneof=1 2" description:"状态 (1:启用, 2:禁用)"`
|
||||
Page int `json:"page" query:"page" validate:"omitempty,min=1" minimum:"1" description:"页码"`
|
||||
PageSize int `json:"page_size" query:"page_size" validate:"omitempty,min=1,max=100" minimum:"1" maximum:"100" description:"每页数量"`
|
||||
ShopID *uint `json:"shop_id" query:"shop_id" validate:"omitempty" description:"被分配的店铺ID"`
|
||||
PackageID *uint `json:"package_id" query:"package_id" validate:"omitempty" description:"套餐ID"`
|
||||
SeriesAllocationID *uint `json:"series_allocation_id" query:"series_allocation_id" validate:"omitempty" description:"系列分配ID"`
|
||||
AllocatorShopID *uint `json:"allocator_shop_id" query:"allocator_shop_id" validate:"omitempty" description:"分配者店铺ID"`
|
||||
Status *int `json:"status" query:"status" validate:"omitempty,oneof=1 2" description:"状态 (1:启用, 2:禁用)"`
|
||||
}
|
||||
|
||||
// UpdateShopPackageAllocationStatusRequest 更新单套餐分配状态请求
|
||||
@@ -26,23 +25,25 @@ type UpdateShopPackageAllocationStatusRequest struct {
|
||||
Status int `json:"status" validate:"required,oneof=1 2" required:"true" description:"状态 (1:启用, 2:禁用)"`
|
||||
}
|
||||
|
||||
// ShopPackageAllocationResponse 单套餐分配响应
|
||||
type ShopPackageAllocationResponse struct {
|
||||
ID uint `json:"id" description:"分配ID"`
|
||||
ShopID uint `json:"shop_id" description:"被分配的店铺ID"`
|
||||
ShopName string `json:"shop_name" description:"被分配的店铺名称"`
|
||||
PackageID uint `json:"package_id" description:"套餐ID"`
|
||||
PackageName string `json:"package_name" description:"套餐名称"`
|
||||
PackageCode string `json:"package_code" description:"套餐编码"`
|
||||
AllocationID uint `json:"allocation_id" description:"关联的系列分配ID"`
|
||||
CostPrice int64 `json:"cost_price" description:"覆盖的成本价(分)"`
|
||||
CalculatedCostPrice int64 `json:"calculated_cost_price" description:"原计算成本价(分),供参考"`
|
||||
Status int `json:"status" description:"状态 (1:启用, 2:禁用)"`
|
||||
CreatedAt string `json:"created_at" description:"创建时间"`
|
||||
UpdatedAt string `json:"updated_at" description:"更新时间"`
|
||||
ID uint `json:"id" description:"分配ID"`
|
||||
ShopID uint `json:"shop_id" description:"被分配的店铺ID"`
|
||||
ShopName string `json:"shop_name" description:"被分配的店铺名称"`
|
||||
PackageID uint `json:"package_id" description:"套餐ID"`
|
||||
PackageName string `json:"package_name" description:"套餐名称"`
|
||||
PackageCode string `json:"package_code" description:"套餐编码"`
|
||||
SeriesID uint `json:"series_id" description:"套餐系列ID"`
|
||||
SeriesName string `json:"series_name" description:"套餐系列名称"`
|
||||
SeriesAllocationID *uint `json:"series_allocation_id" description:"关联的系列分配ID"`
|
||||
AllocatorShopID uint `json:"allocator_shop_id" description:"分配者店铺ID,0表示平台分配"`
|
||||
AllocatorShopName string `json:"allocator_shop_name" description:"分配者店铺名称"`
|
||||
CostPrice int64 `json:"cost_price" description:"该代理的成本价(分)"`
|
||||
Status int `json:"status" description:"状态 (1:启用, 2:禁用)"`
|
||||
CreatedAt string `json:"created_at" description:"创建时间"`
|
||||
UpdatedAt string `json:"updated_at" description:"更新时间"`
|
||||
}
|
||||
|
||||
// ShopPackageAllocationPageResult 单套餐分配分页结果
|
||||
// ShopPackageAllocationPageResult 套餐分配分页结果
|
||||
type ShopPackageAllocationPageResult struct {
|
||||
List []*ShopPackageAllocationResponse `json:"list" description:"分配列表"`
|
||||
Total int64 `json:"total" description:"总数"`
|
||||
@@ -51,13 +52,13 @@ type ShopPackageAllocationPageResult struct {
|
||||
TotalPages int `json:"total_pages" description:"总页数"`
|
||||
}
|
||||
|
||||
// UpdateShopPackageAllocationParams 更新单套餐分配聚合参数
|
||||
// UpdateShopPackageAllocationParams 更新套餐分配聚合参数
|
||||
type UpdateShopPackageAllocationParams struct {
|
||||
IDReq
|
||||
UpdateShopPackageAllocationRequest
|
||||
}
|
||||
|
||||
// UpdateShopPackageAllocationStatusParams 更新单套餐分配状态聚合参数
|
||||
// UpdateShopPackageAllocationStatusParams 更新套餐分配状态聚合参数
|
||||
type UpdateShopPackageAllocationStatusParams struct {
|
||||
IDReq
|
||||
UpdateShopPackageAllocationStatusRequest
|
||||
|
||||
@@ -8,15 +8,14 @@ type PriceAdjustment struct {
|
||||
|
||||
// BatchAllocatePackagesRequest 批量分配套餐请求
|
||||
type BatchAllocatePackagesRequest struct {
|
||||
ShopID uint `json:"shop_id" validate:"required" required:"true" description:"被分配的店铺ID"`
|
||||
SeriesID uint `json:"series_id" validate:"required" required:"true" description:"套餐系列ID"`
|
||||
PriceAdjustment *PriceAdjustment `json:"price_adjustment" validate:"omitempty" description:"可选加价配置"`
|
||||
BaseCommission BaseCommissionConfig `json:"base_commission" validate:"required" required:"true" description:"基础返佣配置"`
|
||||
ShopID uint `json:"shop_id" validate:"required" required:"true" description:"被分配的店铺ID"`
|
||||
SeriesID uint `json:"series_id" validate:"required" required:"true" description:"套餐系列ID"`
|
||||
PriceAdjustment *PriceAdjustment `json:"price_adjustment" validate:"omitempty" description:"可选加价配置"`
|
||||
OneTimeCommissionAmount *int64 `json:"one_time_commission_amount" validate:"omitempty,min=0" minimum:"0" description:"该代理能拿到的一次性佣金(分)"`
|
||||
}
|
||||
|
||||
// BatchAllocatePackagesResponse 批量分配套餐响应
|
||||
type BatchAllocatePackagesResponse struct {
|
||||
AllocationID uint `json:"allocation_id" description:"系列分配ID"`
|
||||
TotalPackages int `json:"total_packages" description:"总套餐数"`
|
||||
AllocatedCount int `json:"allocated_count" description:"成功分配数量"`
|
||||
SkippedCount int `json:"skipped_count" description:"跳过数量(已存在)"`
|
||||
|
||||
@@ -1,86 +1,58 @@
|
||||
package dto
|
||||
|
||||
// BaseCommissionConfig 基础返佣配置
|
||||
type BaseCommissionConfig struct {
|
||||
Mode string `json:"mode" validate:"required,oneof=fixed percent" required:"true" description:"返佣模式 (fixed:固定金额, percent:百分比)"`
|
||||
Value int64 `json:"value" validate:"required,min=0" required:"true" minimum:"0" description:"返佣值(分或千分比,如200=20%)"`
|
||||
}
|
||||
|
||||
// OneTimeCommissionConfig 一次性佣金配置
|
||||
type OneTimeCommissionConfig struct {
|
||||
Type string `json:"type" validate:"required,oneof=fixed tiered" required:"true" description:"一次性佣金类型 (fixed:固定, tiered:梯度)"`
|
||||
Trigger string `json:"trigger" validate:"required,oneof=single_recharge accumulated_recharge" required:"true" description:"触发条件 (single_recharge:单次充值, accumulated_recharge:累计充值)"`
|
||||
Threshold int64 `json:"threshold" validate:"required,min=1" required:"true" minimum:"1" description:"最低阈值(分)"`
|
||||
Mode string `json:"mode" validate:"omitempty,oneof=fixed percent" description:"返佣模式 (fixed:固定金额, percent:百分比) - 固定类型时必填"`
|
||||
Value int64 `json:"value" validate:"omitempty,min=1" minimum:"1" description:"佣金金额(分)或比例(千分比)- 固定类型时必填"`
|
||||
Tiers []OneTimeCommissionTierEntry `json:"tiers" validate:"omitempty,dive" description:"梯度档位列表 - 梯度类型时必填"`
|
||||
}
|
||||
|
||||
// OneTimeCommissionTierEntry 一次性佣金梯度档位条目
|
||||
type OneTimeCommissionTierEntry struct {
|
||||
TierType string `json:"tier_type" validate:"required,oneof=sales_count sales_amount" required:"true" description:"梯度类型 (sales_count:销量, sales_amount:销售额)"`
|
||||
Threshold int64 `json:"threshold" validate:"required,min=1" required:"true" minimum:"1" description:"梯度阈值(销量或销售额分)"`
|
||||
Mode string `json:"mode" validate:"required,oneof=fixed percent" required:"true" description:"返佣模式 (fixed:固定金额, percent:百分比)"`
|
||||
Value int64 `json:"value" validate:"required,min=1" required:"true" minimum:"1" description:"返佣值(分或千分比)"`
|
||||
}
|
||||
|
||||
// CreateShopSeriesAllocationRequest 创建套餐系列分配请求
|
||||
type CreateShopSeriesAllocationRequest struct {
|
||||
ShopID uint `json:"shop_id" validate:"required" required:"true" description:"被分配的店铺ID"`
|
||||
SeriesID uint `json:"series_id" validate:"required" required:"true" description:"套餐系列ID"`
|
||||
BaseCommission BaseCommissionConfig `json:"base_commission" validate:"required" required:"true" description:"基础返佣配置"`
|
||||
EnableOneTimeCommission bool `json:"enable_one_time_commission" description:"是否启用一次性佣金"`
|
||||
OneTimeCommissionConfig *OneTimeCommissionConfig `json:"one_time_commission_config" validate:"omitempty" description:"一次性佣金配置(启用一次性佣金时必填)"`
|
||||
EnableForceRecharge *bool `json:"enable_force_recharge,omitempty" description:"是否启用强充(累计充值强充)"`
|
||||
ForceRechargeAmount *int64 `json:"force_recharge_amount,omitempty" description:"强充金额(分,0表示使用阈值金额)"`
|
||||
ForceRechargeTriggerType *int `json:"force_recharge_trigger_type,omitempty" description:"强充触发类型(1:单次充值, 2:累计充值)"`
|
||||
ShopID uint `json:"shop_id" validate:"required" required:"true" description:"被分配的店铺ID"`
|
||||
SeriesID uint `json:"series_id" validate:"required" required:"true" description:"套餐系列ID"`
|
||||
OneTimeCommissionAmount int64 `json:"one_time_commission_amount" validate:"required,min=0" required:"true" minimum:"0" description:"该代理能拿的一次性佣金金额上限(分)"`
|
||||
EnableOneTimeCommission *bool `json:"enable_one_time_commission" description:"是否启用一次性佣金"`
|
||||
OneTimeCommissionTrigger string `json:"one_time_commission_trigger" validate:"omitempty,oneof=first_recharge accumulated_recharge" description:"一次性佣金触发类型 (first_recharge:首次充值, accumulated_recharge:累计充值)"`
|
||||
OneTimeCommissionThreshold *int64 `json:"one_time_commission_threshold" validate:"omitempty,min=0" minimum:"0" description:"一次性佣金触发阈值(分)"`
|
||||
EnableForceRecharge *bool `json:"enable_force_recharge" description:"是否启用强制充值"`
|
||||
ForceRechargeAmount *int64 `json:"force_recharge_amount" validate:"omitempty,min=0" minimum:"0" description:"强制充值金额(分)"`
|
||||
ForceRechargeTriggerType *int `json:"force_recharge_trigger_type" validate:"omitempty,oneof=1 2" description:"强充触发类型 (1:单次充值, 2:累计充值)"`
|
||||
}
|
||||
|
||||
// UpdateShopSeriesAllocationRequest 更新套餐系列分配请求
|
||||
type UpdateShopSeriesAllocationRequest struct {
|
||||
BaseCommission *BaseCommissionConfig `json:"base_commission" validate:"omitempty" description:"基础返佣配置"`
|
||||
EnableOneTimeCommission *bool `json:"enable_one_time_commission" description:"是否启用一次性佣金"`
|
||||
OneTimeCommissionConfig *OneTimeCommissionConfig `json:"one_time_commission_config" validate:"omitempty" description:"一次性佣金配置"`
|
||||
EnableForceRecharge *bool `json:"enable_force_recharge,omitempty" description:"是否启用强充(累计充值强充)"`
|
||||
ForceRechargeAmount *int64 `json:"force_recharge_amount,omitempty" description:"强充金额(分,0表示使用阈值金额)"`
|
||||
ForceRechargeTriggerType *int `json:"force_recharge_trigger_type,omitempty" description:"强充触发类型(1:单次充值, 2:累计充值)"`
|
||||
OneTimeCommissionAmount *int64 `json:"one_time_commission_amount" validate:"omitempty,min=0" minimum:"0" description:"该代理能拿的一次性佣金金额上限(分)"`
|
||||
EnableOneTimeCommission *bool `json:"enable_one_time_commission" description:"是否启用一次性佣金"`
|
||||
OneTimeCommissionTrigger *string `json:"one_time_commission_trigger" validate:"omitempty,oneof=first_recharge accumulated_recharge" description:"一次性佣金触发类型"`
|
||||
OneTimeCommissionThreshold *int64 `json:"one_time_commission_threshold" validate:"omitempty,min=0" minimum:"0" description:"一次性佣金触发阈值(分)"`
|
||||
EnableForceRecharge *bool `json:"enable_force_recharge" description:"是否启用强制充值"`
|
||||
ForceRechargeAmount *int64 `json:"force_recharge_amount" validate:"omitempty,min=0" minimum:"0" description:"强制充值金额(分)"`
|
||||
ForceRechargeTriggerType *int `json:"force_recharge_trigger_type" validate:"omitempty,oneof=1 2" description:"强充触发类型 (1:单次充值, 2:累计充值)"`
|
||||
Status *int `json:"status" validate:"omitempty,oneof=1 2" description:"状态 (1:启用, 2:禁用)"`
|
||||
}
|
||||
|
||||
// ShopSeriesAllocationListRequest 套餐系列分配列表请求
|
||||
type ShopSeriesAllocationListRequest struct {
|
||||
Page int `json:"page" query:"page" validate:"omitempty,min=1" minimum:"1" description:"页码"`
|
||||
PageSize int `json:"page_size" query:"page_size" validate:"omitempty,min=1,max=100" minimum:"1" maximum:"100" description:"每页数量"`
|
||||
ShopID *uint `json:"shop_id" query:"shop_id" validate:"omitempty" description:"被分配的店铺ID"`
|
||||
SeriesID *uint `json:"series_id" query:"series_id" validate:"omitempty" description:"套餐系列ID"`
|
||||
Status *int `json:"status" query:"status" validate:"omitempty,oneof=1 2" description:"状态 (1:启用, 2:禁用)"`
|
||||
Page int `json:"page" query:"page" validate:"omitempty,min=1" minimum:"1" description:"页码"`
|
||||
PageSize int `json:"page_size" query:"page_size" validate:"omitempty,min=1,max=100" minimum:"1" maximum:"100" description:"每页数量"`
|
||||
ShopID *uint `json:"shop_id" query:"shop_id" validate:"omitempty" description:"被分配的店铺ID"`
|
||||
SeriesID *uint `json:"series_id" query:"series_id" validate:"omitempty" description:"套餐系列ID"`
|
||||
AllocatorShopID *uint `json:"allocator_shop_id" query:"allocator_shop_id" validate:"omitempty" description:"分配者店铺ID"`
|
||||
Status *int `json:"status" query:"status" validate:"omitempty,oneof=1 2" description:"状态 (1:启用, 2:禁用)"`
|
||||
}
|
||||
|
||||
// UpdateShopSeriesAllocationStatusRequest 更新套餐系列分配状态请求
|
||||
type UpdateShopSeriesAllocationStatusRequest struct {
|
||||
Status int `json:"status" validate:"required,oneof=1 2" required:"true" description:"状态 (1:启用, 2:禁用)"`
|
||||
}
|
||||
|
||||
// ShopSeriesAllocationResponse 套餐系列分配响应
|
||||
type ShopSeriesAllocationResponse struct {
|
||||
ID uint `json:"id" description:"分配ID"`
|
||||
ShopID uint `json:"shop_id" description:"被分配的店铺ID"`
|
||||
ShopName string `json:"shop_name" description:"被分配的店铺名称"`
|
||||
SeriesID uint `json:"series_id" description:"套餐系列ID"`
|
||||
SeriesName string `json:"series_name" description:"套餐系列名称"`
|
||||
AllocatorShopID uint `json:"allocator_shop_id" description:"分配者店铺ID"`
|
||||
AllocatorShopName string `json:"allocator_shop_name" description:"分配者店铺名称"`
|
||||
BaseCommission BaseCommissionConfig `json:"base_commission" description:"基础返佣配置"`
|
||||
EnableOneTimeCommission bool `json:"enable_one_time_commission" description:"是否启用一次性佣金"`
|
||||
OneTimeCommissionConfig *OneTimeCommissionConfig `json:"one_time_commission_config,omitempty" description:"一次性佣金配置"`
|
||||
EnableForceRecharge bool `json:"enable_force_recharge" description:"是否启用强充"`
|
||||
ForceRechargeAmount int64 `json:"force_recharge_amount" description:"强充金额(分)"`
|
||||
ForceRechargeTriggerType int `json:"force_recharge_trigger_type" description:"强充触发类型(1:单次充值, 2:累计充值)"`
|
||||
Status int `json:"status" description:"状态 (1:启用, 2:禁用)"`
|
||||
CreatedAt string `json:"created_at" description:"创建时间"`
|
||||
UpdatedAt string `json:"updated_at" description:"更新时间"`
|
||||
ID uint `json:"id" description:"分配ID"`
|
||||
ShopID uint `json:"shop_id" description:"被分配的店铺ID"`
|
||||
ShopName string `json:"shop_name" description:"被分配的店铺名称"`
|
||||
SeriesID uint `json:"series_id" description:"套餐系列ID"`
|
||||
SeriesName string `json:"series_name" description:"套餐系列名称"`
|
||||
SeriesCode string `json:"series_code" description:"套餐系列编码"`
|
||||
AllocatorShopID uint `json:"allocator_shop_id" description:"分配者店铺ID,0表示平台分配"`
|
||||
AllocatorShopName string `json:"allocator_shop_name" description:"分配者店铺名称"`
|
||||
OneTimeCommissionAmount int64 `json:"one_time_commission_amount" description:"该代理能拿的一次性佣金金额上限(分)"`
|
||||
EnableOneTimeCommission bool `json:"enable_one_time_commission" description:"是否启用一次性佣金"`
|
||||
OneTimeCommissionTrigger string `json:"one_time_commission_trigger" description:"一次性佣金触发类型"`
|
||||
OneTimeCommissionThreshold int64 `json:"one_time_commission_threshold" description:"一次性佣金触发阈值(分)"`
|
||||
EnableForceRecharge bool `json:"enable_force_recharge" description:"是否启用强制充值"`
|
||||
ForceRechargeAmount int64 `json:"force_recharge_amount" description:"强制充值金额(分)"`
|
||||
ForceRechargeTriggerType int `json:"force_recharge_trigger_type" description:"强充触发类型 (1:单次充值, 2:累计充值)"`
|
||||
Status int `json:"status" description:"状态 (1:启用, 2:禁用)"`
|
||||
CreatedAt string `json:"created_at" description:"创建时间"`
|
||||
UpdatedAt string `json:"updated_at" description:"更新时间"`
|
||||
}
|
||||
|
||||
// ShopSeriesAllocationPageResult 套餐系列分配分页结果
|
||||
type ShopSeriesAllocationPageResult struct {
|
||||
List []*ShopSeriesAllocationResponse `json:"list" description:"分配列表"`
|
||||
Total int64 `json:"total" description:"总数"`
|
||||
@@ -89,14 +61,7 @@ type ShopSeriesAllocationPageResult struct {
|
||||
TotalPages int `json:"total_pages" description:"总页数"`
|
||||
}
|
||||
|
||||
// UpdateShopSeriesAllocationParams 更新套餐系列分配聚合参数
|
||||
type UpdateShopSeriesAllocationParams struct {
|
||||
IDReq
|
||||
UpdateShopSeriesAllocationRequest
|
||||
}
|
||||
|
||||
// UpdateShopSeriesAllocationStatusParams 更新套餐系列分配状态聚合参数
|
||||
type UpdateShopSeriesAllocationStatusParams struct {
|
||||
IDReq
|
||||
UpdateShopSeriesAllocationStatusRequest
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
@@ -11,35 +13,135 @@ import (
|
||||
// 通过 shop_id 区分所有权:NULL=平台所有,有值=店铺所有
|
||||
type IotCard struct {
|
||||
gorm.Model
|
||||
BaseModel `gorm:"embedded"`
|
||||
ICCID string `gorm:"column:iccid;type:varchar(20);uniqueIndex:idx_iot_card_iccid,where:deleted_at IS NULL;not null;comment:ICCID(唯一标识,电信19位/其他20位)" json:"iccid"`
|
||||
CardCategory string `gorm:"column:card_category;type:varchar(20);default:'normal';not null;comment:卡业务类型 normal-普通卡 industry-行业卡" json:"card_category"`
|
||||
CarrierID uint `gorm:"column:carrier_id;index;not null;comment:运营商ID" json:"carrier_id"`
|
||||
CarrierType string `gorm:"column:carrier_type;type:varchar(20);comment:运营商类型(CMCC/CUCC/CTCC/CBN),导入时快照" json:"carrier_type"`
|
||||
CarrierName string `gorm:"column:carrier_name;type:varchar(100);comment:运营商名称,导入时快照" json:"carrier_name"`
|
||||
IMSI string `gorm:"column:imsi;type:varchar(50);comment:IMSI" json:"imsi"`
|
||||
MSISDN string `gorm:"column:msisdn;type:varchar(20);comment:MSISDN(手机号码)" json:"msisdn"`
|
||||
BatchNo string `gorm:"column:batch_no;type:varchar(100);comment:批次号" json:"batch_no"`
|
||||
Supplier string `gorm:"column:supplier;type:varchar(255);comment:供应商" json:"supplier"`
|
||||
CostPrice int64 `gorm:"column:cost_price;type:bigint;default:0;comment:成本价(分为单位)" json:"cost_price"`
|
||||
DistributePrice int64 `gorm:"column:distribute_price;type:bigint;default:0;comment:分销价(分为单位)" json:"distribute_price"`
|
||||
Status int `gorm:"column:status;type:int;default:1;not null;comment:状态 1-在库 2-已分销 3-已激活 4-已停用" json:"status"`
|
||||
ShopID *uint `gorm:"column:shop_id;index;comment:店铺ID(NULL=平台所有,有值=店铺所有)" json:"shop_id,omitempty"`
|
||||
ActivatedAt *time.Time `gorm:"column:activated_at;comment:激活时间" json:"activated_at"`
|
||||
ActivationStatus int `gorm:"column:activation_status;type:int;default:0;not null;comment:激活状态 0-未激活 1-已激活" json:"activation_status"`
|
||||
RealNameStatus int `gorm:"column:real_name_status;type:int;default:0;not null;comment:实名状态 0-未实名 1-已实名(行业卡可以保持0)" json:"real_name_status"`
|
||||
NetworkStatus int `gorm:"column:network_status;type:int;default:0;not null;comment:网络状态 0-停机 1-开机" json:"network_status"`
|
||||
DataUsageMB int64 `gorm:"column:data_usage_mb;type:bigint;default:0;comment:累计流量使用(MB)" json:"data_usage_mb"`
|
||||
EnablePolling bool `gorm:"column:enable_polling;type:boolean;default:true;comment:是否参与轮询 true-参与 false-不参与" json:"enable_polling"`
|
||||
LastDataCheckAt *time.Time `gorm:"column:last_data_check_at;comment:最后一次流量检查时间" json:"last_data_check_at"`
|
||||
LastRealNameCheckAt *time.Time `gorm:"column:last_real_name_check_at;comment:最后一次实名检查时间" json:"last_real_name_check_at"`
|
||||
LastSyncTime *time.Time `gorm:"column:last_sync_time;comment:最后一次与Gateway同步时间" json:"last_sync_time"`
|
||||
SeriesID *uint `gorm:"column:series_id;index;comment:套餐系列ID(关联PackageSeries)" json:"series_id,omitempty"`
|
||||
FirstCommissionPaid bool `gorm:"column:first_commission_paid;type:boolean;default:false;comment:一次性佣金是否已发放" json:"first_commission_paid"`
|
||||
AccumulatedRecharge int64 `gorm:"column:accumulated_recharge;type:bigint;default:0;comment:累计充值金额(分)" json:"accumulated_recharge"`
|
||||
BaseModel `gorm:"embedded"`
|
||||
ICCID string `gorm:"column:iccid;type:varchar(20);uniqueIndex:idx_iot_card_iccid,where:deleted_at IS NULL;not null;comment:ICCID(唯一标识,电信19位/其他20位)" json:"iccid"`
|
||||
CardCategory string `gorm:"column:card_category;type:varchar(20);default:'normal';not null;comment:卡业务类型 normal-普通卡 industry-行业卡" json:"card_category"`
|
||||
CarrierID uint `gorm:"column:carrier_id;index;not null;comment:运营商ID" json:"carrier_id"`
|
||||
CarrierType string `gorm:"column:carrier_type;type:varchar(20);comment:运营商类型(CMCC/CUCC/CTCC/CBN),导入时快照" json:"carrier_type"`
|
||||
CarrierName string `gorm:"column:carrier_name;type:varchar(100);comment:运营商名称,导入时快照" json:"carrier_name"`
|
||||
IMSI string `gorm:"column:imsi;type:varchar(50);comment:IMSI" json:"imsi"`
|
||||
MSISDN string `gorm:"column:msisdn;type:varchar(20);comment:MSISDN(手机号码)" json:"msisdn"`
|
||||
BatchNo string `gorm:"column:batch_no;type:varchar(100);comment:批次号" json:"batch_no"`
|
||||
Supplier string `gorm:"column:supplier;type:varchar(255);comment:供应商" json:"supplier"`
|
||||
CostPrice int64 `gorm:"column:cost_price;type:bigint;default:0;comment:成本价(分为单位)" json:"cost_price"`
|
||||
DistributePrice int64 `gorm:"column:distribute_price;type:bigint;default:0;comment:分销价(分为单位)" json:"distribute_price"`
|
||||
Status int `gorm:"column:status;type:int;default:1;not null;comment:状态 1-在库 2-已分销 3-已激活 4-已停用" json:"status"`
|
||||
ShopID *uint `gorm:"column:shop_id;index;comment:店铺ID(NULL=平台所有,有值=店铺所有)" json:"shop_id,omitempty"`
|
||||
ActivatedAt *time.Time `gorm:"column:activated_at;comment:激活时间" json:"activated_at"`
|
||||
ActivationStatus int `gorm:"column:activation_status;type:int;default:0;not null;comment:激活状态 0-未激活 1-已激活" json:"activation_status"`
|
||||
RealNameStatus int `gorm:"column:real_name_status;type:int;default:0;not null;comment:实名状态 0-未实名 1-已实名(行业卡可以保持0)" json:"real_name_status"`
|
||||
NetworkStatus int `gorm:"column:network_status;type:int;default:0;not null;comment:网络状态 0-停机 1-开机" json:"network_status"`
|
||||
DataUsageMB int64 `gorm:"column:data_usage_mb;type:bigint;default:0;comment:累计流量使用(MB)" json:"data_usage_mb"`
|
||||
EnablePolling bool `gorm:"column:enable_polling;type:boolean;default:true;comment:是否参与轮询 true-参与 false-不参与" json:"enable_polling"`
|
||||
LastDataCheckAt *time.Time `gorm:"column:last_data_check_at;comment:最后一次流量检查时间" json:"last_data_check_at"`
|
||||
LastRealNameCheckAt *time.Time `gorm:"column:last_real_name_check_at;comment:最后一次实名检查时间" json:"last_real_name_check_at"`
|
||||
LastSyncTime *time.Time `gorm:"column:last_sync_time;comment:最后一次与Gateway同步时间" json:"last_sync_time"`
|
||||
SeriesID *uint `gorm:"column:series_id;index;comment:套餐系列ID(关联PackageSeries)" json:"series_id,omitempty"`
|
||||
FirstCommissionPaid bool `gorm:"column:first_commission_paid;type:boolean;default:false;comment:一次性佣金是否已发放(废弃,使用按系列追踪)" json:"first_commission_paid"`
|
||||
AccumulatedRecharge int64 `gorm:"column:accumulated_recharge;type:bigint;default:0;comment:累计充值金额(分,废弃,使用按系列追踪)" json:"accumulated_recharge"`
|
||||
AccumulatedRechargeBySeriesJSON string `gorm:"column:accumulated_recharge_by_series;type:jsonb;default:'{}';comment:按套餐系列追踪的累计充值金额" json:"-"`
|
||||
FirstRechargeTriggeredBySeriesJSON string `gorm:"column:first_recharge_triggered_by_series;type:jsonb;default:'{}';comment:按套餐系列追踪的首充触发状态" json:"-"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (IotCard) TableName() string {
|
||||
return "tb_iot_card"
|
||||
}
|
||||
|
||||
func (c *IotCard) GetAccumulatedRechargeBySeriesMap() (map[uint]int64, error) {
|
||||
result := make(map[uint]int64)
|
||||
if c.AccumulatedRechargeBySeriesJSON == "" || c.AccumulatedRechargeBySeriesJSON == "{}" {
|
||||
return result, nil
|
||||
}
|
||||
var raw map[string]int64
|
||||
if err := json.Unmarshal([]byte(c.AccumulatedRechargeBySeriesJSON), &raw); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for k, v := range raw {
|
||||
id, err := strconv.ParseUint(k, 10, 64)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
result[uint(id)] = v
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *IotCard) SetAccumulatedRechargeBySeriesMap(m map[uint]int64) error {
|
||||
raw := make(map[string]int64)
|
||||
for k, v := range m {
|
||||
raw[strconv.FormatUint(uint64(k), 10)] = v
|
||||
}
|
||||
data, err := json.Marshal(raw)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.AccumulatedRechargeBySeriesJSON = string(data)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *IotCard) GetAccumulatedRechargeBySeries(seriesID uint) int64 {
|
||||
m, err := c.GetAccumulatedRechargeBySeriesMap()
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return m[seriesID]
|
||||
}
|
||||
|
||||
func (c *IotCard) AddAccumulatedRechargeBySeries(seriesID uint, amount int64) error {
|
||||
m, err := c.GetAccumulatedRechargeBySeriesMap()
|
||||
if err != nil {
|
||||
m = make(map[uint]int64)
|
||||
}
|
||||
m[seriesID] += amount
|
||||
return c.SetAccumulatedRechargeBySeriesMap(m)
|
||||
}
|
||||
|
||||
func (c *IotCard) GetFirstRechargeTriggeredBySeriesMap() (map[uint]bool, error) {
|
||||
result := make(map[uint]bool)
|
||||
if c.FirstRechargeTriggeredBySeriesJSON == "" || c.FirstRechargeTriggeredBySeriesJSON == "{}" {
|
||||
return result, nil
|
||||
}
|
||||
var raw map[string]bool
|
||||
if err := json.Unmarshal([]byte(c.FirstRechargeTriggeredBySeriesJSON), &raw); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for k, v := range raw {
|
||||
id, err := strconv.ParseUint(k, 10, 64)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
result[uint(id)] = v
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *IotCard) SetFirstRechargeTriggeredBySeriesMap(m map[uint]bool) error {
|
||||
raw := make(map[string]bool)
|
||||
for k, v := range m {
|
||||
raw[strconv.FormatUint(uint64(k), 10)] = v
|
||||
}
|
||||
data, err := json.Marshal(raw)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.FirstRechargeTriggeredBySeriesJSON = string(data)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *IotCard) IsFirstRechargeTriggeredBySeries(seriesID uint) bool {
|
||||
m, err := c.GetFirstRechargeTriggeredBySeriesMap()
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return m[seriesID]
|
||||
}
|
||||
|
||||
func (c *IotCard) SetFirstRechargeTriggeredBySeries(seriesID uint, triggered bool) error {
|
||||
m, err := c.GetFirstRechargeTriggeredBySeriesMap()
|
||||
if err != nil {
|
||||
m = make(map[uint]bool)
|
||||
}
|
||||
m[seriesID] = triggered
|
||||
return c.SetFirstRechargeTriggeredBySeriesMap(m)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
@@ -10,11 +11,13 @@ import (
|
||||
// 套餐的分组,用于一次性分佣规则配置
|
||||
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"`
|
||||
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 指定表名
|
||||
@@ -32,13 +35,11 @@ type Package struct {
|
||||
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"`
|
||||
DataType string `gorm:"column:data_type;type:varchar(20);comment:流量类型 real-真流量 virtual-虚流量" json:"data_type"`
|
||||
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"`
|
||||
DataAmountMB int64 `gorm:"column:data_amount_mb;type:bigint;default:0;comment:总流量额度(MB)" json:"data_amount_mb"`
|
||||
Price int64 `gorm:"column:price;type:bigint;not null;comment:套餐价格(分为单位)" json:"price"`
|
||||
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"`
|
||||
SuggestedCostPrice int64 `gorm:"column:suggested_cost_price;type:bigint;default:0;comment:建议成本价(分为单位)" json:"suggested_cost_price"`
|
||||
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"`
|
||||
}
|
||||
@@ -72,3 +73,68 @@ type PackageUsage struct {
|
||||
func (PackageUsage) TableName() string {
|
||||
return "tb_package_usage"
|
||||
}
|
||||
|
||||
// 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 {
|
||||
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"
|
||||
)
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
@@ -4,17 +4,15 @@ import (
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// ShopPackageAllocation 店铺单套餐分配模型
|
||||
// 用于对单个套餐设置覆盖成本价,优先级高于系列级别的加价计算
|
||||
// 适用于特殊定价场景(如某个套餐给特定代理优惠价)
|
||||
type ShopPackageAllocation struct {
|
||||
gorm.Model
|
||||
BaseModel `gorm:"embedded"`
|
||||
ShopID uint `gorm:"column:shop_id;index;not null;comment:被分配的店铺ID" json:"shop_id"`
|
||||
PackageID uint `gorm:"column:package_id;index;not null;comment:套餐ID" json:"package_id"`
|
||||
AllocationID uint `gorm:"column:allocation_id;index;not null;comment:关联的系列分配ID" json:"allocation_id"`
|
||||
CostPrice int64 `gorm:"column:cost_price;type:bigint;not null;comment:覆盖的成本价(分)" json:"cost_price"`
|
||||
Status int `gorm:"column:status;type:int;default:1;not null;comment:状态 1-启用 2-禁用" json:"status"`
|
||||
BaseModel `gorm:"embedded"`
|
||||
ShopID uint `gorm:"column:shop_id;index;not null;comment:被分配的店铺ID" json:"shop_id"`
|
||||
PackageID uint `gorm:"column:package_id;index;not null;comment:套餐ID" json:"package_id"`
|
||||
AllocatorShopID uint `gorm:"column:allocator_shop_id;index;not null;default:0;comment:分配者店铺ID,0表示平台分配" json:"allocator_shop_id"`
|
||||
CostPrice int64 `gorm:"column:cost_price;type:bigint;not null;comment:该代理的成本价(分)" json:"cost_price"`
|
||||
SeriesAllocationID *uint `gorm:"column:series_allocation_id;index;comment:关联的系列分配ID" json:"series_allocation_id"`
|
||||
Status int `gorm:"column:status;type:int;default:1;not null;comment:状态 1-启用 2-禁用" json:"status"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
|
||||
@@ -4,59 +4,22 @@ import (
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// ShopSeriesAllocation 店铺套餐系列分配模型
|
||||
// 记录上级店铺为下级店铺分配的套餐系列,包含基础返佣配置和梯度返佣开关
|
||||
// 分配者只能分配自己已被分配的套餐系列,且只能分配给直属下级
|
||||
type ShopSeriesAllocation struct {
|
||||
gorm.Model
|
||||
BaseModel `gorm:"embedded"`
|
||||
ShopID uint `gorm:"column:shop_id;index;not null;comment:被分配的店铺ID" json:"shop_id"`
|
||||
SeriesID uint `gorm:"column:series_id;index;not null;comment:套餐系列ID" json:"series_id"`
|
||||
AllocatorShopID uint `gorm:"column:allocator_shop_id;index;not null;comment:分配者店铺ID(上级)" json:"allocator_shop_id"`
|
||||
BaseCommissionMode string `gorm:"column:base_commission_mode;type:varchar(20);not null;default:percent;comment:基础返佣模式 fixed-固定金额 percent-百分比" json:"base_commission_mode"`
|
||||
BaseCommissionValue int64 `gorm:"column:base_commission_value;type:bigint;not null;default:0;comment:基础返佣值(分或千分比,如200=20%)" json:"base_commission_value"`
|
||||
|
||||
// 一次性佣金配置
|
||||
EnableOneTimeCommission bool `gorm:"column:enable_one_time_commission;type:boolean;not null;default:false;comment:是否启用一次性佣金" json:"enable_one_time_commission"`
|
||||
OneTimeCommissionType string `gorm:"column:one_time_commission_type;type:varchar(20);comment:一次性佣金类型 fixed-固定 tiered-梯度" json:"one_time_commission_type"`
|
||||
OneTimeCommissionTrigger string `gorm:"column:one_time_commission_trigger;type:varchar(30);comment:触发条件 single_recharge-单次充值 accumulated_recharge-累计充值" json:"one_time_commission_trigger"`
|
||||
OneTimeCommissionThreshold int64 `gorm:"column:one_time_commission_threshold;type:bigint;default:0;comment:最低阈值(分)" json:"one_time_commission_threshold"`
|
||||
OneTimeCommissionMode string `gorm:"column:one_time_commission_mode;type:varchar(20);comment:返佣模式 fixed-固定金额 percent-百分比" json:"one_time_commission_mode"`
|
||||
OneTimeCommissionValue int64 `gorm:"column:one_time_commission_value;type:bigint;default:0;comment:佣金金额(分)或比例(千分比)" json:"one_time_commission_value"`
|
||||
|
||||
// 强充配置
|
||||
EnableForceRecharge bool `gorm:"column:enable_force_recharge;type:boolean;default:false;comment:是否启用强充(累计充值时可选)" json:"enable_force_recharge"`
|
||||
ForceRechargeAmount int64 `gorm:"column:force_recharge_amount;type:bigint;default:0;comment:强充金额(分,0表示使用阈值金额)" json:"force_recharge_amount"`
|
||||
ForceRechargeTriggerType int `gorm:"column:force_recharge_trigger_type;type:int;default:2;comment:强充触发类型(1:单次充值, 2:累计充值)" json:"force_recharge_trigger_type"`
|
||||
|
||||
Status int `gorm:"column:status;type:int;default:1;not null;comment:状态 1-启用 2-禁用" json:"status"`
|
||||
BaseModel `gorm:"embedded"`
|
||||
ShopID uint `gorm:"column:shop_id;index;not null;comment:被分配的店铺ID" json:"shop_id"`
|
||||
SeriesID uint `gorm:"column:series_id;index;not null;comment:套餐系列ID" json:"series_id"`
|
||||
AllocatorShopID uint `gorm:"column:allocator_shop_id;index;not null;default:0;comment:分配者店铺ID,0表示平台分配" json:"allocator_shop_id"`
|
||||
OneTimeCommissionAmount int64 `gorm:"column:one_time_commission_amount;type:bigint;default:0;not null;comment:该代理能拿的一次性佣金金额上限(分)" json:"one_time_commission_amount"`
|
||||
EnableOneTimeCommission bool `gorm:"column:enable_one_time_commission;default:false;not null;comment:是否启用一次性佣金" json:"enable_one_time_commission"`
|
||||
OneTimeCommissionTrigger string `gorm:"column:one_time_commission_trigger;type:varchar(50);comment:一次性佣金触发类型" json:"one_time_commission_trigger"`
|
||||
OneTimeCommissionThreshold int64 `gorm:"column:one_time_commission_threshold;type:bigint;default:0;not null;comment:一次性佣金触发阈值(分)" json:"one_time_commission_threshold"`
|
||||
EnableForceRecharge bool `gorm:"column:enable_force_recharge;default:false;not null;comment:是否启用强制充值" json:"enable_force_recharge"`
|
||||
ForceRechargeAmount int64 `gorm:"column:force_recharge_amount;type:bigint;default:0;not null;comment:强制充值金额(分)" json:"force_recharge_amount"`
|
||||
ForceRechargeTriggerType int `gorm:"column:force_recharge_trigger_type;type:int;default:2;not null;comment:强充触发类型 1-单次充值 2-累计充值" json:"force_recharge_trigger_type"`
|
||||
Status int `gorm:"column:status;type:int;default:1;not null;comment:状态 1-启用 2-禁用" json:"status"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (ShopSeriesAllocation) TableName() string {
|
||||
return "tb_shop_series_allocation"
|
||||
}
|
||||
|
||||
// 返佣模式常量
|
||||
const (
|
||||
// CommissionModeFixed 固定金额返佣
|
||||
CommissionModeFixed = "fixed"
|
||||
// CommissionModePercent 百分比返佣(千分比)
|
||||
CommissionModePercent = "percent"
|
||||
)
|
||||
|
||||
// 一次性佣金类型常量
|
||||
const (
|
||||
// OneTimeCommissionTypeFixed 固定一次性佣金
|
||||
OneTimeCommissionTypeFixed = "fixed"
|
||||
// OneTimeCommissionTypeTiered 梯度一次性佣金
|
||||
OneTimeCommissionTypeTiered = "tiered"
|
||||
)
|
||||
|
||||
// 一次性佣金触发类型常量
|
||||
const (
|
||||
// OneTimeCommissionTriggerSingleRecharge 单次充值触发
|
||||
OneTimeCommissionTriggerSingleRecharge = "single_recharge"
|
||||
// OneTimeCommissionTriggerAccumulatedRecharge 累计充值触发
|
||||
OneTimeCommissionTriggerAccumulatedRecharge = "accumulated_recharge"
|
||||
)
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// ShopSeriesAllocationConfig 套餐系列分配配置版本模型
|
||||
// 记录返佣配置的历史版本,订单创建时锁定配置版本
|
||||
// 支持配置追溯和数据一致性保障
|
||||
type ShopSeriesAllocationConfig struct {
|
||||
gorm.Model
|
||||
AllocationID uint `gorm:"column:allocation_id;index;not null;comment:关联的分配ID" json:"allocation_id"`
|
||||
Version int `gorm:"column:version;type:int;not null;comment:配置版本号" json:"version"`
|
||||
BaseCommissionMode string `gorm:"column:base_commission_mode;type:varchar(20);not null;comment:基础返佣模式(配置快照)" json:"base_commission_mode"`
|
||||
BaseCommissionValue int64 `gorm:"column:base_commission_value;type:bigint;not null;comment:基础返佣值(配置快照)" json:"base_commission_value"`
|
||||
EffectiveFrom time.Time `gorm:"column:effective_from;type:timestamptz;not null;comment:生效开始时间" json:"effective_from"`
|
||||
EffectiveTo *time.Time `gorm:"column:effective_to;type:timestamptz;comment:生效结束时间(NULL表示当前生效)" json:"effective_to"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (ShopSeriesAllocationConfig) TableName() string {
|
||||
return "tb_shop_series_allocation_config"
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// ShopSeriesOneTimeCommissionTier 一次性佣金梯度配置模型
|
||||
// 记录基于销售业绩的一次性佣金梯度档位
|
||||
// 当系列分配的累计销量或销售额达到不同阈值时,返不同的一次性佣金金额
|
||||
type ShopSeriesOneTimeCommissionTier struct {
|
||||
gorm.Model
|
||||
BaseModel `gorm:"embedded"`
|
||||
AllocationID uint `gorm:"column:allocation_id;index;not null;comment:系列分配ID" json:"allocation_id"`
|
||||
TierType string `gorm:"column:tier_type;type:varchar(20);not null;comment:梯度类型 sales_count-销量 sales_amount-销售额" json:"tier_type"`
|
||||
ThresholdValue int64 `gorm:"column:threshold_value;type:bigint;not null;comment:梯度阈值(销量或销售额分)" json:"threshold_value"`
|
||||
CommissionMode string `gorm:"column:commission_mode;type:varchar(20);not null;default:fixed;comment:返佣模式 fixed-固定金额 percent-百分比" json:"commission_mode"`
|
||||
CommissionValue int64 `gorm:"column:commission_value;type:bigint;not null;comment:返佣值(分或千分比)" json:"commission_value"`
|
||||
Status int `gorm:"column:status;type:int;default:1;not null;comment:状态 1-启用 2-停用" json:"status"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (ShopSeriesOneTimeCommissionTier) TableName() string {
|
||||
return "tb_shop_series_one_time_commission_tier"
|
||||
}
|
||||
|
||||
// 梯度类型常量
|
||||
const (
|
||||
// TierTypeSalesCount 销量梯度
|
||||
TierTypeSalesCount = "sales_count"
|
||||
// TierTypeSalesAmount 销售额梯度
|
||||
TierTypeSalesAmount = "sales_amount"
|
||||
)
|
||||
|
||||
// 返佣模式常量在 shop_series_allocation.go 中定义
|
||||
// CommissionModeFixed = "fixed"
|
||||
// CommissionModePercent = "percent"
|
||||
Reference in New Issue
Block a user