package admin_cms import ( "Open_IM/pkg/common/config" "Open_IM/pkg/common/constant" "Open_IM/pkg/common/log" promePkg "Open_IM/pkg/common/prometheus" "Open_IM/pkg/common/token_verify" "Open_IM/pkg/getcdv3" pbAdminCMS "Open_IM/pkg/proto/admin_cms" server_api_params "Open_IM/pkg/proto/sdk_ws" grpcPrometheus "github.com/grpc-ecosystem/go-grpc-prometheus" "Open_IM/pkg/utils" "context" "errors" "net" "strconv" "strings" "sync" "time" "google.golang.org/grpc" "gorm.io/gorm" ) type adminCMSServer struct { rpcPort int rpcRegisterName string etcdSchema string etcdAddr []string } func NewAdminCMSServer(port int) *adminCMSServer { log.NewPrivateLog(constant.LogFileName) return &adminCMSServer{ rpcPort: port, rpcRegisterName: config.Config.RpcRegisterName.OpenImAdminCMSName, etcdSchema: config.Config.Etcd.EtcdSchema, etcdAddr: config.Config.Etcd.EtcdAddr, } } func (s *adminCMSServer) Run() { log.NewInfo("0", "AdminCMS rpc start ") listenIP := "" if config.Config.ListenIP == "" { listenIP = "0.0.0.0" } else { listenIP = config.Config.ListenIP } address := listenIP + ":" + strconv.Itoa(s.rpcPort) //listener network listener, err := net.Listen("tcp", address) if err != nil { panic("listening err:" + err.Error() + s.rpcRegisterName) } log.NewInfo("0", "listen network success, ", address, listener) defer listener.Close() var grpcOpts []grpc.ServerOption if config.Config.Prometheus.Enable { promePkg.NewGrpcRequestCounter() promePkg.NewGrpcRequestFailedCounter() promePkg.NewGrpcRequestSuccessCounter() grpcOpts = append(grpcOpts, []grpc.ServerOption{ // grpc.UnaryInterceptor(promePkg.UnaryServerInterceptorProme), grpc.StreamInterceptor(grpcPrometheus.StreamServerInterceptor), grpc.UnaryInterceptor(grpcPrometheus.UnaryServerInterceptor), }...) } srv := grpc.NewServer(grpcOpts...) defer srv.GracefulStop() //Service registers with etcd pbAdminCMS.RegisterAdminCMSServer(srv, s) rpcRegisterIP := config.Config.RpcRegisterIP if config.Config.RpcRegisterIP == "" { rpcRegisterIP, err = utils.GetLocalIP() if err != nil { log.Error("", "GetLocalIP failed ", err.Error()) } } log.NewInfo("", "rpcRegisterIP ", rpcRegisterIP) err = getcdv3.RegisterEtcd(s.etcdSchema, strings.Join(s.etcdAddr, ","), rpcRegisterIP, s.rpcPort, s.rpcRegisterName, 10) if err != nil { log.NewError("0", "RegisterEtcd failed ", err.Error()) panic(utils.Wrap(err, "register admin module rpc to etcd err")) } err = srv.Serve(listener) if err != nil { log.NewError("0", "Serve failed ", err.Error()) return } log.NewInfo("0", "message cms rpc success") } func (s *adminCMSServer) AdminLogin(_ context.Context, req *pbAdminCMS.AdminLoginReq) (*pbAdminCMS.AdminLoginResp, error) { log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "req: ", req.String()) resp := &pbAdminCMS.AdminLoginResp{CommonResp: &pbAdminCMS.CommonResp{}} for i, adminID := range config.Config.Manager.AppManagerUid { if adminID == req.AdminID && config.Config.Manager.Secrets[i] == req.Secret { token, expTime, err := token_verify.CreateToken(adminID, constant.SingleChatType) if err != nil { log.NewError(req.OperationID, utils.GetSelfFuncName(), "generate token failed", "adminID: ", adminID, err.Error()) resp.CommonResp.ErrCode = constant.ErrTokenUnknown.ErrCode resp.CommonResp.ErrMsg = err.Error() return resp, nil } log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "generate token success", "token: ", token, "expTime:", expTime) resp.Token = token break } } if resp.Token == "" { log.NewError(req.OperationID, utils.GetSelfFuncName(), "failed") resp.CommonResp.ErrCode = constant.ErrTokenUnknown.ErrCode resp.CommonResp.ErrMsg = constant.ErrTokenMalformed.ErrMsg return resp, nil } admin, err := imdb.GetUserByUserID(req.AdminID) if err != nil { log.NewError(req.OperationID, utils.GetSelfFuncName(), "failed", req.AdminID, err.Error()) resp.CommonResp.ErrCode = constant.ErrTokenUnknown.ErrCode resp.CommonResp.ErrMsg = err.Error() return resp, nil } resp.UserName = admin.Nickname resp.FaceURL = admin.FaceURL log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "resp: ", resp.String()) return resp, nil } func (s *adminCMSServer) GetUserToken(_ context.Context, req *pbAdminCMS.GetUserTokenReq) (*pbAdminCMS.GetUserTokenResp, error) { log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "req: ", req.String()) resp := &pbAdminCMS.GetUserTokenResp{ CommonResp: &pbAdminCMS.CommonResp{}, } token, expTime, err := token_verify.CreateToken(req.UserID, int(req.PlatformID)) if err != nil { log.NewError(req.OperationID, utils.GetSelfFuncName(), "generate token failed", "userID: ", req.UserID, req.PlatformID, err.Error()) resp.CommonResp.ErrCode = constant.ErrTokenUnknown.ErrCode resp.CommonResp.ErrMsg = err.Error() return resp, nil } resp.Token = token resp.ExpTime = expTime log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "req: ", resp.String()) return resp, nil } func (s *adminCMSServer) AddUserRegisterAddFriendIDList(_ context.Context, req *pbAdminCMS.AddUserRegisterAddFriendIDListReq) (*pbAdminCMS.AddUserRegisterAddFriendIDListResp, error) { log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "req: ", req.String()) resp := &pbAdminCMS.AddUserRegisterAddFriendIDListResp{CommonResp: &pbAdminCMS.CommonResp{}} if err := imdb.AddUserRegisterAddFriendIDList(req.UserIDList...); err != nil { log.NewError(req.OperationID, utils.GetSelfFuncName(), err.Error(), req.UserIDList) resp.CommonResp.ErrCode = constant.ErrDB.ErrCode resp.CommonResp.ErrMsg = err.Error() return resp, nil } log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "resp: ", req.String()) return resp, nil } func (s *adminCMSServer) ReduceUserRegisterAddFriendIDList(_ context.Context, req *pbAdminCMS.ReduceUserRegisterAddFriendIDListReq) (*pbAdminCMS.ReduceUserRegisterAddFriendIDListResp, error) { log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "req: ", req.String()) resp := &pbAdminCMS.ReduceUserRegisterAddFriendIDListResp{CommonResp: &pbAdminCMS.CommonResp{}} if req.Operation == 0 { if err := imdb.ReduceUserRegisterAddFriendIDList(req.UserIDList...); err != nil { log.NewError(req.OperationID, utils.GetSelfFuncName(), err.Error(), req.UserIDList) resp.CommonResp.ErrCode = constant.ErrDB.ErrCode resp.CommonResp.ErrMsg = err.Error() return resp, nil } } else { if err := imdb.DeleteAllRegisterAddFriendIDList(); err != nil { log.NewError(req.OperationID, utils.GetSelfFuncName(), err.Error(), req.UserIDList) resp.CommonResp.ErrCode = constant.ErrDB.ErrCode resp.CommonResp.ErrMsg = err.Error() return resp, nil } } log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "resp: ", req.String()) return resp, nil } func (s *adminCMSServer) GetUserRegisterAddFriendIDList(_ context.Context, req *pbAdminCMS.GetUserRegisterAddFriendIDListReq) (*pbAdminCMS.GetUserRegisterAddFriendIDListResp, error) { log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "req: ", req.String()) resp := &pbAdminCMS.GetUserRegisterAddFriendIDListResp{CommonResp: &pbAdminCMS.CommonResp{}} userIDList, err := imdb.GetRegisterAddFriendList(req.Pagination.ShowNumber, req.Pagination.PageNumber) if err != nil { log.NewError(req.OperationID, utils.GetSelfFuncName(), err.Error()) resp.CommonResp.ErrCode = constant.ErrDB.ErrCode resp.CommonResp.ErrMsg = err.Error() return resp, nil } userList, err := imdb.GetUsersByUserIDList(userIDList) if err != nil { resp.CommonResp.ErrCode = constant.ErrDB.ErrCode resp.CommonResp.ErrMsg = err.Error() return resp, nil } log.NewDebug(req.OperationID, utils.GetSelfFuncName(), userList, userIDList) resp.Pagination = &server_api_params.ResponsePagination{ CurrentPage: req.Pagination.PageNumber, ShowNumber: req.Pagination.ShowNumber, } utils.CopyStructFields(&resp.UserInfoList, userList) log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "resp: ", req.String()) return resp, nil } func (s *adminCMSServer) GetChatLogs(_ context.Context, req *pbAdminCMS.GetChatLogsReq) (*pbAdminCMS.GetChatLogsResp, error) { log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "GetChatLogs", req.String()) resp := &pbAdminCMS.GetChatLogsResp{CommonResp: &pbAdminCMS.CommonResp{}, Pagination: &server_api_params.ResponsePagination{}} chatLog := imdb.ChatLog{ Content: req.Content, ContentType: req.ContentType, SessionType: req.SessionType, RecvID: req.RecvID, SendID: req.SendID, } if req.SendTime != "" { sendTime, err := utils.TimeStringToTime(req.SendTime) if err != nil { log.NewError(req.OperationID, utils.GetSelfFuncName(), "time string parse error", err.Error()) resp.CommonResp.ErrCode = constant.ErrArgs.ErrCode resp.CommonResp.ErrMsg = err.Error() return resp, nil } chatLog.SendTime = sendTime } log.NewDebug(req.OperationID, utils.GetSelfFuncName(), "chat_log: ", chatLog) num, chatLogs, err := imdb.GetChatLog(&chatLog, req.Pagination.PageNumber, req.Pagination.ShowNumber, []int32{ constant.Text, constant.Picture, constant.Voice, constant.Video, constant.File, constant.AtText, constant.Merger, constant.Card, constant.Location, constant.Custom, constant.Revoke, constant.Quote, constant.AdvancedText, constant.AdvancedRevoke, constant.CustomNotTriggerConversation, }) if err != nil { log.NewError(req.OperationID, utils.GetSelfFuncName(), "GetChatLog", err.Error()) resp.CommonResp.ErrCode = constant.ErrDB.ErrCode resp.CommonResp.ErrMsg = err.Error() return resp, nil } resp.ChatLogsNum = int32(num) for _, chatLog := range chatLogs { pbChatLog := &pbAdminCMS.ChatLog{} utils.CopyStructFields(pbChatLog, chatLog) pbChatLog.SendTime = chatLog.SendTime.Unix() pbChatLog.CreateTime = chatLog.CreateTime.Unix() if chatLog.SenderNickname == "" { sendUser, err := imdb.GetUserByUserID(chatLog.SendID) if err != nil { log.NewError(req.OperationID, utils.GetSelfFuncName(), "GetUserByUserID failed", err.Error()) continue } pbChatLog.SenderNickname = sendUser.Nickname } switch chatLog.SessionType { case constant.SingleChatType: recvUser, err := imdb.GetUserByUserID(chatLog.RecvID) if err != nil { log.NewError(req.OperationID, utils.GetSelfFuncName(), "GetUserByUserID failed", err.Error()) continue } pbChatLog.SenderNickname = recvUser.Nickname case constant.GroupChatType, constant.SuperGroupChatType: group, err := imdb.GetGroupInfoByGroupID(chatLog.RecvID) if err != nil { log.NewError(req.OperationID, utils.GetSelfFuncName(), "GetGroupById failed") continue } pbChatLog.RecvID = group.GroupID pbChatLog.GroupName = group.GroupName } resp.ChatLogs = append(resp.ChatLogs, pbChatLog) } resp.Pagination = &server_api_params.ResponsePagination{ CurrentPage: req.Pagination.PageNumber, ShowNumber: req.Pagination.ShowNumber, } log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "resp output: ", resp.String()) return resp, nil } func (s *adminCMSServer) GetActiveGroup(_ context.Context, req *pbAdminCMS.GetActiveGroupReq) (*pbAdminCMS.GetActiveGroupResp, error) { resp := &pbAdminCMS.GetActiveGroupResp{} fromTime, toTime, err := ParseTimeFromTo(req.StatisticsReq.From, req.StatisticsReq.To) if err != nil { return resp, err } activeGroups, err := imdb.GetActiveGroups(fromTime, toTime, 12) if err != nil { return resp, err } for _, activeGroup := range activeGroups { resp.Groups = append(resp.Groups, &pbAdminCMS.GroupResp{ GroupName: activeGroup.Name, GroupID: activeGroup.Id, MessageNum: int32(activeGroup.MessageNum), }) } return resp, nil } func (s *adminCMSServer) GetActiveUser(_ context.Context, req *pbAdminCMS.GetActiveUserReq) (*pbAdminCMS.GetActiveUserResp, error) { log.NewInfo(req.OperationID, utils.GetSelfFuncName(), req.String()) resp := &pbAdminCMS.GetActiveUserResp{CommonResp: &pbAdminCMS.CommonResp{}} fromTime, toTime, err := ParseTimeFromTo(req.StatisticsReq.From, req.StatisticsReq.To) if err != nil { log.NewError(req.OperationID, utils.GetSelfFuncName(), "ParseTimeFromTo failed", err.Error()) resp.CommonResp.ErrCode = constant.ErrDB.ErrCode resp.CommonResp.ErrMsg = err.Error() return resp, nil } log.NewDebug(req.OperationID, utils.GetSelfFuncName(), "time: ", fromTime, toTime) activeUsers, err := imdb.GetActiveUsers(fromTime, toTime, 12) if err != nil { log.NewError(req.OperationID, utils.GetSelfFuncName(), "GetActiveUsers failed", err.Error()) resp.CommonResp.ErrCode = constant.ErrDB.ErrCode resp.CommonResp.ErrMsg = err.Error() return resp, nil } for _, activeUser := range activeUsers { resp.Users = append(resp.Users, &pbAdminCMS.UserResp{ UserID: activeUser.ID, NickName: activeUser.Name, MessageNum: int32(activeUser.MessageNum), }, ) } log.NewInfo(req.OperationID, utils.GetSelfFuncName(), resp.String()) return resp, nil } func ParseTimeFromTo(from, to string) (time.Time, time.Time, error) { var fromTime time.Time var toTime time.Time fromTime, err := utils.TimeStringToTime(from) if err != nil { return fromTime, toTime, err } toTime, err = utils.TimeStringToTime(to) if err != nil { return fromTime, toTime, err } return fromTime, toTime, nil } func isInOneMonth(from, to time.Time) bool { return from.Month() == to.Month() && from.Year() == to.Year() } func GetRangeDate(from, to time.Time) [][2]time.Time { interval := to.Sub(from) var times [][2]time.Time switch { // today case interval == 0: times = append(times, [2]time.Time{ from, from.Add(time.Hour * 24), }) // days case isInOneMonth(from, to): for i := 0; ; i++ { fromTime := from.Add(time.Hour * 24 * time.Duration(i)) toTime := from.Add(time.Hour * 24 * time.Duration(i+1)) if toTime.After(to.Add(time.Hour * 24)) { break } times = append(times, [2]time.Time{ fromTime, toTime, }) } // month case !isInOneMonth(from, to): if to.Sub(from) < time.Hour*24*30 { for i := 0; ; i++ { fromTime := from.Add(time.Hour * 24 * time.Duration(i)) toTime := from.Add(time.Hour * 24 * time.Duration(i+1)) if toTime.After(to.Add(time.Hour * 24)) { break } times = append(times, [2]time.Time{ fromTime, toTime, }) } } else { for i := 0; ; i++ { if i == 0 { fromTime := from toTime := getFirstDateOfNextNMonth(fromTime, 1) times = append(times, [2]time.Time{ fromTime, toTime, }) } else { fromTime := getFirstDateOfNextNMonth(from, i) toTime := getFirstDateOfNextNMonth(fromTime, 1) if toTime.After(to) { toTime = to times = append(times, [2]time.Time{ fromTime, toTime, }) break } times = append(times, [2]time.Time{ fromTime, toTime, }) } } } } return times } func getFirstDateOfNextNMonth(currentTime time.Time, n int) time.Time { lastOfMonth := time.Date(currentTime.Year(), currentTime.Month(), 1, 0, 0, 0, 0, currentTime.Location()).AddDate(0, n, 0) return lastOfMonth } func (s *adminCMSServer) GetGroupStatistics(_ context.Context, req *pbAdminCMS.GetGroupStatisticsReq) (*pbAdminCMS.GetGroupStatisticsResp, error) { log.NewInfo(req.OperationID, utils.GetSelfFuncName(), req.String()) resp := &pbAdminCMS.GetGroupStatisticsResp{CommonResp: &pbAdminCMS.CommonResp{}} fromTime, toTime, err := ParseTimeFromTo(req.StatisticsReq.From, req.StatisticsReq.To) if err != nil { log.NewError(req.OperationID, utils.GetSelfFuncName(), "GetGroupStatistics failed", err.Error()) resp.CommonResp.ErrCode = constant.ErrDB.ErrCode resp.CommonResp.ErrMsg = err.Error() return resp, nil } increaseGroupNum, err := imdb.GetIncreaseGroupNum(fromTime, toTime.Add(time.Hour*24)) if err != nil { log.NewError(req.OperationID, utils.GetSelfFuncName(), "GetIncreaseGroupNum failed", err.Error(), fromTime, toTime) resp.CommonResp.ErrCode = constant.ErrDB.ErrCode resp.CommonResp.ErrMsg = err.Error() return resp, nil } totalGroupNum, err := imdb.GetTotalGroupNum() if err != nil { log.NewError(req.OperationID, utils.GetSelfFuncName(), err.Error()) resp.CommonResp.ErrCode = constant.ErrDB.ErrCode resp.CommonResp.ErrMsg = err.Error() return resp, nil } resp.IncreaseGroupNum = increaseGroupNum resp.TotalGroupNum = totalGroupNum times := GetRangeDate(fromTime, toTime) log.NewDebug(req.OperationID, "times:", times) wg := &sync.WaitGroup{} resp.IncreaseGroupNumList = make([]*pbAdminCMS.DateNumList, len(times), len(times)) resp.TotalGroupNumList = make([]*pbAdminCMS.DateNumList, len(times), len(times)) wg.Add(len(times)) for i, v := range times { go func(wg *sync.WaitGroup, index int, v [2]time.Time) { defer wg.Done() num, err := imdb.GetIncreaseGroupNum(v[0], v[1]) if err != nil { log.NewError(req.OperationID, utils.GetSelfFuncName(), "GetIncreaseGroupNum", v, err.Error()) } resp.IncreaseGroupNumList[index] = &pbAdminCMS.DateNumList{ Date: v[0].String(), Num: num, } num, err = imdb.GetGroupNum(v[1]) if err != nil { log.NewError(req.OperationID, utils.GetSelfFuncName(), "GetIncreaseGroupNum", v, err.Error()) } resp.TotalGroupNumList[index] = &pbAdminCMS.DateNumList{ Date: v[0].String(), Num: num, } }(wg, i, v) } wg.Wait() log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "resp: ", resp) return resp, nil } func (s *adminCMSServer) GetMessageStatistics(_ context.Context, req *pbAdminCMS.GetMessageStatisticsReq) (*pbAdminCMS.GetMessageStatisticsResp, error) { log.NewInfo(req.OperationID, utils.GetSelfFuncName(), req.String()) resp := &pbAdminCMS.GetMessageStatisticsResp{CommonResp: &pbAdminCMS.CommonResp{}} fromTime, toTime, err := ParseTimeFromTo(req.StatisticsReq.From, req.StatisticsReq.To) log.NewDebug(req.OperationID, utils.GetSelfFuncName(), "times: ", fromTime, toTime) if err != nil { log.NewError(req.OperationID, utils.GetSelfFuncName(), "ParseTimeFromTo failed", err.Error()) resp.CommonResp.ErrCode = constant.ErrDB.ErrCode resp.CommonResp.ErrMsg = err.Error() return resp, nil } privateMessageNum, err := imdb.GetSingleChatMessageNum(fromTime, toTime.Add(time.Hour*24)) if err != nil { log.NewError(req.OperationID, utils.GetSelfFuncName(), "GetSingleChatMessageNum failed", err.Error()) resp.CommonResp.ErrCode = constant.ErrDB.ErrCode resp.CommonResp.ErrMsg = err.Error() return resp, nil } groupMessageNum, err := imdb.GetGroupMessageNum(fromTime, toTime.Add(time.Hour*24)) if err != nil { log.NewError(req.OperationID, utils.GetSelfFuncName(), "GetGroupMessageNum failed", err.Error()) resp.CommonResp.ErrCode = constant.ErrDB.ErrCode resp.CommonResp.ErrMsg = err.Error() return resp, nil } log.NewDebug(req.OperationID, utils.GetSelfFuncName(), privateMessageNum, groupMessageNum) resp.PrivateMessageNum = privateMessageNum resp.GroupMessageNum = groupMessageNum times := GetRangeDate(fromTime, toTime) resp.GroupMessageNumList = make([]*pbAdminCMS.DateNumList, len(times), len(times)) resp.PrivateMessageNumList = make([]*pbAdminCMS.DateNumList, len(times), len(times)) wg := &sync.WaitGroup{} wg.Add(len(times)) for i, v := range times { go func(wg *sync.WaitGroup, index int, v [2]time.Time) { defer wg.Done() num, err := imdb.GetSingleChatMessageNum(v[0], v[1]) if err != nil { log.NewError(req.OperationID, utils.GetSelfFuncName(), "GetIncreaseGroupNum", v, err.Error()) } resp.PrivateMessageNumList[index] = &pbAdminCMS.DateNumList{ Date: v[0].String(), Num: num, } num, err = imdb.GetGroupMessageNum(v[0], v[1]) if err != nil { log.NewError(req.OperationID, utils.GetSelfFuncName(), "GetIncreaseGroupNum", v, err.Error()) } resp.GroupMessageNumList[index] = &pbAdminCMS.DateNumList{ Date: v[0].String(), Num: num, } }(wg, i, v) } wg.Wait() return resp, nil } func (s *adminCMSServer) GetUserStatistics(_ context.Context, req *pbAdminCMS.GetUserStatisticsReq) (*pbAdminCMS.GetUserStatisticsResp, error) { log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "req: ", req.String()) resp := &pbAdminCMS.GetUserStatisticsResp{CommonResp: &pbAdminCMS.CommonResp{}} fromTime, toTime, err := ParseTimeFromTo(req.StatisticsReq.From, req.StatisticsReq.To) if err != nil { log.NewError(req.OperationID, utils.GetSelfFuncName(), "ParseTimeFromTo failed", err.Error()) resp.CommonResp.ErrCode = constant.ErrDB.ErrCode resp.CommonResp.ErrMsg = err.Error() return resp, nil } activeUserNum, err := imdb.GetActiveUserNum(fromTime, toTime.Add(time.Hour*24)) if err != nil { log.NewError(req.OperationID, utils.GetSelfFuncName(), "GetActiveUserNum failed", err.Error()) resp.CommonResp.ErrCode = constant.ErrDB.ErrCode resp.CommonResp.ErrMsg = err.Error() return resp, nil } increaseUserNum, err := imdb.GetIncreaseUserNum(fromTime, toTime.Add(time.Hour*24)) if err != nil { log.NewError(req.OperationID, utils.GetSelfFuncName(), "GetIncreaseUserNum failed", err.Error()) resp.CommonResp.ErrCode = constant.ErrDB.ErrCode resp.CommonResp.ErrMsg = err.Error() return resp, nil } totalUserNum, err := imdb.GetTotalUserNum() if err != nil { log.NewError(req.OperationID, utils.GetSelfFuncName(), "GetTotalUserNum failed", err.Error()) resp.CommonResp.ErrCode = constant.ErrDB.ErrCode resp.CommonResp.ErrMsg = err.Error() return resp, nil } resp.ActiveUserNum = activeUserNum resp.TotalUserNum = totalUserNum resp.IncreaseUserNum = increaseUserNum times := GetRangeDate(fromTime, toTime) resp.TotalUserNumList = make([]*pbAdminCMS.DateNumList, len(times), len(times)) resp.ActiveUserNumList = make([]*pbAdminCMS.DateNumList, len(times), len(times)) resp.IncreaseUserNumList = make([]*pbAdminCMS.DateNumList, len(times), len(times)) wg := &sync.WaitGroup{} wg.Add(len(times)) for i, v := range times { go func(wg *sync.WaitGroup, index int, v [2]time.Time) { defer wg.Done() num, err := imdb.GetActiveUserNum(v[0], v[1]) if err != nil { log.NewError(req.OperationID, utils.GetSelfFuncName(), "GetIncreaseGroupNum", v, err.Error()) } resp.ActiveUserNumList[index] = &pbAdminCMS.DateNumList{ Date: v[0].String(), Num: num, } num, err = imdb.GetTotalUserNumByDate(v[1]) if err != nil { log.NewError(req.OperationID, utils.GetSelfFuncName(), "GetTotalUserNumByDate", v, err.Error()) } resp.TotalUserNumList[index] = &pbAdminCMS.DateNumList{ Date: v[0].String(), Num: num, } num, err = imdb.GetIncreaseUserNum(v[0], v[1]) if err != nil { log.NewError(req.OperationID, utils.GetSelfFuncName(), "GetIncreaseUserNum", v, err.Error()) } resp.IncreaseUserNumList[index] = &pbAdminCMS.DateNumList{ Date: v[0].String(), Num: num, } }(wg, i, v) } wg.Wait() log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "resp: ", resp) return resp, nil } func (s *adminCMSServer) GetUserFriends(_ context.Context, req *pbAdminCMS.GetUserFriendsReq) (*pbAdminCMS.GetUserFriendsResp, error) { log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "req: ", req.String()) resp := &pbAdminCMS.GetUserFriendsResp{CommonResp: &pbAdminCMS.CommonResp{}, Pagination: &server_api_params.ResponsePagination{CurrentPage: req.Pagination.PageNumber, ShowNumber: req.Pagination.ShowNumber}} var friendList []*imdb.FriendUser var err error if req.FriendUserID != "" { friend, err := imdb.GetFriendByIDCMS(req.UserID, req.FriendUserID) if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { log.NewError(req.OperationID, utils.GetSelfFuncName(), err, req.UserID, req.FriendUserID) return resp, nil } log.NewError(req.OperationID, utils.GetSelfFuncName(), err.Error(), req.UserID, req.FriendUserID) resp.CommonResp.ErrCode = constant.ErrDB.ErrCode resp.CommonResp.ErrMsg = err.Error() return resp, nil } friendList = append(friendList, friend) resp.FriendNums = 1 } else { var count int64 friendList, count, err = imdb.GetUserFriendsCMS(req.UserID, req.FriendUserName, req.Pagination.PageNumber, req.Pagination.ShowNumber) if err != nil { log.NewError(req.OperationID, utils.GetSelfFuncName(), err.Error(), req.UserID, req.FriendUserName, req.Pagination.PageNumber, req.Pagination.ShowNumber) resp.CommonResp.ErrCode = constant.ErrDB.ErrCode resp.CommonResp.ErrMsg = err.Error() return resp, nil } resp.FriendNums = int32(count) } for _, v := range friendList { friendInfo := &server_api_params.FriendInfo{} userInfo := &server_api_params.UserInfo{UserID: v.FriendUserID, Nickname: v.Nickname} utils.CopyStructFields(friendInfo, v) friendInfo.FriendUser = userInfo resp.FriendInfoList = append(resp.FriendInfoList, friendInfo) } log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "resp: ", resp.String()) return resp, nil } func (s *adminCMSServer) GetUserIDByEmailAndPhoneNumber(_ context.Context, req *pbAdminCMS.GetUserIDByEmailAndPhoneNumberReq) (*pbAdminCMS.GetUserIDByEmailAndPhoneNumberResp, error) { log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "req: ", req.String()) resp := &pbAdminCMS.GetUserIDByEmailAndPhoneNumberResp{CommonResp: &pbAdminCMS.CommonResp{}} userIDList, err := imdb.GetUserIDsByEmailAndID(req.PhoneNumber, req.Email) if err != nil { log.NewError(req.OperationID, utils.GetSelfFuncName(), err.Error(), req.PhoneNumber, req.Email) resp.CommonResp.ErrCode = constant.ErrDB.ErrCode resp.CommonResp.ErrMsg = err.Error() return resp, nil } resp.UserIDList = userIDList log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "resp: ", resp.String()) return resp, nil } func (s *adminCMSServer) GenerateInvitationCode(_ context.Context, req *pbAdminCMS.GenerateInvitationCodeReq) (*pbAdminCMS.GenerateInvitationCodeResp, error) { return nil, nil } func (s *adminCMSServer) GetInvitationCodes(_ context.Context, req *pbAdminCMS.GetInvitationCodesReq) (*pbAdminCMS.GetInvitationCodesResp, error) { return nil, nil } func (s *adminCMSServer) QueryIPRegister(_ context.Context, req *pbAdminCMS.QueryIPRegisterReq) (*pbAdminCMS.QueryIPRegisterResp, error) { return nil, nil } func (s *adminCMSServer) AddIPLimit(_ context.Context, req *pbAdminCMS.AddIPLimitReq) (*pbAdminCMS.AddIPLimitResp, error) { return nil, nil } func (s *adminCMSServer) RemoveIPLimit(_ context.Context, req *pbAdminCMS.RemoveIPLimitReq) (*pbAdminCMS.RemoveIPLimitResp, error) { return nil, nil } func (s *adminCMSServer) QueryUserIDIPLimitLogin(_ context.Context, req *pbAdminCMS.QueryUserIDIPLimitLoginReq) (*pbAdminCMS.QueryUserIDIPLimitLoginResp, error) { return nil, nil } func (s *adminCMSServer) AddUserIPLimitLogin(_ context.Context, req *pbAdminCMS.AddUserIPLimitLoginReq) (*pbAdminCMS.AddUserIPLimitLoginResp, error) { return nil, nil } func (s *adminCMSServer) RemoveUserIPLimit(_ context.Context, req *pbAdminCMS.RemoveUserIPLimitReq) (*pbAdminCMS.RemoveUserIPLimitResp, error) { return nil, nil } func (s *adminCMSServer) GetClientInitConfig(_ context.Context, req *pbAdminCMS.GetClientInitConfigReq) (*pbAdminCMS.GetClientInitConfigResp, error) { return nil, nil } func (s *adminCMSServer) SetClientInitConfig(_ context.Context, req *pbAdminCMS.SetClientInitConfigReq) (*pbAdminCMS.SetClientInitConfigResp, error) { return nil, nil }