package smdl import ( "admin/apps/game/domain/entity" "admin/apps/game/domain/projects/smdl/internal" "admin/apps/game/model" "admin/apps/game/model/dto" "admin/internal/errcode" "admin/lib/httpclient" "admin/lib/utils" "math" "net/url" "strconv" ) type AccountHook struct { } func (hook *AccountHook) List(projectInfo *entity.Project, resource string, params *dto.CommonListReq, fields []*dto.CommonDtoFieldDesc, totalCount int, rows []dto.CommonDtoValues) ( int, []*dto.CommonDtoFieldDesc, []dto.CommonDtoValues, error) { alisrvAddr := projectInfo.GetApiAddr() if alisrvAddr == "" { return 0, nil, nil, errcode.New(errcode.ServerError, "项目%v没有配置api服务器地址", projectInfo.Po.Name) } serverList, err := getAllRunningServers(projectInfo) if err != nil { return 0, nil, nil, err } totalCount, reqPageServerList, err := getPaginationServerReqList(projectInfo, serverList, params, func(info *internal.ServerInfo) int { return info.TotalAccountCount }) if err != nil { return 0, nil, nil, err } // {"data":[{"account":"20250425cs01","roleList":[{"account":"20250425cs01","createAt":1745567667525,"latestLoginAt":1745567714234,"roleId":"20001000001","serverId":"20001"}],"serverId":"20001"}], // "state":{"code":2000000,"msg":"OK"}} type RspData struct { State struct { Code int `json:"code"` Msg string `json:"msg"` } `json:"state"` Data []struct { Account string `json:"account"` ServerId string `json:"serverId"` RoleList []*Role `json:"roleList"` } `json:"data"` } body := &url.Values{} for _, cond := range params.ParsedWhereConditions.Conditions { if cond.Key == "Account" { // 按账号查询 body.Set("userId", cond.Value1.(string)) break } } for _, reqServer := range reqPageServerList { body.Set("serverid", reqServer.RawInfo.ServerId) body.Set("offset", strconv.Itoa(reqServer.Offset)) body.Set("count", strconv.Itoa(reqServer.Count)) body.Set("userlist", "true") rsp := &RspData{} err := httpclient.Request(alisrvAddr+"/rolelist", "get", body, rsp) if err != nil { return 0, nil, nil, err } for _, user := range rsp.Data { userPo := &model.Account{ Account: user.Account, ServerConfId: user.ServerId, } latestLoginTime := int64(0) earliestCreateTime := int64(math.MaxInt64) for _, v := range user.RoleList { userPo.RoleIds = append(userPo.RoleIds, v.RoleId) if latestLoginTime < v.LatestLoginTime { latestLoginTime = v.LatestLoginTime } if earliestCreateTime > v.CreateTime { earliestCreateTime = v.CreateTime } } userPo.LatestLoginTime = utils.ParseUnixTimestamp2LocalTime(latestLoginTime) userPo.CreatedAt = utils.ParseUnixTimestamp2LocalTime(earliestCreateTime) et := (&entity.CommonResource{}).FromPo(userPo) rows = append(rows, et.ToCommonDto()) } } return totalCount, fields, rows, nil } func (hook *AccountHook) GetDetail(projectInfo *entity.Project, account string) (*dto.GetAccountDetailRsp, error) { accountId := account if accountId == "" { return nil, errcode.New(errcode.ParamsInvalid, "not found account id:%v", accountId) } rsp := &dto.GetAccountDetailRsp{ AccountInfo: &dto.AccountDetailInfo{}, } params := &url.Values{} allRunningServers, err := getAllRunningServers(projectInfo) if err != nil { return nil, err } roleList := make([]*dto.AccountDetailRoleInfo, 0) for _, runningServer := range allRunningServers { params.Set("serverid", runningServer.ServerId) params.Set("userId", accountId) params.Set("userlist", "true") type RspData struct { State struct { Code int `json:"code"` Msg string `json:"msg"` } `json:"state"` Data *dto.AccountDetailInfo `json:"data"` } detailRsp := &RspData{} err := httpclient.Request(projectInfo.GetApiAddr()+"/rolelist", "get", params, detailRsp) if err != nil { return nil, err } if detailRsp.Data == nil { continue } rsp.AccountInfo = detailRsp.Data roleList = append(roleList, detailRsp.Data.RoleList...) } rsp.AccountInfo.RoleCount = len(roleList) rsp.AccountInfo.RoleList = roleList return rsp, nil } func getPaginationServerReqList(projectInfo *entity.Project, serverInfoList internal.ServerInfoList, params *dto.CommonListReq, queryCountField func(*internal.ServerInfo) int) ( totalCount int, reqServerInfoList []*internal.PageServerCountInfo, err error) { pageNo := params.PageNo pageLen := params.PageLen reqServerList := make([]*internal.PageServerCountInfo, 0) if specServerId, serverInfo, find := findWhereConditionSpecServer(params.ParsedWhereConditions.Conditions, serverInfoList); find { if serverInfo == nil { logServerList := make([]string, 0, len(serverInfoList)) for _, s := range serverInfoList { logServerList = append(logServerList, s.ServerId) } return 0, nil, errcode.New(errcode.GameServerNotRunning, "运行的区服列表(%+v)中没有指定的区服(%v)", logServerList, specServerId) } // 前端检索条件指定了区服 totalCount = queryCountField(serverInfo) offset := (pageNo - 1) * pageLen limit := pageLen reqServerList = append(reqServerList, &internal.PageServerCountInfo{ RawInfo: serverInfo, Offset: offset, Count: limit, }) } else { // 根据分页参数计算需要几个区服数据参与查询 totalCountTmp, tidyPageInfoList := serverInfoList.TidyToPageList(pageLen, queryCountField) if len(tidyPageInfoList) == 0 { // 没有找到分页信息,返回空表 return 0, nil, nil } totalCount = totalCountTmp for i, tidyPageInfo := range tidyPageInfoList { if i+1 == pageNo { reqServerList = append(reqServerList, tidyPageInfo.ServerList...) break } } } return totalCount, reqServerList, nil } func findWhereConditionSpecServer(whereConditions []*dto.GetWhereCondition, serverInfoList internal.ServerInfoList) (string, *internal.ServerInfo, bool) { if len(whereConditions) > 1 { // 第一个是ProjectId条件 for _, cond := range whereConditions { if cond.Key == "ServerConfId" { specServerId := cond.Value1.(string) // 前端指定了查询某个区服的数据 for _, v := range serverInfoList { if v.ServerId == specServerId { return v.ServerId, v, true } } return specServerId, nil, true } } } return "", nil, false }