2026-05-29 19:56:14 +08:00

343 lines
20 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package model
const (
UserStatusActive = "active"
UserStatusLocked = "locked"
UserStatusDisabled = "disabled"
JobStatusPending = "pending"
JobStatusRunning = "running"
JobStatusSucceeded = "succeeded"
JobStatusFailed = "failed"
JobStatusCanceled = "canceled"
)
type User struct {
ID uint `gorm:"primaryKey" json:"id"`
Username string `gorm:"size:64;uniqueIndex;not null" json:"account"`
Name string `gorm:"size:80;not null" json:"name"`
PasswordHash string `gorm:"size:255;not null" json:"-"`
Team string `gorm:"size:80" json:"team"`
Status string `gorm:"size:24;index;not null;default:active" json:"status"`
MFAEnabled bool `gorm:"not null;default:false" json:"mfaEnabled"`
LastLoginAtMS *int64 `gorm:"column:last_login_at_ms" json:"lastLoginAtMs"`
Roles []Role `gorm:"many2many:admin_user_roles;" json:"roles"`
CreatedAtMS int64 `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"`
UpdatedAtMS int64 `gorm:"column:updated_at_ms;autoUpdateTime:milli" json:"updatedAtMs"`
}
func (User) TableName() string {
return "admin_users"
}
type Role struct {
ID uint `gorm:"primaryKey" json:"id"`
Name string `gorm:"size:80;uniqueIndex;not null" json:"name"`
Code string `gorm:"size:80;uniqueIndex;not null" json:"code"`
Description string `gorm:"size:255" json:"description"`
Users []User `gorm:"many2many:admin_user_roles;" json:"-"`
Permissions []Permission `gorm:"many2many:admin_role_permissions;" json:"permissions"`
CreatedAtMS int64 `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"`
UpdatedAtMS int64 `gorm:"column:updated_at_ms;autoUpdateTime:milli" json:"updatedAtMs"`
}
func (Role) TableName() string {
return "admin_roles"
}
type Permission struct {
ID uint `gorm:"primaryKey" json:"id"`
Name string `gorm:"size:100;not null" json:"name"`
Code string `gorm:"size:100;uniqueIndex;not null" json:"code"`
Kind string `gorm:"size:32;index;not null" json:"kind"`
Description string `gorm:"size:255" json:"description"`
CreatedAtMS int64 `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"`
UpdatedAtMS int64 `gorm:"column:updated_at_ms;autoUpdateTime:milli" json:"updatedAtMs"`
}
func (Permission) TableName() string {
return "admin_permissions"
}
type Menu struct {
ID uint `gorm:"primaryKey" json:"id"`
ParentID *uint `gorm:"index" json:"parentId"`
Title string `gorm:"size:80;not null" json:"label"`
Code string `gorm:"size:100;uniqueIndex;not null" json:"code"`
Path string `gorm:"size:160" json:"path"`
Icon string `gorm:"size:64" json:"icon"`
PermissionCode string `gorm:"size:100;index" json:"permissionCode"`
Sort int `gorm:"not null;default:0" json:"sort"`
Visible bool `gorm:"not null;default:true" json:"visible"`
CreatedAtMS int64 `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"`
UpdatedAtMS int64 `gorm:"column:updated_at_ms;autoUpdateTime:milli" json:"updatedAtMs"`
}
func (Menu) TableName() string {
return "admin_menus"
}
type AppConfig struct {
ID uint `gorm:"primaryKey" json:"id"`
Group string `gorm:"size:64;index:idx_admin_app_config_group_key,unique;not null" json:"group"`
Key string `gorm:"size:100;index:idx_admin_app_config_group_key,unique;not null" json:"key"`
Value string `gorm:"type:text" json:"value"`
Description string `gorm:"size:255" json:"description"`
CreatedAtMS int64 `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"`
UpdatedAtMS int64 `gorm:"column:updated_at_ms;autoUpdateTime:milli" json:"updatedAtMs"`
}
func (AppConfig) TableName() string {
return "admin_app_configs"
}
type AppBanner struct {
ID uint `gorm:"primaryKey" json:"id"`
AppCode string `gorm:"size:32;index:idx_admin_app_banners_app_sort,not null;default:lalu" json:"appCode"`
CoverURL string `gorm:"size:1024;not null" json:"coverUrl"`
RoomSmallImageURL string `gorm:"column:room_small_image_url;size:1024;not null;default:'';comment:房间内小屏图 URL" json:"roomSmallImageUrl"`
BannerType string `gorm:"size:16;not null" json:"bannerType"`
DisplayScope string `gorm:"size:128;index:idx_admin_app_banners_display,not null;default:home;comment:显示范围,多选逗号分隔:首页、房间内或充值页" json:"displayScope"`
Param string `gorm:"size:2048" json:"param"`
Status string `gorm:"size:24;index:idx_admin_app_banners_app_sort,not null;default:active" json:"status"`
Platform string `gorm:"size:24;index:idx_admin_app_banners_scope,not null" json:"platform"`
SortOrder int `gorm:"index:idx_admin_app_banners_app_sort,not null;default:0" json:"sortOrder"`
RegionID int64 `gorm:"index:idx_admin_app_banners_scope,not null;default:0" json:"regionId"`
CountryCode string `gorm:"size:8;index:idx_admin_app_banners_scope" json:"countryCode"`
Description string `gorm:"size:255" json:"description"`
StartsAtMS int64 `gorm:"column:starts_at_ms;not null;default:0;comment:投放开始时间UTC epoch ms" json:"startsAtMs"`
EndsAtMS int64 `gorm:"column:ends_at_ms;not null;default:0;comment:投放结束时间UTC epoch ms" json:"endsAtMs"`
CreatedAtMS int64 `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"`
UpdatedAtMS int64 `gorm:"column:updated_at_ms;autoUpdateTime:milli" json:"updatedAtMs"`
}
func (AppBanner) TableName() string {
return "admin_app_banners"
}
type AppVersion struct {
ID uint `gorm:"primaryKey" json:"id"`
AppCode string `gorm:"size:32;uniqueIndex:uk_admin_app_versions_build,not null;default:lalu" json:"appCode"`
Platform string `gorm:"size:24;uniqueIndex:uk_admin_app_versions_build;index:idx_admin_app_versions_latest,not null" json:"platform"`
Version string `gorm:"size:40;not null" json:"version"`
BuildNumber int64 `gorm:"uniqueIndex:uk_admin_app_versions_build;index:idx_admin_app_versions_latest,not null" json:"buildNumber"`
ForceUpdate bool `gorm:"not null;default:false" json:"forceUpdate"`
DownloadURL string `gorm:"size:2048;not null" json:"downloadUrl"`
Description string `gorm:"type:text" json:"description"`
CreatedAtMS int64 `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"`
UpdatedAtMS int64 `gorm:"column:updated_at_ms;autoUpdateTime:milli" json:"updatedAtMs"`
}
func (AppVersion) TableName() string {
return "admin_app_versions"
}
type AppExploreTab struct {
ID uint `gorm:"primaryKey" json:"id"`
AppCode string `gorm:"size:32;uniqueIndex:uk_admin_app_explore_tabs_tab;index:idx_admin_app_explore_tabs_app_sort,not null;default:lalu" json:"appCode"`
Tab string `gorm:"size:80;uniqueIndex:uk_admin_app_explore_tabs_tab,not null" json:"tab"`
H5URL string `gorm:"column:h5_url;size:2048;not null" json:"h5Url"`
Enabled bool `gorm:"index:idx_admin_app_explore_tabs_app_sort,not null;default:true" json:"enabled"`
SortOrder int `gorm:"index:idx_admin_app_explore_tabs_app_sort,not null;default:0" json:"sortOrder"`
CreatedAtMS int64 `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"`
UpdatedAtMS int64 `gorm:"column:updated_at_ms;autoUpdateTime:milli" json:"updatedAtMs"`
}
func (AppExploreTab) TableName() string {
return "admin_app_explore_tabs"
}
type HostAgencySalaryPolicy struct {
ID uint `gorm:"primaryKey" json:"id"`
AppCode string `gorm:"size:32;uniqueIndex:uk_admin_host_agency_salary_policy_name;index:idx_admin_host_agency_salary_policy_region,not null;default:lalu" json:"appCode"`
Name string `gorm:"size:120;uniqueIndex:uk_admin_host_agency_salary_policy_name;not null" json:"name"`
// RegionID 是第一阶段的政策适用边界;结算时按用户所属区域命中唯一 active 政策。
RegionID int64 `gorm:"uniqueIndex:uk_admin_host_agency_salary_policy_name;index:idx_admin_host_agency_salary_policy_region,not null" json:"regionId"`
Status string `gorm:"size:24;index:idx_admin_host_agency_salary_policy_region,not null;default:disabled" json:"status"`
// SettlementMode 只配置结算节奏,等级金额仍按累计值保存,实际发放由后续结算任务计算差额。
SettlementMode string `gorm:"size:24;not null;default:daily" json:"settlementMode"`
// SettlementTriggerMode 区分自动任务与后台人工结算;手动政策发布后仍可被查询,但不会被 cron 自动发薪。
SettlementTriggerMode string `gorm:"column:settlement_trigger_mode;size:24;not null;default:automatic" json:"settlementTriggerMode"`
// 比例字段使用 decimal 字符串承载,避免金币、钻石、美元换算出现 float 精度误差。
GiftCoinToDiamondRatio string `gorm:"column:gift_coin_to_diamond_ratio;type:decimal(18,6);not null;default:1.000000" json:"giftCoinToDiamondRatio"`
ResidualDiamondToUSDRate string `gorm:"column:residual_diamond_to_usd_rate;type:decimal(24,12);not null;default:0.000000000000" json:"residualDiamondToUsdRate"`
// 时间范围采用 epoch ms 半开区间EffectiveToMS=0 表示长期有效。
EffectiveFromMS int64 `gorm:"column:effective_from_ms;index:idx_admin_host_agency_salary_policy_region,not null;default:0" json:"effectiveFromMs"`
EffectiveToMS int64 `gorm:"column:effective_to_ms;not null;default:0" json:"effectiveToMs"`
Description string `gorm:"size:255;not null;default:''" json:"description"`
CreatedByAdminID uint `gorm:"column:created_by_admin_id;not null;default:0" json:"createdByAdminId"`
UpdatedByAdminID uint `gorm:"column:updated_by_admin_id;not null;default:0" json:"updatedByAdminId"`
// 发布字段只记录 admin 配置同步到 wallet 运行快照的结果;结算仍只读取 wallet-service 自己的运行表。
PublishStatus string `gorm:"column:publish_status;size:24;not null;default:draft" json:"publishStatus"`
PublishError string `gorm:"column:publish_error;size:255;not null;default:''" json:"publishError"`
PublishedAtMS int64 `gorm:"column:published_at_ms;not null;default:0" json:"publishedAtMs"`
PublishedByAdminID uint `gorm:"column:published_by_admin_id;not null;default:0" json:"publishedByAdminId"`
CreatedAtMS int64 `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"`
UpdatedAtMS int64 `gorm:"column:updated_at_ms;autoUpdateTime:milli" json:"updatedAtMs"`
Levels []HostAgencySalaryLevel `gorm:"foreignKey:PolicyID" json:"levels"`
}
func (HostAgencySalaryPolicy) TableName() string {
return "admin_host_agency_salary_policies"
}
type HostAgencySalaryLevel struct {
ID uint `gorm:"primaryKey" json:"id"`
PolicyID uint `gorm:"uniqueIndex:uk_admin_host_agency_salary_level;index:idx_admin_host_agency_salary_level_policy,not null" json:"policyId"`
// LevelNo 是累计工资差额结算的顺序锚点,必须在同一 policy 下唯一。
LevelNo int32 `gorm:"column:level_no;uniqueIndex:uk_admin_host_agency_salary_level;not null" json:"level"`
// RequiredDiamonds 保存主播当月钻石门槛,月底清空逻辑不在 admin-server 第一阶段执行。
RequiredDiamonds int64 `gorm:"column:required_diamonds;index:idx_admin_host_agency_salary_level_policy,not null" json:"requiredDiamonds"`
// 三个权益字段保存“达到该等级后的累计值”,结算任务只发本次等级与已结算等级之间的差额。
HostSalaryUSD string `gorm:"column:host_salary_usd;type:decimal(12,2);not null;default:0.00" json:"hostSalaryUsd"`
HostCoinReward int64 `gorm:"column:host_coin_reward;not null;default:0" json:"hostCoinReward"`
AgencySalaryUSD string `gorm:"column:agency_salary_usd;type:decimal(12,2);not null;default:0.00" json:"agencySalaryUsd"`
Status string `gorm:"size:24;not null;default:active" json:"status"`
SortOrder int32 `gorm:"column:sort_order;not null;default:0" json:"sortOrder"`
CreatedAtMS int64 `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"`
UpdatedAtMS int64 `gorm:"column:updated_at_ms;autoUpdateTime:milli" json:"updatedAtMs"`
}
func (HostAgencySalaryLevel) TableName() string {
return "admin_host_agency_salary_policy_levels"
}
type TeamSalaryPolicy struct {
ID uint `gorm:"primaryKey" json:"id"`
AppCode string `gorm:"size:32;uniqueIndex:uk_admin_team_salary_policy_name;index:idx_admin_team_salary_policy_scope,not null;default:lalu" json:"appCode"`
// PolicyType 当前只允许 bd/admin拆表会让两类策略后续结算扩展变重所以用类型字段保持同一套配置 API。
PolicyType string `gorm:"column:policy_type;size:24;uniqueIndex:uk_admin_team_salary_policy_name;index:idx_admin_team_salary_policy_scope,not null" json:"policyType"`
Name string `gorm:"size:120;uniqueIndex:uk_admin_team_salary_policy_name;not null" json:"name"`
// RegionID 沿用 Host 政策的区域边界,保证同一区域组织链路可以命中同一套工资配置。
RegionID int64 `gorm:"uniqueIndex:uk_admin_team_salary_policy_name;index:idx_admin_team_salary_policy_scope,not null" json:"regionId"`
Status string `gorm:"size:24;index:idx_admin_team_salary_policy_scope,not null;default:disabled" json:"status"`
// SettlementTriggerMode 决定次月 5 日窗口由自动任务处理还是进入后台人工批量结算池。
SettlementTriggerMode string `gorm:"column:settlement_trigger_mode;size:24;not null;default:automatic" json:"settlementTriggerMode"`
// BD/Admin 都按完整自然月统计,结算日期固定为次月 5 日;这里不再提供日结/半月结节奏字段。
EffectiveFromMS int64 `gorm:"column:effective_from_ms;index:idx_admin_team_salary_policy_scope,not null;default:0" json:"effectiveFromMs"`
EffectiveToMS int64 `gorm:"column:effective_to_ms;not null;default:0" json:"effectiveToMs"`
Description string `gorm:"size:255;not null;default:''" json:"description"`
CreatedByAdminID uint `gorm:"column:created_by_admin_id;not null;default:0" json:"createdByAdminId"`
UpdatedByAdminID uint `gorm:"column:updated_by_admin_id;not null;default:0" json:"updatedByAdminId"`
CreatedAtMS int64 `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"`
UpdatedAtMS int64 `gorm:"column:updated_at_ms;autoUpdateTime:milli" json:"updatedAtMs"`
Levels []TeamSalaryLevel `gorm:"foreignKey:PolicyID" json:"levels"`
}
func (TeamSalaryPolicy) TableName() string {
return "admin_team_salary_policies"
}
type TeamSalaryLevel struct {
ID uint `gorm:"primaryKey" json:"id"`
PolicyID uint `gorm:"uniqueIndex:uk_admin_team_salary_level;index:idx_admin_team_salary_level_policy,not null" json:"policyId"`
// LevelNo 是差额结算锚点,当前等级累计工资减去已结算累计工资就是本次应发金额。
LevelNo int32 `gorm:"column:level_no;uniqueIndex:uk_admin_team_salary_level;not null" json:"level"`
// ThresholdUSD 对 BD 表示下属 Agency 管理主播 Host Salary 合计门槛,对 Admin 表示下属 BD Salary 合计门槛。
ThresholdUSD string `gorm:"column:threshold_usd;type:decimal(12,2);index:idx_admin_team_salary_level_policy,not null;default:0.00" json:"thresholdUsd"`
// RatePercent 保存运营看到的百分比数字,例如 8 表示 8%,结算时再换算成比例。
RatePercent string `gorm:"column:rate_percent;type:decimal(9,4);not null;default:0.0000" json:"ratePercent"`
// SalaryUSD 是达到该等级后的累计应得工资,实际入账仍按差额结算。
SalaryUSD string `gorm:"column:salary_usd;type:decimal(12,2);not null;default:0.00" json:"salaryUsd"`
Status string `gorm:"size:24;not null;default:active" json:"status"`
SortOrder int32 `gorm:"column:sort_order;not null;default:0" json:"sortOrder"`
CreatedAtMS int64 `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"`
UpdatedAtMS int64 `gorm:"column:updated_at_ms;autoUpdateTime:milli" json:"updatedAtMs"`
}
func (TeamSalaryLevel) TableName() string {
return "admin_team_salary_policy_levels"
}
type RefreshToken struct {
ID uint `gorm:"primaryKey" json:"id"`
UserID uint `gorm:"index;not null" json:"userId"`
TokenHash string `gorm:"size:128;uniqueIndex;not null" json:"-"`
UserAgent string `gorm:"size:255" json:"userAgent"`
IP string `gorm:"size:64" json:"ip"`
ExpiresAtMS int64 `gorm:"column:expires_at_ms;index;not null" json:"expiresAtMs"`
RevokedAtMS *int64 `gorm:"column:revoked_at_ms" json:"revokedAtMs"`
CreatedAtMS int64 `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"`
UpdatedAtMS int64 `gorm:"column:updated_at_ms;autoUpdateTime:milli" json:"updatedAtMs"`
}
func (RefreshToken) TableName() string {
return "admin_refresh_tokens"
}
type LoginLog struct {
ID uint `gorm:"primaryKey" json:"id"`
Username string `gorm:"size:64;index" json:"username"`
UserID *uint `gorm:"index" json:"userId"`
IP string `gorm:"size:64" json:"ip"`
UserAgent string `gorm:"size:255" json:"userAgent"`
Status string `gorm:"size:32;index;not null" json:"status"`
Message string `gorm:"size:255" json:"message"`
CreatedAtMS int64 `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"`
}
func (LoginLog) TableName() string {
return "admin_login_logs"
}
type OperationLog struct {
ID uint `gorm:"primaryKey" json:"id"`
RequestID string `gorm:"size:64;index;not null;default:''" json:"requestId"`
UserID uint `gorm:"index;not null" json:"userId"`
Username string `gorm:"size:64;index;not null" json:"username"`
Action string `gorm:"size:80;index;not null" json:"action"`
Resource string `gorm:"size:120;index" json:"resource"`
ResourceID string `gorm:"size:80;index;not null;default:''" json:"resourceId"`
Method string `gorm:"size:12" json:"method"`
Path string `gorm:"size:180" json:"path"`
IP string `gorm:"size:64" json:"ip"`
UserAgent string `gorm:"size:255;not null;default:''" json:"userAgent"`
Status string `gorm:"size:32;index;not null" json:"status"`
HTTPStatus int `gorm:"not null;default:0" json:"httpStatus"`
RiskLevel string `gorm:"size:24;index;not null;default:normal" json:"riskLevel"`
LatencyMS int64 `gorm:"not null;default:0" json:"latencyMs"`
Detail string `gorm:"type:text" json:"detail"`
CreatedAtMS int64 `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"`
}
func (OperationLog) TableName() string {
return "admin_operation_logs"
}
type DataScope struct {
ID uint `gorm:"primaryKey" json:"id"`
RoleID uint `gorm:"index;not null" json:"roleId"`
ScopeType string `gorm:"size:40;index;not null" json:"scopeType"`
ScopeValue string `gorm:"size:120;index;not null" json:"scopeValue"`
CreatedAtMS int64 `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"`
UpdatedAtMS int64 `gorm:"column:updated_at_ms;autoUpdateTime:milli" json:"updatedAtMs"`
}
func (DataScope) TableName() string {
return "admin_data_scopes"
}
type AdminJob struct {
ID uint `gorm:"primaryKey" json:"id"`
Type string `gorm:"size:80;index;not null" json:"type"`
Status string `gorm:"size:32;index;not null" json:"status"`
PayloadJSON string `gorm:"type:text" json:"payload"`
ResultJSON string `gorm:"type:text" json:"result"`
Error string `gorm:"type:text" json:"error"`
Attempt int `gorm:"not null;default:0" json:"attempt"`
MaxAttempts int `gorm:"not null;default:3" json:"maxAttempts"`
LockedBy string `gorm:"size:120;index;not null;default:''" json:"lockedBy"`
LockedUntilMS *int64 `gorm:"column:locked_until_ms;index" json:"lockedUntilMs"`
ArtifactPath string `gorm:"size:255;not null;default:''" json:"artifactPath"`
CreatedBy uint `gorm:"index;not null" json:"createdBy"`
CreatedByName string `gorm:"size:64;index;not null" json:"createdByName"`
StartedAtMS *int64 `gorm:"column:started_at_ms" json:"startedAtMs"`
FinishedAtMS *int64 `gorm:"column:finished_at_ms" json:"finishedAtMs"`
CreatedAtMS int64 `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"`
UpdatedAtMS int64 `gorm:"column:updated_at_ms;autoUpdateTime:milli" json:"updatedAtMs"`
}
func (AdminJob) TableName() string {
return "admin_jobs"
}