package analysisadminlogic import ( "context" "strconv" "lone-services/pkg/modelbase" "lone-services/pkg/utils" "lone-services/pkg/validate" analysis "lone-services/rpc/analysis/pb" userpb "lone-services/rpc/user/pb" "lone-services/services/analysis/internal/dao" "lone-services/services/analysis/internal/logic/common" "lone-services/services/analysis/internal/model" "lone-services/services/analysis/internal/svc" "lone-services/services/analysis/validator" "github.com/zeromicro/go-zero/core/logx" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) type ScanListLogic struct { ctx context.Context svcCtx *svc.ServiceContext logx.Logger } func NewScanListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ScanListLogic { return &ScanListLogic{ ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx), } } func (l *ScanListLogic) ScanList(in *analysis.AdminScanListReq) (*analysis.Response, error) { var req validator.AdminScanListValidator if msg := validate.ValidateFromProto(in, &req); msg != utils.StringEmpty { return outParams(msg), nil } if _, fail := common.RequireAdmin(l.ctx); fail != nil { return fail, nil } params := modelbase.Params{ Eq: map[string]string{ "status": strconv.Itoa(utils.StatusOk), }, Order: "id desc", Page: int(req.Page), Size: int(req.Size), } if req.State > utils.NumberZero { params.Eq["state"] = strconv.Itoa(int(req.State)) } if req.Keyword != utils.StringEmpty { bizIds, err := l.filterBizIds(req.Keyword) if err != nil { l.Errorf("admin scan list filter: %v", err) return common.FailResponse(utils.Fail), nil } if len(bizIds) == utils.NumberZero { return common.OkResponse(modelbase.PageResult{Items: []dao.AdminScanListItem{}}), nil } params.In = map[string][]string{"user_id": idStrings(bizIds)} } var logs []dao.UserImageLog page, err := model.UserImageLogModel{}.Init().Page(params, &logs) if err != nil { l.Errorf("admin scan list page: %v", err) return common.FailResponse(utils.Fail), nil } if len(logs) == utils.NumberZero { page.Items = []dao.AdminScanListItem{} return common.OkResponse(page), nil } userIds := make([]int64, 0, len(logs)) seen := make(map[int64]struct{}, len(logs)) for _, row := range logs { if row.UserId < utils.NumberOne { continue } if _, ok := seen[row.UserId]; ok { continue } seen[row.UserId] = struct{}{} userIds = append(userIds, row.UserId) } profiles, err := l.loadProfiles(userIds) if err != nil { l.Errorf("admin scan list profiles: %v", err) return common.FailResponse(utils.Fail), nil } users, err := loadAnalysisUsers(userIds) if err != nil { l.Errorf("admin scan list users: %v", err) return common.FailResponse(utils.Fail), nil } items := make([]dao.AdminScanListItem, 0, len(logs)) for _, row := range logs { item := dao.AdminScanListItem{ Id: row.Id, UserId: row.UserId, DetectionNumber: row.DetectionNumber, DetectionTime: row.DetectionTime.String(), State: int(row.State), GenderText: formatGender(utils.NumberZero), } if user, ok := users[row.UserId]; ok { item.CreatedAt = user.CreatedAt.String() } if profile, ok := profiles[row.UserId]; ok { name := profile.GetName() item.Username = name item.Nickname = name mobile, _ := utils.DecryptPhone(profile.GetMobile()) item.Mobile = mobile item.Gender = int(profile.GetGender()) item.GenderText = formatGender(profile.GetGender()) item.BirthdayText = utils.CalcAgeStr(profile.GetBirthday()) } items = append(items, item) } page.Items = items return common.OkResponse(page), nil } func (l *ScanListLogic) filterBizIds(keyword string) ([]int64, error) { if l.svcCtx.UserSvcName == utils.StringEmpty { return nil, status.Error(codes.FailedPrecondition, "user service empty") } cli, err := svc.GetRpcClient(l.svcCtx.UserSvcName) if err != nil { return nil, err } res, err := userpb.NewUserClient(cli.Conn()).InternalUsersByBiz(l.ctx, &userpb.InternalUsersByBizReq{ ClientCode: dao.ClientCodeUserSkin, Keyword: keyword, }) if err != nil { return nil, err } ids := make([]int64, 0, len(res.GetItems())) for _, item := range res.GetItems() { if item.GetBizId() > utils.NumberZero { ids = append(ids, item.GetBizId()) } } return ids, nil } func (l *ScanListLogic) loadProfiles(bizIds []int64) (map[int64]*userpb.BizUserItem, error) { out := make(map[int64]*userpb.BizUserItem, len(bizIds)) if len(bizIds) == utils.NumberZero { return out, nil } if l.svcCtx.UserSvcName == utils.StringEmpty { return nil, status.Error(codes.FailedPrecondition, "user service empty") } cli, err := svc.GetRpcClient(l.svcCtx.UserSvcName) if err != nil { return nil, err } res, err := userpb.NewUserClient(cli.Conn()).InternalUsersByBiz(l.ctx, &userpb.InternalUsersByBizReq{ ClientCode: dao.ClientCodeUserSkin, BizIds: bizIds, }) if err != nil { return nil, err } for _, item := range res.GetItems() { out[item.GetBizId()] = item } return out, nil } func loadAnalysisUsers(ids []int64) (map[int64]dao.User, error) { out := make(map[int64]dao.User, len(ids)) if len(ids) == utils.NumberZero { return out, nil } var rows []dao.User err := model.UserModel{}.Init().Items(modelbase.Params{ In: map[string][]string{"id": idStrings(ids)}, }, &rows) if err != nil { return nil, err } for _, row := range rows { out[row.Id] = row } return out, nil }