package hostorg import ( "encoding/json" "fmt" "strconv" "strings" "hyapp-admin-server/internal/modules/shared" ) // flexibleInt64 只用于 admin HTTP 请求入参:前端新合约会按字符串提交用户长 ID,旧页面或脚本可能仍提交 JSON number。 // 这里同时接受两种形态,进入业务层前仍落成 int64,保证后续短 ID 解析、RPC 参数和审计日志不出现两套类型分支。 type flexibleInt64 int64 func (v *flexibleInt64) UnmarshalJSON(data []byte) error { raw := strings.TrimSpace(string(data)) if raw == "" || raw == "null" { *v = 0 return nil } if strings.HasPrefix(raw, `"`) { var text string if err := json.Unmarshal(data, &text); err != nil { return err } raw = strings.TrimSpace(text) if raw == "" { *v = 0 return nil } } parsed, err := strconv.ParseInt(raw, 10, 64) if err != nil { return fmt.Errorf("invalid int64 id %q", raw) } *v = flexibleInt64(parsed) return nil } func (v flexibleInt64) Int64() int64 { return int64(v) } type listQuery struct { Page int PageSize int Keyword string UserFilter shared.UserIdentityFilter OwnerFilter shared.UserIdentityFilter ParentLeaderFilter shared.UserIdentityFilter ParentBDFilter shared.UserIdentityFilter Status string RegionID int64 AgencyID int64 ParentBDUserID int64 ParentLeaderUserID int64 ParentUserID int64 TargetUserID int64 SortBy string SortDirection string } type createBDLeaderRequest struct { CommandID string `json:"commandId" binding:"required"` TargetUserID flexibleInt64 `json:"targetUserId" binding:"required"` PositionAlias string `json:"positionAlias"` Reason string `json:"reason"` } type createManagerRequest struct { Contact string `json:"contact"` TargetUserID flexibleInt64 `json:"targetUserId" binding:"required"` CanGrantAvatarFrame *bool `json:"canGrantAvatarFrame"` CanGrantVehicle *bool `json:"canGrantVehicle"` CanGrantBadge *bool `json:"canGrantBadge"` CanGrantVIP *bool `json:"canGrantVip"` CanUpdateUserLevel *bool `json:"canUpdateUserLevel"` CanAddBDLeader *bool `json:"canAddBdLeader"` CanAddAdmin *bool `json:"canAddAdmin"` CanAddSuperadmin *bool `json:"canAddSuperadmin"` CanBlockUser *bool `json:"canBlockUser"` CanTransferCountry *bool `json:"canTransferUserCountry"` } type updateManagerRequest struct { Contact *string `json:"contact"` Status *string `json:"status"` CanGrantAvatarFrame *bool `json:"canGrantAvatarFrame"` CanGrantVehicle *bool `json:"canGrantVehicle"` CanGrantBadge *bool `json:"canGrantBadge"` CanGrantVIP *bool `json:"canGrantVip"` CanUpdateUserLevel *bool `json:"canUpdateUserLevel"` CanAddBDLeader *bool `json:"canAddBdLeader"` CanAddAdmin *bool `json:"canAddAdmin"` CanAddSuperadmin *bool `json:"canAddSuperadmin"` CanBlockUser *bool `json:"canBlockUser"` CanTransferCountry *bool `json:"canTransferUserCountry"` } func (r updateManagerRequest) appendStatusAssignment(assignments *[]string, args *[]any) error { if r.Status == nil { return nil } status := strings.ToLower(strings.TrimSpace(*r.Status)) if status == "" { return nil } if status != "active" && status != "disabled" { return fmt.Errorf("manager status is invalid") } // 经理状态属于 manager_profiles 自身身份开关;停用经理只关闭经理中心身份,不改用户主状态或其他 Host/BD 关系。 *assignments = append(*assignments, "status = ?") *args = append(*args, status) return nil } type managerPermissions struct { CanGrantAvatarFrame bool CanGrantVehicle bool CanGrantBadge bool CanGrantVIP bool CanUpdateUserLevel bool CanAddBDLeader bool CanAddAdmin bool CanAddSuperadmin bool CanBlockUser bool CanTransferCountry bool } func (r createManagerRequest) permissionsWithDefault() managerPermissions { return managerPermissions{ CanGrantAvatarFrame: boolDefaultTrue(r.CanGrantAvatarFrame), CanGrantVehicle: boolDefaultTrue(r.CanGrantVehicle), CanGrantBadge: boolDefaultTrue(r.CanGrantBadge), CanGrantVIP: boolDefaultTrue(r.CanGrantVIP), CanUpdateUserLevel: boolDefaultTrue(r.CanUpdateUserLevel), CanAddBDLeader: boolDefaultTrue(r.CanAddBDLeader), CanAddAdmin: boolDefaultTrue(r.CanAddAdmin), CanAddSuperadmin: boolDefaultTrue(r.CanAddSuperadmin), CanBlockUser: boolDefaultTrue(r.CanBlockUser), CanTransferCountry: boolDefaultTrue(r.CanTransferCountry), } } func (r updateManagerRequest) appendPermissionAssignments(assignments *[]string, args *[]any) { appendBoolAssignment(assignments, args, "can_grant_avatar_frame", r.CanGrantAvatarFrame) appendBoolAssignment(assignments, args, "can_grant_vehicle", r.CanGrantVehicle) appendBoolAssignment(assignments, args, "can_grant_badge", r.CanGrantBadge) appendBoolAssignment(assignments, args, "can_grant_vip", r.CanGrantVIP) appendBoolAssignment(assignments, args, "can_update_user_level", r.CanUpdateUserLevel) appendBoolAssignment(assignments, args, "can_add_bd_leader", r.CanAddBDLeader) appendBoolAssignment(assignments, args, "can_add_admin", r.CanAddAdmin) appendBoolAssignment(assignments, args, "can_add_superadmin", r.CanAddSuperadmin) appendBoolAssignment(assignments, args, "can_block_user", r.CanBlockUser) appendBoolAssignment(assignments, args, "can_transfer_user_country", r.CanTransferCountry) } func appendBoolAssignment(assignments *[]string, args *[]any, column string, value *bool) { if value == nil { return } *assignments = append(*assignments, column+" = ?") *args = append(*args, *value) } func boolDefaultTrue(value *bool) bool { return value == nil || *value } type createBDRequest struct { CommandID string `json:"commandId" binding:"required"` TargetUserID flexibleInt64 `json:"targetUserId" binding:"required"` ParentLeaderUserID flexibleInt64 `json:"parentLeaderUserId"` Reason string `json:"reason"` } type bdStatusRequest struct { CommandID string `json:"commandId" binding:"required"` Status string `json:"status" binding:"required"` Reason string `json:"reason"` } type bdLeaderPositionAliasRequest struct { CommandID string `json:"commandId" binding:"required"` PositionAlias string `json:"positionAlias"` Reason string `json:"reason"` } type createCoinSellerRequest struct { CommandID string `json:"commandId" binding:"required"` Contact string `json:"contact"` TargetUserID flexibleInt64 `json:"targetUserId" binding:"required"` Reason string `json:"reason"` CanManageSubCoinSellers *bool `json:"canManageSubCoinSellers"` } type coinSellerStatusRequest struct { CommandID string `json:"commandId" binding:"required"` Contact *string `json:"contact"` Status string `json:"status" binding:"required"` Reason string `json:"reason"` CanManageSubCoinSellers *bool `json:"canManageSubCoinSellers"` } type coinSellerSubApplicationReviewRequest struct { CommandID string `json:"commandId" binding:"required"` Reason string `json:"reason"` } type coinSellerStockCreditRequest struct { CommandID string `json:"commandId" binding:"required"` Type string `json:"type" binding:"required"` CoinAmount int64 `json:"coinAmount" binding:"required"` RechargeAmount string `json:"rechargeAmount"` PaymentRef string `json:"paymentRef"` EvidenceRef string `json:"evidenceRef"` Reason string `json:"reason"` } type coinSellerStockDebitRequest struct { CommandID string `json:"commandId" binding:"required"` CoinAmount int64 `json:"coinAmount" binding:"required"` RechargeAmount string `json:"rechargeAmount" binding:"required"` EvidenceRef string `json:"evidenceRef"` Reason string `json:"reason" binding:"required"` } type replaceCoinSellerSalaryRatesRequest struct { Tiers []coinSellerSalaryRateTierRequest `json:"tiers" binding:"required"` } type coinSellerSalaryRateTierRequest struct { MinUSD string `json:"minUsd"` MaxUSD string `json:"maxUsd"` MinUSDMinor int64 `json:"minUsdMinor"` MaxUSDMinor int64 `json:"maxUsdMinor"` CoinPerUSD int64 `json:"coinPerUsd" binding:"required"` Enabled *bool `json:"enabled"` Status string `json:"status"` SortOrder int `json:"sortOrder"` } type createAgencyRequest struct { CommandID string `json:"commandId" binding:"required"` OwnerUserID flexibleInt64 `json:"ownerUserId" binding:"required"` ParentBDUserID flexibleInt64 `json:"parentBdUserId"` Name string `json:"name"` JoinEnabled *bool `json:"joinEnabled" binding:"required"` Reason string `json:"reason"` } type agencyHostAddRequest struct { CommandID string `json:"commandId" binding:"required"` TargetUserID flexibleInt64 `json:"targetUserId" binding:"required"` Reason string `json:"reason"` } type agencyJoinEnabledRequest struct { CommandID string `json:"commandId" binding:"required"` JoinEnabled *bool `json:"joinEnabled" binding:"required"` Reason string `json:"reason"` } type agencyCloseRequest struct { CommandID string `json:"commandId" binding:"required"` Reason string `json:"reason"` } type agencyStatusRequest struct { CommandID string `json:"commandId" binding:"required"` Status string `json:"status" binding:"required"` Reason string `json:"reason"` } type agencyDeleteRequest struct { CommandID string `json:"commandId" binding:"required"` Reason string `json:"reason"` }