2026-07-09 18:15:57 +08:00

280 lines
9.8 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 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"`
}