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