package logic import ( "context" "strconv" "lone-services/pkg/modelbase" "lone-services/pkg/utils" "lone-services/pkg/validate" user "lone-services/rpc/user/pb" "lone-services/services/user/internal/dao" "lone-services/services/user/internal/model" "lone-services/services/user/internal/svc" "lone-services/services/user/validator" "github.com/zeromicro/go-zero/core/logx" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "gorm.io/gorm" ) type UpdateMobileLogic struct { ctx context.Context svcCtx *svc.ServiceContext logx.Logger } func NewUpdateMobileLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UpdateMobileLogic { return &UpdateMobileLogic{ ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx), } } // UpdateMobile 内部:修改用户手机号,并同步 password 凭证的 identifier func (l *UpdateMobileLogic) UpdateMobile(in *user.UpdateMobileReq) (*user.UpdateMobileData, error) { var req validator.UpdateMobileValidator if msg := validate.ValidateFromProto(in, &req); msg != utils.StringEmpty { return nil, status.Error(codes.InvalidArgument, msg) } userModel := model.UserModel{}.Init() var row dao.UserRow if err := userModel.GetOne(modelbase.Params{ Eq: map[string]string{"id": strconv.FormatInt(req.UserId, utils.NumberTen)}, }, &row); err != nil { l.Errorf("update mobile get user: %v", err) return nil, status.Error(codes.Internal, utils.Fail.Msg) } if row.Id < utils.NumberOne { return nil, status.Error(codes.NotFound, utils.ErrorNotFund.Msg) } newEncrypt, encErr := utils.EncryptPhone(req.Mobile) if encErr != nil { l.Errorf("update mobile encrypt: %v", encErr) return nil, status.Error(codes.Internal, utils.ErrorEncryptAesError.Msg) } if newEncrypt == row.Mobile { return &user.UpdateMobileData{UserId: row.Id, Mobile: row.Mobile}, nil } var occupied dao.UserRow if err := userModel.GetOne(modelbase.Params{ Eq: map[string]string{"mobile": newEncrypt}, }, &occupied); err != nil { l.Errorf("update mobile unique check: %v", err) return nil, status.Error(codes.Internal, utils.Fail.Msg) } if occupied.Id > utils.NumberZero && occupied.Id != row.Id { return nil, status.Error(codes.AlreadyExists, utils.ErrorDataIsExist.Msg) } oldMobile := row.Mobile txErr := l.svcCtx.DB.WithContext(l.ctx).Transaction(func(tx *gorm.DB) error { um := model.UserModel{}.Init() um.Base = um.Base.WithTX(tx) if _, err := um.Edit(modelbase.Params{ Eq: map[string]string{"id": strconv.FormatInt(row.Id, utils.NumberTen)}, }, map[string]interface{}{"mobile": newEncrypt}); err != nil { return err } credModel := model.UserCredentialModel{}.Init() credModel.Base = credModel.Base.WithTX(tx) var cred dao.UserCredential if err := credModel.GetOne(modelbase.Params{ Eq: map[string]string{ "user_id": strconv.FormatInt(row.Id, utils.NumberTen), "credential_type": dao.CredentialTypePassword, "identifier": oldMobile, }, }, &cred); err != nil { return err } if cred.Id < utils.NumberOne { return nil } _, err := credModel.Edit(modelbase.Params{ Eq: map[string]string{"id": strconv.FormatInt(cred.Id, utils.NumberTen)}, }, map[string]interface{}{"identifier": newEncrypt}) return err }) if txErr != nil { l.Errorf("update mobile tx: %v", txErr) return nil, status.Error(codes.Internal, utils.Fail.Msg) } return &user.UpdateMobileData{UserId: row.Id, Mobile: newEncrypt}, nil }