answer/internal/service/user_service.go

732 lines
22 KiB
Go
Raw Normal View History

2022-09-27 17:59:05 +08:00
package service
import (
"context"
2022-10-28 14:53:44 +08:00
"encoding/json"
2022-09-27 17:59:05 +08:00
"fmt"
2022-12-12 16:39:48 +08:00
"time"
2022-09-27 17:59:05 +08:00
"github.com/answerdev/answer/internal/base/handler"
"github.com/answerdev/answer/internal/base/reason"
"github.com/answerdev/answer/internal/base/translator"
"github.com/answerdev/answer/internal/base/validator"
"github.com/answerdev/answer/internal/entity"
"github.com/answerdev/answer/internal/schema"
"github.com/answerdev/answer/internal/service/activity"
2022-12-12 16:39:48 +08:00
"github.com/answerdev/answer/internal/service/activity_common"
"github.com/answerdev/answer/internal/service/auth"
"github.com/answerdev/answer/internal/service/export"
"github.com/answerdev/answer/internal/service/role"
"github.com/answerdev/answer/internal/service/service_config"
"github.com/answerdev/answer/internal/service/siteinfo_common"
usercommon "github.com/answerdev/answer/internal/service/user_common"
2022-09-27 17:59:05 +08:00
"github.com/google/uuid"
"github.com/segmentfault/pacman/errors"
"github.com/segmentfault/pacman/log"
"golang.org/x/crypto/bcrypt"
)
// UserRepo user repository
// UserService user service
type UserService struct {
userCommonService *usercommon.UserCommon
userRepo usercommon.UserRepo
userActivity activity.UserActiveActivityRepo
2022-12-12 16:39:48 +08:00
activityRepo activity_common.ActivityRepo
serviceConfig *service_config.ServiceConfig
emailService *export.EmailService
authService *auth.AuthService
siteInfoService *siteinfo_common.SiteInfoCommonService
userRoleService *role.UserRoleRelService
2022-09-27 17:59:05 +08:00
}
func NewUserService(userRepo usercommon.UserRepo,
userActivity activity.UserActiveActivityRepo,
2022-12-12 16:39:48 +08:00
activityRepo activity_common.ActivityRepo,
2022-09-27 17:59:05 +08:00
emailService *export.EmailService,
authService *auth.AuthService,
serviceConfig *service_config.ServiceConfig,
siteInfoService *siteinfo_common.SiteInfoCommonService,
userRoleService *role.UserRoleRelService,
userCommonService *usercommon.UserCommon,
) *UserService {
2022-09-27 17:59:05 +08:00
return &UserService{
userCommonService: userCommonService,
userRepo: userRepo,
userActivity: userActivity,
2022-12-12 16:39:48 +08:00
activityRepo: activityRepo,
emailService: emailService,
serviceConfig: serviceConfig,
authService: authService,
siteInfoService: siteInfoService,
userRoleService: userRoleService,
2022-09-27 17:59:05 +08:00
}
}
// GetUserInfoByUserID get user info by user id
2022-10-28 15:43:37 +08:00
func (us *UserService) GetUserInfoByUserID(ctx context.Context, token, userID string) (resp *schema.GetUserToSetShowResp, err error) {
2022-09-27 17:59:05 +08:00
userInfo, exist, err := us.userRepo.GetByUserID(ctx, userID)
if err != nil {
return nil, err
}
if !exist {
return nil, errors.BadRequest(reason.UserNotFound)
}
roleID, err := us.userRoleService.GetUserRole(ctx, userInfo.ID)
if err != nil {
log.Error(err)
}
2022-10-28 15:43:37 +08:00
resp = &schema.GetUserToSetShowResp{}
2022-09-27 17:59:05 +08:00
resp.GetFromUserEntity(userInfo)
resp.AccessToken = token
resp.IsAdmin = roleID == role.RoleAdminID
2022-09-27 17:59:05 +08:00
return resp, nil
}
func (us *UserService) GetOtherUserInfoByUsername(ctx context.Context, username string) (
resp *schema.GetOtherUserInfoResp, err error,
) {
2022-09-27 17:59:05 +08:00
userInfo, exist, err := us.userRepo.GetByUsername(ctx, username)
if err != nil {
return nil, err
}
resp = &schema.GetOtherUserInfoResp{}
if !exist {
return resp, nil
}
resp.Has = true
resp.Info = &schema.GetOtherUserInfoByUsernameResp{}
resp.Info.GetFromUserEntity(userInfo)
return resp, nil
}
// EmailLogin email login
func (us *UserService) EmailLogin(ctx context.Context, req *schema.UserEmailLogin) (resp *schema.GetUserResp, err error) {
userInfo, exist, err := us.userRepo.GetByEmail(ctx, req.Email)
if err != nil {
return nil, err
}
if !exist || userInfo.Status == entity.UserStatusDeleted {
return nil, errors.BadRequest(reason.EmailOrPasswordWrong)
}
if !us.verifyPassword(ctx, req.Pass, userInfo.Pass) {
return nil, errors.BadRequest(reason.EmailOrPasswordWrong)
}
err = us.userRepo.UpdateLastLoginDate(ctx, userInfo.ID)
if err != nil {
log.Error("UpdateLastLoginDate", err.Error())
}
roleID, err := us.userRoleService.GetUserRole(ctx, userInfo.ID)
if err != nil {
log.Error(err)
}
2022-09-27 17:59:05 +08:00
resp = &schema.GetUserResp{}
resp.GetFromUserEntity(userInfo)
userCacheInfo := &entity.UserCacheInfo{
UserID: userInfo.ID,
EmailStatus: userInfo.MailStatus,
UserStatus: userInfo.Status,
IsAdmin: roleID == role.RoleAdminID,
2022-09-27 17:59:05 +08:00
}
resp.AccessToken, err = us.authService.SetUserCacheInfo(ctx, userCacheInfo)
if err != nil {
return nil, err
}
resp.IsAdmin = userCacheInfo.IsAdmin
2022-09-27 17:59:05 +08:00
if resp.IsAdmin {
2022-12-21 16:55:16 +08:00
err = us.authService.SetAdminUserCacheInfo(ctx, resp.AccessToken, userCacheInfo)
2022-09-27 17:59:05 +08:00
if err != nil {
return nil, err
}
}
return resp, nil
}
// RetrievePassWord .
func (us *UserService) RetrievePassWord(ctx context.Context, req *schema.UserRetrievePassWordRequest) (string, error) {
userInfo, has, err := us.userRepo.GetByEmail(ctx, req.Email)
if err != nil {
return "", err
}
if !has {
return "", errors.BadRequest(reason.UserNotFound)
}
// send email
data := &schema.EmailCodeContent{
Email: req.Email,
UserID: userInfo.ID,
}
code := uuid.NewString()
verifyEmailURL := fmt.Sprintf("%s/users/password-reset?code=%s", us.getSiteUrl(ctx), code)
title, body, err := us.emailService.PassResetTemplate(ctx, verifyEmailURL)
2022-09-27 17:59:05 +08:00
if err != nil {
return "", err
}
go us.emailService.SendAndSaveCode(ctx, req.Email, title, body, code, data.ToJSONString())
2022-09-27 17:59:05 +08:00
return code, nil
}
2022-10-28 19:28:08 +08:00
// UseRePassword
func (us *UserService) UseRePassword(ctx context.Context, req *schema.UserRePassWordRequest) (resp *schema.GetUserResp, err error) {
2022-09-27 17:59:05 +08:00
data := &schema.EmailCodeContent{}
err = data.FromJSONString(req.Content)
if err != nil {
return nil, errors.BadRequest(reason.EmailVerifyURLExpired)
2022-09-27 17:59:05 +08:00
}
userInfo, exist, err := us.userRepo.GetByEmail(ctx, data.Email)
if err != nil {
return nil, err
}
if !exist {
return nil, errors.BadRequest(reason.UserNotFound)
}
enpass, err := us.encryptPassword(ctx, req.Pass)
if err != nil {
return nil, err
}
2022-10-28 19:28:08 +08:00
err = us.userRepo.UpdatePass(ctx, userInfo.ID, enpass)
2022-09-27 17:59:05 +08:00
if err != nil {
return nil, err
}
resp = &schema.GetUserResp{}
return resp, nil
}
func (us *UserService) UserModifyPassWordVerification(ctx context.Context, request *schema.UserModifyPassWordRequest) (bool, error) {
userInfo, has, err := us.userRepo.GetByUserID(ctx, request.UserID)
2022-09-27 17:59:05 +08:00
if err != nil {
return false, err
}
if !has {
return false, fmt.Errorf("user does not exist")
}
isPass := us.verifyPassword(ctx, request.OldPass, userInfo.Pass)
if !isPass {
return false, nil
}
return true, nil
}
2022-10-28 19:28:08 +08:00
// UserModifyPassword user modify password
func (us *UserService) UserModifyPassword(ctx context.Context, request *schema.UserModifyPassWordRequest) error {
2022-09-27 17:59:05 +08:00
enpass, err := us.encryptPassword(ctx, request.Pass)
if err != nil {
return err
}
userInfo, has, err := us.userRepo.GetByUserID(ctx, request.UserID)
2022-09-27 17:59:05 +08:00
if err != nil {
return err
}
if !has {
return fmt.Errorf("user does not exist")
}
isPass := us.verifyPassword(ctx, request.OldPass, userInfo.Pass)
if !isPass {
return fmt.Errorf("the old password verification failed")
}
2022-10-28 19:28:08 +08:00
err = us.userRepo.UpdatePass(ctx, userInfo.ID, enpass)
2022-09-27 17:59:05 +08:00
if err != nil {
return err
}
return nil
}
2022-10-14 17:01:06 +08:00
// UpdateInfo update user info
func (us *UserService) UpdateInfo(ctx context.Context, req *schema.UpdateInfoRequest) (err error) {
if len(req.Username) > 0 {
userInfo, exist, err := us.userRepo.GetByUsername(ctx, req.Username)
if err != nil {
return err
}
if exist && userInfo.ID != req.UserID {
2022-10-14 17:01:06 +08:00
return errors.BadRequest(reason.UsernameDuplicate)
}
}
avatar, err := json.Marshal(req.Avatar)
2022-10-28 14:53:44 +08:00
if err != nil {
2022-10-28 15:21:23 +08:00
err = errors.BadRequest(reason.UserSetAvatar).WithError(err).WithStack()
2022-10-28 14:53:44 +08:00
return err
}
2022-10-14 17:01:06 +08:00
userInfo := entity.User{}
userInfo.ID = req.UserID
userInfo.Avatar = string(avatar)
2022-10-14 17:01:06 +08:00
userInfo.DisplayName = req.DisplayName
userInfo.Bio = req.Bio
userInfo.BioHTML = req.BioHTML
2022-10-14 17:01:06 +08:00
userInfo.Location = req.Location
userInfo.Website = req.Website
userInfo.Username = req.Username
if err := us.userRepo.UpdateInfo(ctx, &userInfo); err != nil {
2022-09-27 17:59:05 +08:00
return err
}
return nil
}
func (us *UserService) UserEmailHas(ctx context.Context, email string) (bool, error) {
_, has, err := us.userRepo.GetByEmail(ctx, email)
if err != nil {
return false, err
}
return has, nil
}
// UserUpdateInterface update user interface
func (us *UserService) UserUpdateInterface(ctx context.Context, req *schema.UpdateUserInterfaceRequest) (err error) {
if !translator.CheckLanguageIsValid(req.Language) {
return errors.BadRequest(reason.LangNotFound)
}
err = us.userRepo.UpdateLanguage(ctx, req.UserId, req.Language)
if err != nil {
return
}
return nil
}
2022-09-27 17:59:05 +08:00
// UserRegisterByEmail user register
2022-10-14 17:01:06 +08:00
func (us *UserService) UserRegisterByEmail(ctx context.Context, registerUserInfo *schema.UserRegisterReq) (
resp *schema.GetUserResp, errFields []*validator.FormErrorField, err error,
) {
2022-09-27 17:59:05 +08:00
_, has, err := us.userRepo.GetByEmail(ctx, registerUserInfo.Email)
if err != nil {
return nil, nil, err
2022-09-27 17:59:05 +08:00
}
if has {
errFields = append(errFields, &validator.FormErrorField{
ErrorField: "e_mail",
ErrorMsg: reason.EmailDuplicate,
})
return nil, errFields, errors.BadRequest(reason.EmailDuplicate)
2022-09-27 17:59:05 +08:00
}
userInfo := &entity.User{}
userInfo.EMail = registerUserInfo.Email
userInfo.DisplayName = registerUserInfo.Name
userInfo.Pass, err = us.encryptPassword(ctx, registerUserInfo.Pass)
if err != nil {
return nil, nil, err
2022-09-27 17:59:05 +08:00
}
userInfo.Username, err = us.userCommonService.MakeUsername(ctx, registerUserInfo.Name)
2022-09-27 17:59:05 +08:00
if err != nil {
errFields = append(errFields, &validator.FormErrorField{
ErrorField: "name",
ErrorMsg: reason.UsernameInvalid,
})
return nil, errFields, err
2022-09-27 17:59:05 +08:00
}
userInfo.IPInfo = registerUserInfo.IP
userInfo.MailStatus = entity.EmailStatusToBeVerified
userInfo.Status = entity.UserStatusAvailable
userInfo.LastLoginDate = time.Now()
2022-09-27 17:59:05 +08:00
err = us.userRepo.AddUser(ctx, userInfo)
if err != nil {
return nil, nil, err
2022-09-27 17:59:05 +08:00
}
// send email
data := &schema.EmailCodeContent{
Email: registerUserInfo.Email,
UserID: userInfo.ID,
}
code := uuid.NewString()
verifyEmailURL := fmt.Sprintf("%s/users/account-activation?code=%s", us.getSiteUrl(ctx), code)
title, body, err := us.emailService.RegisterTemplate(ctx, verifyEmailURL)
2022-09-27 17:59:05 +08:00
if err != nil {
return nil, nil, err
2022-09-27 17:59:05 +08:00
}
go us.emailService.SendAndSaveCode(ctx, userInfo.EMail, title, body, code, data.ToJSONString())
2022-09-27 17:59:05 +08:00
roleID, err := us.userRoleService.GetUserRole(ctx, userInfo.ID)
if err != nil {
log.Error(err)
}
2022-09-27 17:59:05 +08:00
// return user info and token
resp = &schema.GetUserResp{}
resp.GetFromUserEntity(userInfo)
userCacheInfo := &entity.UserCacheInfo{
UserID: userInfo.ID,
EmailStatus: userInfo.MailStatus,
UserStatus: userInfo.Status,
IsAdmin: roleID == role.RoleAdminID,
2022-09-27 17:59:05 +08:00
}
resp.AccessToken, err = us.authService.SetUserCacheInfo(ctx, userCacheInfo)
if err != nil {
return nil, nil, err
2022-09-27 17:59:05 +08:00
}
resp.IsAdmin = userCacheInfo.IsAdmin
2022-09-27 17:59:05 +08:00
if resp.IsAdmin {
2022-12-21 16:55:16 +08:00
err = us.authService.SetAdminUserCacheInfo(ctx, resp.AccessToken, &entity.UserCacheInfo{UserID: userInfo.ID})
2022-09-27 17:59:05 +08:00
if err != nil {
return nil, nil, err
2022-09-27 17:59:05 +08:00
}
}
return resp, nil, nil
2022-09-27 17:59:05 +08:00
}
func (us *UserService) UserVerifyEmailSend(ctx context.Context, userID string) error {
userInfo, has, err := us.userRepo.GetByUserID(ctx, userID)
if err != nil {
return err
}
if !has {
return errors.BadRequest(reason.UserNotFound)
}
data := &schema.EmailCodeContent{
Email: userInfo.EMail,
UserID: userInfo.ID,
}
code := uuid.NewString()
verifyEmailURL := fmt.Sprintf("%s/users/account-activation?code=%s", us.getSiteUrl(ctx), code)
title, body, err := us.emailService.RegisterTemplate(ctx, verifyEmailURL)
2022-09-27 17:59:05 +08:00
if err != nil {
return err
}
go us.emailService.SendAndSaveCode(ctx, userInfo.EMail, title, body, code, data.ToJSONString())
2022-09-27 17:59:05 +08:00
return nil
}
func (us *UserService) UserNoticeSet(ctx context.Context, userID string, noticeSwitch bool) (
resp *schema.UserNoticeSetResp, err error,
) {
userInfo, has, err := us.userRepo.GetByUserID(ctx, userID)
2022-09-27 17:59:05 +08:00
if err != nil {
return nil, err
}
if !has {
return nil, errors.BadRequest(reason.UserNotFound)
}
if noticeSwitch {
2022-10-28 19:28:08 +08:00
userInfo.NoticeStatus = schema.NoticeStatusOn
2022-09-27 17:59:05 +08:00
} else {
2022-10-28 19:28:08 +08:00
userInfo.NoticeStatus = schema.NoticeStatusOff
2022-09-27 17:59:05 +08:00
}
err = us.userRepo.UpdateNoticeStatus(ctx, userInfo.ID, userInfo.NoticeStatus)
return &schema.UserNoticeSetResp{NoticeSwitch: noticeSwitch}, err
}
func (us *UserService) UserVerifyEmail(ctx context.Context, req *schema.UserVerifyEmailReq) (resp *schema.GetUserResp, err error) {
data := &schema.EmailCodeContent{}
err = data.FromJSONString(req.Content)
if err != nil {
return nil, errors.BadRequest(reason.EmailVerifyURLExpired)
2022-09-27 17:59:05 +08:00
}
userInfo, has, err := us.userRepo.GetByEmail(ctx, data.Email)
if err != nil {
return nil, err
}
if !has {
return nil, errors.BadRequest(reason.UserNotFound)
}
userInfo.MailStatus = entity.EmailStatusAvailable
err = us.userRepo.UpdateEmailStatus(ctx, userInfo.ID, userInfo.MailStatus)
if err != nil {
return nil, err
}
if err = us.userActivity.UserActive(ctx, userInfo.ID); err != nil {
log.Error(err)
}
accessToken, userCacheInfo, err := us.userCommonService.CacheLoginUserInfo(
ctx, userInfo.ID, userInfo.MailStatus, userInfo.Status)
if err != nil {
return nil, err
}
2022-09-27 17:59:05 +08:00
resp = &schema.GetUserResp{}
resp.GetFromUserEntity(userInfo)
resp.IsAdmin = userCacheInfo.IsAdmin
resp.AccessToken = accessToken
// User verified email will update user email status. So user status cache should be updated.
if err = us.authService.SetUserStatus(ctx, userCacheInfo); err != nil {
return nil, err
}
2022-09-27 17:59:05 +08:00
return resp, nil
}
// verifyPassword
// Compare whether the password is correct
func (us *UserService) verifyPassword(ctx context.Context, LoginPass, UserPass string) bool {
err := bcrypt.CompareHashAndPassword([]byte(UserPass), []byte(LoginPass))
return err == nil
2022-09-27 17:59:05 +08:00
}
// encryptPassword
// The password does irreversible encryption.
func (us *UserService) encryptPassword(ctx context.Context, Pass string) (string, error) {
hashPwd, err := bcrypt.GenerateFromPassword([]byte(Pass), bcrypt.DefaultCost)
// This encrypted string can be saved to the database and can be used as password matching verification
2022-09-27 17:59:05 +08:00
return string(hashPwd), err
}
// UserChangeEmailSendCode user change email verification
func (us *UserService) UserChangeEmailSendCode(ctx context.Context, req *schema.UserChangeEmailSendCodeReq) (
resp []*validator.FormErrorField, err error) {
2022-10-31 16:50:38 +08:00
userInfo, exist, err := us.userRepo.GetByUserID(ctx, req.UserID)
2022-09-27 17:59:05 +08:00
if err != nil {
return nil, err
2022-09-27 17:59:05 +08:00
}
if !exist {
return nil, errors.BadRequest(reason.UserNotFound)
2022-09-27 17:59:05 +08:00
}
_, exist, err = us.userRepo.GetByEmail(ctx, req.Email)
if err != nil {
return nil, err
2022-09-27 17:59:05 +08:00
}
if exist {
resp = append([]*validator.FormErrorField{}, &validator.FormErrorField{
ErrorField: "e_mail",
ErrorMsg: translator.GlobalTrans.Tr(handler.GetLangByCtx(ctx), reason.EmailDuplicate),
})
return resp, errors.BadRequest(reason.EmailDuplicate)
2022-09-27 17:59:05 +08:00
}
data := &schema.EmailCodeContent{
Email: req.Email,
UserID: req.UserID,
}
code := uuid.NewString()
2022-10-31 16:50:38 +08:00
var title, body string
verifyEmailURL := fmt.Sprintf("%s/users/confirm-new-email?code=%s", us.getSiteUrl(ctx), code)
2022-10-31 16:50:38 +08:00
if userInfo.MailStatus == entity.EmailStatusToBeVerified {
2022-11-01 15:38:06 +08:00
title, body, err = us.emailService.RegisterTemplate(ctx, verifyEmailURL)
2022-10-31 16:50:38 +08:00
} else {
2022-11-01 15:38:06 +08:00
title, body, err = us.emailService.ChangeEmailTemplate(ctx, verifyEmailURL)
2022-10-31 16:53:59 +08:00
}
2022-09-27 17:59:05 +08:00
if err != nil {
return nil, err
2022-09-27 17:59:05 +08:00
}
log.Infof("send email confirmation %s", verifyEmailURL)
2022-09-27 17:59:05 +08:00
go us.emailService.SendAndSaveCode(context.Background(), req.Email, title, body, code, data.ToJSONString())
return nil, nil
2022-09-27 17:59:05 +08:00
}
// UserChangeEmailVerify user change email verify code
func (us *UserService) UserChangeEmailVerify(ctx context.Context, content string) (err error) {
data := &schema.EmailCodeContent{}
err = data.FromJSONString(content)
if err != nil {
return errors.BadRequest(reason.EmailVerifyURLExpired)
2022-09-27 17:59:05 +08:00
}
_, exist, err := us.userRepo.GetByEmail(ctx, data.Email)
if err != nil {
return err
}
if exist {
return errors.BadRequest(reason.EmailDuplicate)
}
_, exist, err = us.userRepo.GetByUserID(ctx, data.UserID)
if err != nil {
return err
}
if !exist {
return errors.BadRequest(reason.UserNotFound)
}
err = us.userRepo.UpdateEmail(ctx, data.UserID, data.Email)
if err != nil {
2022-10-28 15:21:23 +08:00
return errors.BadRequest(reason.UserNotFound)
2022-09-27 17:59:05 +08:00
}
2022-10-28 16:21:09 +08:00
err = us.userRepo.UpdateEmailStatus(ctx, data.UserID, entity.EmailStatusAvailable)
2022-09-27 17:59:05 +08:00
if err != nil {
return err
}
return nil
}
// getSiteUrl get site url
func (us *UserService) getSiteUrl(ctx context.Context) string {
siteGeneral, err := us.siteInfoService.GetSiteGeneral(ctx)
if err != nil {
log.Errorf("get site general failed: %s", err)
return ""
}
return siteGeneral.SiteUrl
}
// UserRanking get user ranking
2022-12-12 16:39:48 +08:00
func (us *UserService) UserRanking(ctx context.Context) (resp *schema.UserRankingResp, err error) {
limit := 20
2022-12-12 16:39:48 +08:00
endTime := time.Now()
startTime := endTime.AddDate(0, 0, -7)
userIDs, userIDExist := make([]string, 0), make(map[string]bool, 0)
2022-12-12 16:39:48 +08:00
// get most reputation users
rankStat, rankStatUserIDs, err := us.getActivityUserRankStat(ctx, startTime, endTime, limit, userIDExist)
if err != nil {
return nil, err
}
userIDs = append(userIDs, rankStatUserIDs...)
// get most vote users
voteStat, voteStatUserIDs, err := us.getActivityUserVoteStat(ctx, startTime, endTime, limit, userIDExist)
if err != nil {
return nil, err
}
userIDs = append(userIDs, voteStatUserIDs...)
// get all staff members
userRoleRels, staffUserIDs, err := us.getStaff(ctx, userIDExist)
if err != nil {
return nil, err
}
userIDs = append(userIDs, staffUserIDs...)
// get user information
userInfoMapping, err := us.getUserInfoMapping(ctx, userIDs)
2022-12-12 16:39:48 +08:00
if err != nil {
return nil, err
}
return us.warpStatRankingResp(userInfoMapping, rankStat, voteStat, userRoleRels), nil
}
// UserUnsubscribeEmailNotification user unsubscribe email notification
func (us *UserService) UserUnsubscribeEmailNotification(
ctx context.Context, req *schema.UserUnsubscribeEmailNotificationReq) (err error) {
data := &schema.EmailCodeContent{}
err = data.FromJSONString(req.Content)
if err != nil || len(data.UserID) == 0 {
return errors.BadRequest(reason.EmailVerifyURLExpired)
}
userInfo, exist, err := us.userRepo.GetByUserID(ctx, data.UserID)
if err != nil {
return err
}
if !exist {
return errors.BadRequest(reason.UserNotFound)
}
return us.userRepo.UpdateNoticeStatus(ctx, userInfo.ID, schema.NoticeStatusOff)
}
func (us *UserService) getActivityUserRankStat(ctx context.Context, startTime, endTime time.Time, limit int,
userIDExist map[string]bool) (rankStat []*entity.ActivityUserRankStat, userIDs []string, err error) {
rankStat, err = us.activityRepo.GetUsersWhoHasGainedTheMostReputation(ctx, startTime, endTime, limit)
if err != nil {
return nil, nil, err
}
2022-12-12 16:39:48 +08:00
for _, stat := range rankStat {
if stat.Rank <= 0 {
2022-12-12 16:39:48 +08:00
continue
}
if userIDExist[stat.UserID] {
continue
}
userIDs = append(userIDs, stat.UserID)
userIDExist[stat.UserID] = true
}
return rankStat, userIDs, nil
}
2022-12-12 16:39:48 +08:00
func (us *UserService) getActivityUserVoteStat(ctx context.Context, startTime, endTime time.Time, limit int,
userIDExist map[string]bool) (voteStat []*entity.ActivityUserVoteStat, userIDs []string, err error) {
voteStat, err = us.activityRepo.GetUsersWhoHasVoteMost(ctx, startTime, endTime, limit)
2022-12-12 16:39:48 +08:00
if err != nil {
return nil, nil, err
2022-12-12 16:39:48 +08:00
}
for _, stat := range voteStat {
if stat.VoteCount <= 0 {
2022-12-12 16:39:48 +08:00
continue
}
if userIDExist[stat.UserID] {
continue
}
userIDs = append(userIDs, stat.UserID)
userIDExist[stat.UserID] = true
}
return voteStat, userIDs, nil
}
2022-12-12 16:39:48 +08:00
func (us *UserService) getStaff(ctx context.Context, userIDExist map[string]bool) (
userRoleRels []*entity.UserRoleRel, userIDs []string, err error) {
userRoleRels, err = us.userRoleService.GetUserByRoleID(ctx, []int{role.RoleAdminID, role.RoleModeratorID})
2022-12-12 16:39:48 +08:00
if err != nil {
return nil, nil, err
2022-12-12 16:39:48 +08:00
}
for _, rel := range userRoleRels {
if userIDExist[rel.UserID] {
continue
}
userIDs = append(userIDs, rel.UserID)
userIDExist[rel.UserID] = true
}
return userRoleRels, userIDs, nil
}
2022-12-12 16:39:48 +08:00
func (us *UserService) getUserInfoMapping(ctx context.Context, userIDs []string) (
userInfoMapping map[string]*entity.User, err error) {
userInfoMapping = make(map[string]*entity.User, 0)
2022-12-12 16:39:48 +08:00
if len(userIDs) == 0 {
return userInfoMapping, nil
2022-12-12 16:39:48 +08:00
}
userInfoList, err := us.userRepo.BatchGetByID(ctx, userIDs)
if err != nil {
return nil, err
}
for _, user := range userInfoList {
user.Avatar = schema.FormatAvatarInfo(user.Avatar)
userInfoMapping[user.ID] = user
}
return userInfoMapping, nil
}
2022-12-12 16:39:48 +08:00
func (us *UserService) warpStatRankingResp(
userInfoMapping map[string]*entity.User,
rankStat []*entity.ActivityUserRankStat,
voteStat []*entity.ActivityUserVoteStat,
userRoleRels []*entity.UserRoleRel) (resp *schema.UserRankingResp) {
resp = &schema.UserRankingResp{
UsersWithTheMostReputation: make([]*schema.UserRankingSimpleInfo, 0),
UsersWithTheMostVote: make([]*schema.UserRankingSimpleInfo, 0),
Staffs: make([]*schema.UserRankingSimpleInfo, 0),
}
2022-12-12 16:39:48 +08:00
for _, stat := range rankStat {
if stat.Rank <= 0 {
continue
}
if userInfo := userInfoMapping[stat.UserID]; userInfo != nil {
resp.UsersWithTheMostReputation = append(resp.UsersWithTheMostReputation, &schema.UserRankingSimpleInfo{
Username: userInfo.Username,
Rank: stat.Rank,
DisplayName: userInfo.DisplayName,
Avatar: userInfo.Avatar,
})
2022-12-12 16:39:48 +08:00
}
}
for _, stat := range voteStat {
if stat.VoteCount <= 0 {
continue
}
if userInfo := userInfoMapping[stat.UserID]; userInfo != nil {
resp.UsersWithTheMostVote = append(resp.UsersWithTheMostVote, &schema.UserRankingSimpleInfo{
Username: userInfo.Username,
VoteCount: stat.VoteCount,
DisplayName: userInfo.DisplayName,
Avatar: userInfo.Avatar,
})
2022-12-12 16:39:48 +08:00
}
}
for _, rel := range userRoleRels {
if userInfo := userInfoMapping[rel.UserID]; userInfo != nil {
resp.Staffs = append(resp.Staffs, &schema.UserRankingSimpleInfo{
Username: userInfo.Username,
Rank: userInfo.Rank,
DisplayName: userInfo.DisplayName,
Avatar: userInfo.Avatar,
})
2022-12-12 16:39:48 +08:00
}
}
return resp
}