diff --git a/.gitea/workflows/cd-test.yml b/.gitea/workflows/cd-test.yml index a0b7696..e8a6c0e 100644 --- a/.gitea/workflows/cd-test.yml +++ b/.gitea/workflows/cd-test.yml @@ -51,4 +51,6 @@ jobs: docker pull ${{ vars.REGISTRY }}/lone/support:latest docker pull ${{ vars.REGISTRY }}/lone/percutaneous:latest docker pull ${{ vars.REGISTRY }}/lone/water:latest + docker pull ${{ vars.REGISTRY }}/lone/store:latest + docker pull ${{ vars.REGISTRY }}/lone/analysis:latest docker compose up -d diff --git a/pkg/utils/tools.go b/pkg/utils/tools.go index e8946ac..ccaf02f 100644 --- a/pkg/utils/tools.go +++ b/pkg/utils/tools.go @@ -533,33 +533,6 @@ func GetStringByMap(m map[string]interface{}, key string) string { return "" } -func BuildImageURL(data interface{}) interface{} { - switch v := data.(type) { - - case map[string]interface{}: - for key, val := range v { - v[key] = BuildImageURL(val) - } - return v - - case []interface{}: - for i, val := range v { - v[i] = BuildImageURL(val) - } - return v - - case string: - if v == "" { - return v - } - base := GetConfigString("upload.image_base_url") - return fmt.Sprintf("%s/%s", strings.TrimRight(base, "/"), strings.TrimLeft(v, "/")) - - default: - return v - } -} - func ParseIntArray(value string) ([]int, error) { var result []int diff --git a/rpc/user/pb/user.pb.go b/rpc/user/pb/user.pb.go index 92f1417..bef724c 100644 --- a/rpc/user/pb/user.pb.go +++ b/rpc/user/pb/user.pb.go @@ -1995,11 +1995,11 @@ func (x *UpdateReq) GetRealName() string { } type PasswordReq struct { - state protoimpl.MessageState `protogen:"open.v1"` - OldPassword string `protobuf:"bytes,1,opt,name=old_password,json=oldPassword,proto3" json:"old_password,omitempty"` - Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"` + ConfirmPassword string `protobuf:"bytes,3,opt,name=confirm_password,json=confirmPassword,proto3" json:"confirm_password,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *PasswordReq) Reset() { @@ -2032,16 +2032,16 @@ func (*PasswordReq) Descriptor() ([]byte, []int) { return file_user_user_proto_rawDescGZIP(), []int{31} } -func (x *PasswordReq) GetOldPassword() string { +func (x *PasswordReq) GetPassword() string { if x != nil { - return x.OldPassword + return x.Password } return "" } -func (x *PasswordReq) GetPassword() string { +func (x *PasswordReq) GetConfirmPassword() string { if x != nil { - return x.Password + return x.ConfirmPassword } return "" } @@ -2405,10 +2405,10 @@ const file_user_user_proto_rawDesc = "" + "\x06gender\x18\x03 \x01(\rR\x06gender\x12\x1a\n" + "\bbirthday\x18\x04 \x01(\tR\bbirthday\x12\x16\n" + "\x06mobile\x18\x05 \x01(\tR\x06mobile\x12\x1b\n" + - "\treal_name\x18\x06 \x01(\tR\brealName\"L\n" + - "\vPasswordReq\x12!\n" + - "\fold_password\x18\x01 \x01(\tR\voldPassword\x12\x1a\n" + - "\bpassword\x18\x02 \x01(\tR\bpassword\"V\n" + + "\treal_name\x18\x06 \x01(\tR\brealName\"T\n" + + "\vPasswordReq\x12\x1a\n" + + "\bpassword\x18\x02 \x01(\tR\bpassword\x12)\n" + + "\x10confirm_password\x18\x03 \x01(\tR\x0fconfirmPassword\"V\n" + "\tClientReq\x12\x12\n" + "\x04name\x18\x01 \x01(\tR\x04name\x12\x12\n" + "\x04type\x18\x02 \x01(\tR\x04type\x12!\n" + diff --git a/rpc/user/user.pb b/rpc/user/user.pb index 62fccce..83da1f0 100644 Binary files a/rpc/user/user.pb and b/rpc/user/user.pb differ diff --git a/rpc/user/user.proto b/rpc/user/user.proto index c9dff6b..400f553 100644 --- a/rpc/user/user.proto +++ b/rpc/user/user.proto @@ -297,8 +297,8 @@ message UpdateReq { } message PasswordReq { - string old_password = 1; string password = 2; + string confirm_password = 3; } message ClientReq { diff --git a/services/analysis/internal/logic/analysisstore/storeUserListLogic.go b/services/analysis/internal/logic/analysisstore/storeUserListLogic.go index 17f10a5..f9be4da 100644 --- a/services/analysis/internal/logic/analysisstore/storeUserListLogic.go +++ b/services/analysis/internal/logic/analysisstore/storeUserListLogic.go @@ -122,14 +122,14 @@ func (l *StoreUserListLogic) StoreUserList(in *analysis.StoreUserListReq) (*anal StoreId: row.StoreId, Name: profile.Name, Nickname: profile.Name, - Avatar: imageURL(profile.Avatar), + Avatar: profile.Avatar, Mobile: decryptMobile(profile.Mobile), Gender: int(profile.Gender), Birthday: profile.Birthday, Age: utils.CalcAgeStr(profile.Birthday), } if logRow, ok := logs[row.UserId]; ok { - item.Cover = imageURL(logRow.Cover) + item.Cover = logRow.Cover item.DetectionNumber = logRow.DetectionNumber item.DetectionTime = logRow.DetectionTime.Format(detectionTimeLayout) } diff --git a/services/analysis/internal/logic/analysisstore/storeView.go b/services/analysis/internal/logic/analysisstore/storeView.go index a43be06..b3e343f 100644 --- a/services/analysis/internal/logic/analysisstore/storeView.go +++ b/services/analysis/internal/logic/analysisstore/storeView.go @@ -45,7 +45,6 @@ func loadPassedStore(ctx context.Context, storeId int64) (*storepb.InfoResponse, } func skinStore(info *storepb.InfoResponse) dao.StoreSkinInfo { - img, _ := utils.BuildImageURL(info.Images).(string) return dao.StoreSkinInfo{ Id: info.Id, StoreName: info.Name, @@ -53,7 +52,7 @@ func skinStore(info *storepb.InfoResponse) dao.StoreSkinInfo { StoreUserMobile: utils.DecryptPhoneReplace(info.UserMobile), District: info.DistrictIds, Address: regionAddress(info), - StoreImg: img, + StoreImg: info.Images, StoreContact: info.Contact, StoreContent: info.Content, OpenTime: info.OpenTime, @@ -75,14 +74,6 @@ func regionAddress(info *storepb.InfoResponse) string { return strings.Join(parts, "") + info.Address } -func imageURL(path string) string { - if path == utils.StringEmpty { - return utils.StringEmpty - } - url, _ := utils.BuildImageURL(path).(string) - return url -} - func dateOnly(value string) string { if len(value) >= len("2006-01-02") { return value[:len("2006-01-02")] diff --git a/services/equipment/internal/logic/authorizationStoreItemsLogic.go b/services/equipment/internal/logic/authorizationStoreItemsLogic.go index ccff346..5937799 100644 --- a/services/equipment/internal/logic/authorizationStoreItemsLogic.go +++ b/services/equipment/internal/logic/authorizationStoreItemsLogic.go @@ -8,7 +8,7 @@ import ( "lone-services/services/equipment/internal/model" "strconv" - "lone-services/rpc/equipment/pb" + equipment "lone-services/rpc/equipment/pb" "lone-services/services/equipment/internal/svc" "github.com/zeromicro/go-zero/core/logx" diff --git a/services/user/internal/logic/passwordLogic.go b/services/user/internal/logic/passwordLogic.go index b26641f..ea86053 100644 --- a/services/user/internal/logic/passwordLogic.go +++ b/services/user/internal/logic/passwordLogic.go @@ -55,27 +55,6 @@ func (l *PasswordLogic) Password(in *user.PasswordReq) (*user.Response, error) { l.Errorf("password load user: %v", userErr) return failResponse(utils.ErrorNotFund), nil } - if row.Mobile == utils.StringEmpty { - return outResponse(utils.ErrorParams, "用户未绑定手机号,无法修改密码"), nil - } - - cred, credErr := findCredential(dao.CredentialTypePassword, row.Mobile, subjectType) - if credErr != nil { - l.Errorf("password find credential: %v", credErr) - return failResponse(utils.Fail), nil - } - if cred == nil || cred.UserId != loginUser.ID { - return outResponse(utils.ErrorNotFund, "密码凭证不存在"), nil - } - if cred.Status == dao.StatusDisabled { - return outResponse(utils.Fail, "登录凭证已禁用"), nil - } - if !utils.EqualsPassword(req.OldPassword, cred.Secret) { - return failResponse(utils.ErrorPwdError), nil - } - if req.OldPassword == req.Password { - return outResponse(utils.ErrorParams, "新密码不能与原密码相同"), nil - } hashed, hashErr := utils.EncryptPassword(req.Password) if hashErr != nil { @@ -83,21 +62,91 @@ func (l *PasswordLogic) Password(in *user.PasswordReq) (*user.Response, error) { return failResponse(utils.ErrorEncryptAesError), nil } + cred, credErr := findPasswordCredentialByUser(loginUser.ID, subjectType) + if credErr != nil { + l.Errorf("password find credential: %v", credErr) + return failResponse(utils.Fail), nil + } + credModel := model.UserCredentialModel{}.Init() - _, editErr := credModel.Edit(modelbase.Params{ - Eq: map[string]string{"id": strconv.FormatInt(cred.Id, utils.NumberTen)}, - }, map[string]interface{}{ - "secret": hashed, - "status": dao.StatusEnabled, - }) - if editErr != nil { - l.Errorf("password update: %v", editErr) + if cred != nil { + if cred.Status == dao.StatusDisabled { + return outResponse(utils.Fail, "登录凭证已禁用"), nil + } + if utils.EqualsPassword(req.Password, cred.Secret) { + return outResponse(utils.ErrorParams, "新密码不能与原密码相同"), nil + } + _, editErr := credModel.Edit(modelbase.Params{ + Eq: map[string]string{"id": strconv.FormatInt(cred.Id, utils.NumberTen)}, + }, map[string]interface{}{ + "secret": hashed, + }) + if editErr != nil { + l.Errorf("password update: %v", editErr) + return failResponse(utils.Fail), nil + } + return okResponse(nil), nil + } + + if row.Mobile == utils.StringEmpty { + return outResponse(utils.ErrorParams, "未设置手机号不能修改密码"), nil + } + + exist, existErr := findCredential(dao.CredentialTypePassword, row.Mobile, subjectType) + if existErr != nil { + l.Errorf("password find by mobile: %v", existErr) + return failResponse(utils.Fail), nil + } + if exist != nil && exist.UserId != loginUser.ID { + return outResponse(utils.Fail, "登录凭证已被其他用户占用"), nil + } + if exist != nil { + _, editErr := credModel.Edit(modelbase.Params{ + Eq: map[string]string{"id": strconv.FormatInt(exist.Id, utils.NumberTen)}, + }, map[string]interface{}{ + "secret": hashed, + }) + if editErr != nil { + l.Errorf("password update occupied: %v", editErr) + return failResponse(utils.Fail), nil + } + return okResponse(nil), nil + } + + if createErr := credModel.Create(&dao.UserCredential{ + UserId: loginUser.ID, + CredentialType: dao.CredentialTypePassword, + Identifier: row.Mobile, + Secret: hashed, + SubjectType: subjectType, + ExtraJson: dao.ExtraJsonEmpty, + Status: dao.StatusEnabled, + }); createErr != nil { + l.Errorf("password create: %v", createErr) return failResponse(utils.Fail), nil } return okResponse(nil), nil } +func findPasswordCredentialByUser(userId int64, subjectType string) (*dao.UserCredential, error) { + var cred dao.UserCredential + credModel := model.UserCredentialModel{}.Init() + if err := credModel.GetOne(modelbase.Params{ + Eq: map[string]string{ + "user_id": strconv.FormatInt(userId, utils.NumberTen), + "credential_type": dao.CredentialTypePassword, + "subject_type": subjectType, + }, + }, &cred); err != nil { + return nil, err + } + if cred.Id < utils.NumberOne { + return nil, nil + } + return &cred, nil +} + func (l *PasswordLogic) resolveSubjectType(loginUser utils.UserInfo) (string, error) { if loginUser.ClientCode != utils.StringEmpty { client, err := loadEnabledClient(loginUser.ClientCode) diff --git a/services/user/validator/user.go b/services/user/validator/user.go index fd496c9..f069126 100644 --- a/services/user/validator/user.go +++ b/services/user/validator/user.go @@ -81,17 +81,17 @@ func (p UpdateValidator) GetMessage() validate.ValidatorMessages { } type PasswordValidator struct { - OldPassword string `validate:"required,max=64"` - Password string `validate:"required,min=6,max=64"` + Password string `validate:"required,min=6,max=64"` + ConfirmPassword string `validate:"required,eqfield=Password"` } func (p PasswordValidator) GetMessage() validate.ValidatorMessages { return validate.ValidatorMessages{ - "OldPassword.required": "原密码不能为空", - "OldPassword.max": "原密码过长", - "Password.required": "新密码不能为空", - "Password.min": "新密码长度不能小于6位", - "Password.max": "新密码过长", + "Password.required": "新密码不能为空", + "Password.min": "新密码长度不能小于6位", + "Password.max": "新密码过长", + "ConfirmPassword.required": "确认密码不能为空", + "ConfirmPassword.eqfield": "确认密码与新密码不一致", } }