package model const ( UserStatusActive = "active" UserStatusLocked = "locked" UserStatusDisabled = "disabled" TeamProductResearchID uint = 1 TeamOperationsID uint = 2 JobStatusPending = "pending" JobStatusRunning = "running" JobStatusSucceeded = "succeeded" JobStatusFailed = "failed" JobStatusCanceled = "canceled" FinanceApplicationStatusPending = "pending" FinanceApplicationStatusApproved = "approved" FinanceApplicationStatusRejected = "rejected" WithdrawalApplicationStatusPending = "pending" WithdrawalApplicationStatusApproved = "approved" WithdrawalApplicationStatusRejected = "rejected" ) 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"` TeamID *uint `gorm:"column:team_id;index" json:"teamId"` TeamRecord Team `gorm:"foreignKey:TeamID;references:ID" json:"-"` 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 Team struct { ID uint `gorm:"primaryKey" json:"id"` ParentID *uint `gorm:"column:parent_id;index" json:"parentId"` Parent *Team `gorm:"foreignKey:ParentID;references:ID" json:"-"` Name string `gorm:"size:80;uniqueIndex;not null" json:"name"` Description string `gorm:"size:255" json:"description"` Sort int `gorm:"not null;default:0" json:"sort"` ParentName string `gorm:"column:parent_name;->;-:migration" json:"parentName,omitempty"` UserCount int64 `gorm:"column:user_count;->;-:migration" json:"userCount"` CreatedAtMS int64 `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"` UpdatedAtMS int64 `gorm:"column:updated_at_ms;autoUpdateTime:milli" json:"updatedAtMs"` } func (Team) TableName() string { return "admin_teams" } 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 AppSplashScreen struct { ID uint `gorm:"primaryKey" json:"id"` AppCode string `gorm:"size:32;index:idx_admin_app_splash_screens_app_sort,not null;default:lalu" json:"appCode"` CoverURL string `gorm:"size:1024;not null" json:"coverUrl"` SplashType string `gorm:"size:16;not null" json:"splashType"` Param string `gorm:"size:2048" json:"param"` Status string `gorm:"size:24;index:idx_admin_app_splash_screens_app_sort,not null;default:active" json:"status"` Platform string `gorm:"size:24;index:idx_admin_app_splash_screens_scope,not null" json:"platform"` SortOrder int `gorm:"index:idx_admin_app_splash_screens_app_sort,not null;default:0" json:"sortOrder"` RegionID int64 `gorm:"index:idx_admin_app_splash_screens_scope,not null;default:0" json:"regionId"` CountryCode string `gorm:"size:8;index:idx_admin_app_splash_screens_scope" json:"countryCode"` Description string `gorm:"size:255" json:"description"` DisplayDurationMS int `gorm:"column:display_duration_ms;not null;default:3000;comment:开屏展示时长,毫秒;0 表示客户端默认值" json:"displayDurationMs"` 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 (AppSplashScreen) TableName() string { return "admin_app_splash_screens" } type AppPopup struct { ID uint `gorm:"primaryKey" json:"id"` AppCode string `gorm:"size:32;not null;default:lalu;index:idx_admin_app_popups_app_sort;uniqueIndex:uk_admin_app_popups_code" json:"appCode"` Code string `gorm:"size:80;not null;uniqueIndex:uk_admin_app_popups_code;comment:弹窗编码" json:"code"` Name string `gorm:"size:80;not null;comment:弹窗名称" json:"name"` ImageURL string `gorm:"column:image_url;size:1024;not null;default:'';comment:弹窗图片 URL,可为空" json:"imageUrl"` JumpType string `gorm:"size:16;not null;comment:跳转类型,h5 或 app" json:"jumpType"` JumpURL string `gorm:"column:jump_url;size:2048;not null;default:'';comment:跳转地址" json:"jumpUrl"` DisplayPeriodDays int `gorm:"column:display_period_days;not null;default:0;comment:展示周期天数,0 表示每次打开都展示" json:"displayPeriodDays"` Status string `gorm:"size:24;index:idx_admin_app_popups_app_sort,not null;default:active" json:"status"` SortOrder int `gorm:"index:idx_admin_app_popups_app_sort,not null;default:0" json:"sortOrder"` 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 (AppPopup) TableName() string { return "admin_app_popups" } 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 UserMoneyScope struct { ID uint `gorm:"primaryKey" json:"id"` UserID uint `gorm:"index:idx_admin_user_money_scopes_user;index:uk_admin_user_money_scope,unique;not null" json:"userId"` AppCode string `gorm:"size:32;index:idx_admin_user_money_scopes_app_region;index:uk_admin_user_money_scope,unique;not null" json:"appCode"` RegionID int64 `gorm:"index:idx_admin_user_money_scopes_app_region;index:uk_admin_user_money_scope,unique;not null;default:0" json:"regionId"` CreatedAtMS int64 `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"` UpdatedAtMS int64 `gorm:"column:updated_at_ms;autoUpdateTime:milli" json:"updatedAtMs"` } func (UserMoneyScope) TableName() string { return "admin_user_money_scopes" } // DatabiKpiTarget 是社交 BI 里运营人员按 App×区域×月份 的充值 KPI 目标; // 实际达成从统计链路实时聚合,目标只在 admin 库维护,不回写任何业务库。 type DatabiKpiTarget struct { ID uint `gorm:"primaryKey" json:"id"` UserID uint `gorm:"index:uk_admin_databi_kpi_target,unique;not null" json:"userId"` AppCode string `gorm:"size:32;index:uk_admin_databi_kpi_target,unique;not null" json:"appCode"` RegionID int64 `gorm:"index:uk_admin_databi_kpi_target,unique;not null;default:0" json:"regionId"` PeriodMonth string `gorm:"size:7;column:period_month;index:uk_admin_databi_kpi_target,unique;index:idx_admin_databi_kpi_targets_period;not null" json:"periodMonth"` TargetUSDMinor int64 `gorm:"column:target_usd_minor;not null;default:0" json:"targetUsdMinor"` DailyTargetUSDMinor int64 `gorm:"column:daily_target_usd_minor;not null;default:0" json:"dailyTargetUsdMinor"` CreatedAtMS int64 `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"` UpdatedAtMS int64 `gorm:"column:updated_at_ms;autoUpdateTime:milli" json:"updatedAtMs"` } func (DatabiKpiTarget) TableName() string { return "admin_databi_kpi_targets" } // DatabiAppKpiTarget 是 App 级充值 KPI 月度目标:不分运营的全员共同目标。 type DatabiAppKpiTarget struct { ID uint `gorm:"primaryKey" json:"id"` AppCode string `gorm:"size:32;index:uk_admin_databi_app_kpi_target,unique;not null" json:"appCode"` PeriodMonth string `gorm:"size:7;column:period_month;index:uk_admin_databi_app_kpi_target,unique;not null" json:"periodMonth"` TargetUSDMinor int64 `gorm:"column:target_usd_minor;not null;default:0" json:"targetUsdMinor"` DailyTargetUSDMinor int64 `gorm:"column:daily_target_usd_minor;not null;default:0" json:"dailyTargetUsdMinor"` CreatedAtMS int64 `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"` UpdatedAtMS int64 `gorm:"column:updated_at_ms;autoUpdateTime:milli" json:"updatedAtMs"` } func (DatabiAppKpiTarget) TableName() string { return "admin_databi_app_kpi_targets" } type TemporaryPaymentLinkOwner struct { AppCode string `gorm:"size:32;primaryKey" json:"appCode"` OrderID string `gorm:"size:96;primaryKey" json:"orderId"` AdminUserID uint `gorm:"index:idx_admin_temporary_payment_link_owners_user;not null" json:"adminUserId"` RegionID int64 `gorm:"index:idx_admin_temporary_payment_link_owners_region;not null" json:"regionId"` CreatedAtMS int64 `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"` UpdatedAtMS int64 `gorm:"column:updated_at_ms;autoUpdateTime:milli" json:"updatedAtMs"` } func (TemporaryPaymentLinkOwner) TableName() string { return "admin_temporary_payment_link_owners" } // LegacyGooglePaidDetail 缓存 legacy App(Yumi/Aslan)谷歌账单经 Play Orders API 同步的实付明细; // legacy 平台的 Mongo 对 admin 只读,实付事实只能落在 admin 自己的库里,按账单交易号回填展示。 type LegacyGooglePaidDetail struct { AppCode string `gorm:"size:32;primaryKey;index:idx_legacy_google_paid_bill_time,priority:1" json:"appCode"` TransactionID string `gorm:"size:96;primaryKey;column:transaction_id" json:"transactionId"` ProviderOrderID string `gorm:"size:128;not null;default:''" json:"providerOrderId"` PaidCurrencyCode string `gorm:"size:8;not null;default:''" json:"paidCurrencyCode"` PaidAmountMicro int64 `gorm:"not null;default:0" json:"paidAmountMicro"` PaidTaxMicro int64 `gorm:"not null;default:0" json:"paidTaxMicro"` PaidNetMicro int64 `gorm:"not null;default:0" json:"paidNetMicro"` // BillUSDMinor/BillCreatedAtMS 是同步时从 legacy 账单带过来的快照,让概览统计不用再回查 Mongo。 BillUSDMinor int64 `gorm:"column:bill_usd_minor;not null;default:0" json:"billUsdMinor"` BillCreatedAtMS int64 `gorm:"column:bill_created_at_ms;not null;default:0;index:idx_legacy_google_paid_bill_time,priority:2" json:"billCreatedAtMs"` SyncedAtMS int64 `gorm:"column:synced_at_ms;not null" json:"syncedAtMs"` CreatedAtMS int64 `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"` UpdatedAtMS int64 `gorm:"column:updated_at_ms;autoUpdateTime:milli" json:"updatedAtMs"` } func (LegacyGooglePaidDetail) TableName() string { return "admin_legacy_google_paid_details" } type FinanceApplication struct { ID uint `gorm:"primaryKey" json:"id"` AppCode string `gorm:"size:32;index:idx_admin_finance_app_app_status;not null" json:"appCode"` Operation string `gorm:"size:64;index:idx_admin_finance_app_operation;not null" json:"operation"` WalletIdentity string `gorm:"size:32;not null;default:''" json:"walletIdentity"` TargetUserID string `gorm:"size:64;index:idx_admin_finance_app_target;not null" json:"targetUserId"` CoinAmount int64 `gorm:"not null;default:0" json:"coinAmount"` RechargeAmount string `gorm:"type:decimal(18,2);not null;default:0.00" json:"rechargeAmount"` CredentialImageURL string `gorm:"size:1024;not null;default:''" json:"credentialImageUrl"` CredentialText string `gorm:"type:text" json:"credentialText"` ApplicantUserID uint `gorm:"index:idx_admin_finance_app_applicant;not null" json:"applicantUserId"` ApplicantName string `gorm:"size:64;not null;default:''" json:"applicantName"` AuditorUserID *uint `gorm:"index:idx_admin_finance_app_auditor" json:"auditorUserId"` AuditorName string `gorm:"size:64;not null;default:''" json:"auditorName"` Status string `gorm:"size:32;index:idx_admin_finance_app_app_status;not null;default:pending" json:"status"` AuditRemark string `gorm:"type:text" json:"auditRemark"` AuditedAtMS *int64 `gorm:"column:audited_at_ms" json:"auditedAtMs"` WalletCommandID string `gorm:"size:128;not null;default:''" json:"walletCommandId"` WalletTransactionID string `gorm:"size:128;not null;default:''" json:"walletTransactionId"` WalletAssetType string `gorm:"size:64;not null;default:''" json:"walletAssetType"` WalletAmountDelta int64 `gorm:"not null;default:0" json:"walletAmountDelta"` WalletBalanceAfter int64 `gorm:"not null;default:0" json:"walletBalanceAfter"` CreatedAtMS int64 `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"` UpdatedAtMS int64 `gorm:"column:updated_at_ms;autoUpdateTime:milli" json:"updatedAtMs"` } func (FinanceApplication) TableName() string { return "admin_finance_applications" } type UserWithdrawalApplication struct { ID uint `gorm:"primaryKey" json:"id"` AppCode string `gorm:"size:32;index:idx_admin_withdrawal_app_status_time;not null" json:"appCode"` UserID string `gorm:"size:64;index:idx_admin_withdrawal_user;not null" json:"userId"` SalaryAssetType string `gorm:"size:64;not null;default:''" json:"salaryAssetType"` WithdrawAmount string `gorm:"type:decimal(18,2);not null;default:0.00" json:"withdrawAmount"` WithdrawAmountMinor int64 `gorm:"not null;default:0" json:"withdrawAmountMinor"` WithdrawMethod string `gorm:"size:64;index:idx_admin_withdrawal_method;not null;default:''" json:"withdrawMethod"` WithdrawAddress string `gorm:"size:255;not null;default:''" json:"withdrawAddress"` FreezeCommandID string `gorm:"size:128;not null;default:''" json:"freezeCommandId"` FreezeTransactionID string `gorm:"size:128;not null;default:''" json:"freezeTransactionId"` AuditCommandID string `gorm:"size:128;not null;default:''" json:"auditCommandId"` AuditTransactionID string `gorm:"size:128;not null;default:''" json:"auditTransactionId"` Status string `gorm:"size:32;index:idx_admin_withdrawal_app_status_time;not null;default:pending" json:"status"` ApproverUserID *uint `gorm:"index:idx_admin_withdrawal_approver" json:"approverUserId"` ApproverName string `gorm:"size:64;not null;default:''" json:"approverName"` AuditRemark string `gorm:"type:text" json:"auditRemark"` AuditImageURL string `gorm:"column:audit_image_url;size:1024;not null;default:''" json:"auditImageUrl"` ApprovedAtMS *int64 `gorm:"column:approved_at_ms" json:"approvedAtMs"` CreatedAtMS int64 `gorm:"column:created_at_ms;autoCreateTime:milli;index:idx_admin_withdrawal_app_status_time" json:"createdAtMs"` UpdatedAtMS int64 `gorm:"column:updated_at_ms;autoUpdateTime:milli" json:"updatedAtMs"` } func (UserWithdrawalApplication) TableName() string { return "admin_user_withdrawal_applications" } 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" }