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 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 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"` }