diff --git a/api/consts/role.go b/api/consts/role.go index 959ec96e..0a4cfbb9 100644 --- a/api/consts/role.go +++ b/api/consts/role.go @@ -15,6 +15,8 @@ const ( StreamerToBe = 4 //准主播 ) +var RolesAllowedToCancel = []int64{User, StreamerToBe} + var AccountPunishmentRoleMap = map[int64][]int64{ AccountPunishment_BlockFromCreatingMoment: {Streamer}, } diff --git a/app/mix/service/apiservice.go b/app/mix/service/apiservice.go index e89937b9..c4240ae8 100644 --- a/app/mix/service/apiservice.go +++ b/app/mix/service/apiservice.go @@ -135,6 +135,15 @@ func (s *Service) ApiLoginByPswd(ctx *gin.Context, req *loginproto.ApiLoginByPsw return } + // 判断是否是注销申请中,如果是注销申请中,则中止注销 + if account.GetStatus() == consts.AccountStatus_Cancelling { + if err := s.utilAbortAccountCancellation(ctx, account.GetMid()); err != nil { + ec = errcode.ErrCodeAccountCancellationSrvFail + logger.Error("utilAbortAccountCancellation failed, err: %v", err) + return + } + } + // 5.组装返回信息 accountVO = &accountproto.ApiListVO{} accountVO.CopyAccount(account) @@ -214,6 +223,16 @@ func (s *Service) ApiLoginByVeriCode(ctx *gin.Context, req *loginproto.ApiLoginB } logger.Info("login info updated...") + // 判断是否是注销申请中,如果是注销申请中,则中止注销 + if account.GetStatus() == consts.AccountStatus_Cancelling { + if err := s.utilAbortAccountCancellation(ctx, account.GetMid()); err != nil { + ec = errcode.ErrCodeAccountCancellationSrvFail + logger.Error("utilAbortAccountCancellation failed, err: %v", err) + return + } + logger.Info("account cancellation has been aborted...") + } + // 7.组装返回信息 isEnabled = util.DerefInt64(login.IsEnabled) accountVO = &accountproto.ApiListVO{} @@ -591,38 +610,23 @@ func (s *Service) ApiAccountExpInc(ctx *gin.Context, req *accountproto.ApiExpInc func (s *Service) ApiCancelAccount(ctx *gin.Context, req *accountproto.ApiCancelReq) (ec errcode.ErrCode) { ec = errcode.ErrCodeAccountSrvOk - // 查询Account信息 - account, err := _DefaultAccount.OpListByMid(ctx, &accountproto.OpListByMidReq{ - Mid: goproto.Int64(req.Mid), - }) - if err != nil { - logger.Error("OpListByMid fail, err: %v", err) - ec = errcode.ErrCodeAccountSrvFail - return - } - if account == nil { - logger.Error("No account entity was found!") - ec = errcode.ErrCodeAccountNotExist + // 业务鉴权 + account, ec := s.ApiCancelAccountBusinessValidate(ctx, req) + if ec != errcode.ErrCodeAccountSrvOk { return } - if util.DerefInt64(account.Role) == consts.Streamer { - logger.Error("Cancellation of streamer requires manual operation") - ec = errcode.ErrCodeAccountStreamerRoleCancellation - return - } - - if util.DerefInt64(account.Role) != consts.User { - logger.Error("Cancellation of non-user account requires manual operation") - ec = errcode.ErrCodeAccountNonUserRoleCancellation - return - } - - if util.DerefInt64(account.Status) != consts.AccountStatus_Normal { - logger.Error("Only account in normal status is allowed to cancel") - ec = errcode.ErrCodeAccountNotInNormalStatus - return - } + defer func() { + // 如果是准主播,则直接清掉所有的完善资料请求 + if account.GetRole() == consts.StreamerToBe { + err := _DefaultStreamerAuthApprovalDetails.OpDeleteBatchByMids(ctx, []int64{account.GetMid()}, consts.StreamerAuthApprovalDetails_Rejected, consts.StreamerAuthApprovalDetailsApprove_Rejected, "账户注销,自动删除") + if err != nil { + logger.Error("_DefaultStreamerAuthApprovalDetails OpDeleteBatchByMids fail, req: %v, err: %v", util.ToJson(req), err) + ec = errcode.ErrCodeStreamerAuthApprovalDetailsSrvFail + return + } + } + }() // 更改状态 if err := _DefaultAccount.OpUpdate(ctx, &accountproto.OpUpdateReq{ @@ -658,63 +662,19 @@ func (s *Service) ApiCancelAccount(ctx *gin.Context, req *accountproto.ApiCancel func (s *Service) ApiAbortAccountCancellation(ctx *gin.Context, req *accountproto.ApiAbortCancellationReq) (ec errcode.ErrCode) { ec = errcode.ErrCodeAccountSrvOk - // 查询Account信息 - account, err := _DefaultAccount.OpListByMid(ctx, &accountproto.OpListByMidReq{ - Mid: goproto.Int64(req.Mid), - }) - if err != nil { - logger.Error("OpListByMid fail, err: %v", err) - ec = errcode.ErrCodeAccountSrvFail - return - } - if account == nil { - logger.Error("No account entity was found!") - ec = errcode.ErrCodeAccountNotExist + // 业务鉴权 + ec = s.ApiAbortAccountCancellationBusinessValidate(ctx, req) + if ec != errcode.ErrCodeAccountSrvOk { return } - if util.DerefInt64(account.Status) != consts.AccountStatus_Cancelling { - logger.Error("This account is not in cancelling status!") - ec = errcode.ErrCodeAccountNotInCancellingStatus - return - } - - // 更改数据库记录 - err = _DefaultAccountCancellation.OpUpdateByMidAndStatus( - ctx, - &account_cancellationproto.OpUpdateReq{ - AccountCancellation: &dbstruct.AccountCancellation{ - Mid: goproto.Int64(req.Mid), - Status: goproto.Int64(consts.AccountCancellationStatus_Aborted), - AbortTime: goproto.Int64(time.Now().Unix()), - }, - }, - consts.AccountCancellationStatus_Cancelling) - if err == qmgo.ErrNoSuchDocuments { - logger.Error("_DefaultAccountCancellation OpUpdate fail, req: %v, err: %v", util.ToJson(req), err) - ec = errcode.ErrCodeAccountCancellationNotExist - return - } + err := s.utilAbortAccountCancellation(ctx, req.BaseRequest.Mid) if err != nil { - logger.Error("_DefaultAccountCancellation OpUpdate fail, req: %v, err: %v", util.ToJson(req), err) + logger.Error("utilAbortAccountCancellation fail, err: %v", err) ec = errcode.ErrCodeAccountCancellationSrvFail return } - // 更改状态 - if err := _DefaultAccount.OpUpdateByMidAndStatus(ctx, - &accountproto.OpUpdateReq{ - Account: &dbstruct.Account{ - Mid: goproto.Int64(req.Mid), - Status: goproto.Int64(consts.AccountStatus_Normal), - }, - }, - consts.AccountStatus_Cancelling); err != nil { - logger.Error("_DefaultAccount OpUpdate fail, req: %v, err: %v", util.ToJson(req), err) - ec = errcode.ErrCodeAccountSrvFail - return - } - return } diff --git a/app/mix/service/apiservice_business_validation.go b/app/mix/service/apiservice_business_validation.go index bd54af06..66ad8175 100644 --- a/app/mix/service/apiservice_business_validation.go +++ b/app/mix/service/apiservice_business_validation.go @@ -281,6 +281,46 @@ func (s *Service) ApiAccountExpIncBusinessValidate(ctx *gin.Context, req *accoun return } +func (s *Service) ApiCancelAccountBusinessValidate(ctx *gin.Context, req *accountproto.ApiCancelReq) (account *dbstruct.Account, ec errcode.ErrCode) { + ec = errcode.ErrCodeLoginSrvOk + + // 1.业务校验 + result := businessvalidator.NewAuthBusinessValidator(ctx, req). + QueryAccount(_DefaultAccount.OpListByMid). + EnsureAccountExist(). + EnsureIsNotThisRole(consts.Streamer, errcode.ErrCodeAccountStreamerRoleCancellation). + EnsureIsInTheseRoles(consts.RolesAllowedToCancel, errcode.ErrCodeAccountNonUserRoleCancellation). + EnsureAccountIsAtThisStatus(consts.AccountStatus_Normal, errcode.ErrCodeAccountNotInNormalStatus). + Validate(). + Collect() + if ec = result[0].(errcode.ErrCode); ec != errcode.ErrCodeOk { + logger.Error("ApiAccountExpInc business validation failed") + return + } + + account, _ = result[1].(*dbstruct.Account) + + return +} + +func (s *Service) ApiAbortAccountCancellationBusinessValidate(ctx *gin.Context, req *accountproto.ApiAbortCancellationReq) (ec errcode.ErrCode) { + ec = errcode.ErrCodeLoginSrvOk + + // 1.业务校验 + result := businessvalidator.NewAuthBusinessValidator(ctx, req). + QueryAccount(_DefaultAccount.OpListByMid). + EnsureAccountExist(). + EnsureAccountIsAtThisStatus(consts.AccountStatus_Cancelling, errcode.ErrCodeAccountNotInCancellingStatus). + Validate(). + Collect() + if ec = result[0].(errcode.ErrCode); ec != errcode.ErrCodeOk { + logger.Error("ApiAccountExpInc business validation failed") + return + } + + return +} + // AccountRelation func (s *Service) ApiCreateAccountRelationBusinessValidate(ctx *gin.Context, req *accountrelationproto.ApiCreateReq) (ec errcode.ErrCode) { ec = errcode.ErrCodeLoginSrvOk diff --git a/app/mix/service/business_validator/auth.go b/app/mix/service/business_validator/auth.go index 9e558cb5..e193de4d 100644 --- a/app/mix/service/business_validator/auth.go +++ b/app/mix/service/business_validator/auth.go @@ -113,8 +113,21 @@ func (a *AuthBusinessValidator) EnsureAccountExist() *AuthBusinessValidator { return a } +func (a *AuthBusinessValidator) EnsureAccountIsAtThisStatus(status int64, ecs ...errcode.ErrCode) *AuthBusinessValidator { + a.oplist = append(a.oplist, func() { + if a.account.GetStatus() != status { + if len(ecs) > 0 { + a.ec = ecs[0] + } else { + a.ec = errcode.ErrCodeAccountNotInNormalStatus + } + } + }) + return a +} + // 角色鉴权 -func (a *AuthBusinessValidator) EnsureIsThisRole(role int64) *AuthBusinessValidator { +func (a *AuthBusinessValidator) EnsureIsThisRole(role int64, ecs ...errcode.ErrCode) *AuthBusinessValidator { a.oplist = append(a.oplist, func() { accountRole := util.DerefInt64(a.account.Role) @@ -124,7 +137,11 @@ func (a *AuthBusinessValidator) EnsureIsThisRole(role int64) *AuthBusinessValida if accountRole != role { logger.Error("Insufficient privileges of role: %v, this operation is %v-execute-only", consts.RoleNameMap[role]) - a.ec = errcode.ErrCodeRolePrivilegesNotEnough + if len(ecs) > 0 { + a.ec = ecs[0] + } else { + a.ec = errcode.ErrCodeRolePrivilegesNotEnough + } return } }) @@ -132,7 +149,7 @@ func (a *AuthBusinessValidator) EnsureIsThisRole(role int64) *AuthBusinessValida } // 角色鉴权 -func (a *AuthBusinessValidator) EnsureIsInTheseRoles(roles []int64) *AuthBusinessValidator { +func (a *AuthBusinessValidator) EnsureIsInTheseRoles(roles []int64, ecs ...errcode.ErrCode) *AuthBusinessValidator { a.oplist = append(a.oplist, func() { accountRole := util.DerefInt64(a.account.Role) @@ -153,7 +170,11 @@ func (a *AuthBusinessValidator) EnsureIsInTheseRoles(roles []int64) *AuthBusines roleNames[i] = consts.RoleNameMap[role] } logger.Error("Insufficient privileges of role: %v, this operation is %v-execute-only", roleNames) - a.ec = errcode.ErrCodeRolePrivilegesNotEnough + if len(ecs) > 0 { + a.ec = ecs[0] + } else { + a.ec = errcode.ErrCodeRolePrivilegesNotEnough + } return } }) @@ -161,14 +182,18 @@ func (a *AuthBusinessValidator) EnsureIsInTheseRoles(roles []int64) *AuthBusines } // 角色鉴权 -func (a *AuthBusinessValidator) EnsureIsNotThisRole(role int64) *AuthBusinessValidator { +func (a *AuthBusinessValidator) EnsureIsNotThisRole(role int64, ecs ...errcode.ErrCode) *AuthBusinessValidator { a.oplist = append(a.oplist, func() { accountRole := util.DerefInt64(a.account.Role) if accountRole == role { logger.Error("Insufficient privileges of role: %v, this operation to %v is not permitted", consts.RoleNameMap[role]) - a.ec = errcode.ErrCodeRolePrivilegesNotEnough + if len(ecs) > 0 { + a.ec = ecs[0] + } else { + a.ec = errcode.ErrCodeRolePrivilegesNotEnough + } return } }) diff --git a/app/mix/service/utilservice.go b/app/mix/service/utilservice.go index 0c80440b..2983e0e1 100644 --- a/app/mix/service/utilservice.go +++ b/app/mix/service/utilservice.go @@ -9,6 +9,7 @@ import ( "service/api/interfaces" "service/api/message/request" accountproto "service/api/proto/account/proto" + account_cancellationproto "service/api/proto/account_cancellation/proto" accountrelationproto "service/api/proto/accountrelation/proto" contact_customer_service_sessionproto "service/api/proto/contact_customer_service_session/proto" imageauditproto "service/api/proto/imageaudit/proto" @@ -2208,3 +2209,35 @@ func (s *Service) UtilEncryptVideosForZoneMomentVOs(ctx *gin.Context, list []*zo } } } + +func (s *Service) utilAbortAccountCancellation(ctx *gin.Context, mid int64) error { + // 更改数据库记录 + err := _DefaultAccountCancellation.OpUpdateByMidAndStatus( + ctx, + &account_cancellationproto.OpUpdateReq{ + AccountCancellation: &dbstruct.AccountCancellation{ + Mid: goproto.Int64(mid), + Status: goproto.Int64(consts.AccountCancellationStatus_Aborted), + AbortTime: goproto.Int64(time.Now().Unix()), + }, + }, + consts.AccountCancellationStatus_Cancelling) + if err != nil { + logger.Error("_DefaultAccountCancellation OpUpdate fail, mid: %v, err: %v", mid, err) + return err + } + + // 更改状态 + if err := _DefaultAccount.OpUpdateByMidAndStatus(ctx, + &accountproto.OpUpdateReq{ + Account: &dbstruct.Account{ + Mid: goproto.Int64(mid), + Status: goproto.Int64(consts.AccountStatus_Normal), + }, + }, + consts.AccountStatus_Cancelling); err != nil { + logger.Error("_DefaultAccount OpUpdate fail, mid: %v, err: %v", mid, err) + return err + } + return nil +} diff --git a/dbstruct/account.go b/dbstruct/account.go index 198c621c..6ea1922e 100644 --- a/dbstruct/account.go +++ b/dbstruct/account.go @@ -88,6 +88,13 @@ func (p *Account) GetRole() int64 { return *p.Role } +func (p *Account) GetStatus() int64 { + if p == nil || p.Status == nil { + return -1 + } + return *p.Status +} + // StreamerAcct 用户结构 type StreamerAcct struct { Mid *int64 `json:"mid" bson:"_id"` // 用户表Id