mirror of
				https://github.com/continew-org/continew-admin.git
				synced 2025-10-31 22:57:17 +08:00 
			
		
		
		
	新增:新增修改密码功能,并优化部分以往代码
This commit is contained in:
		| @@ -0,0 +1,33 @@ | ||||
| /* | ||||
|  * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
|  | ||||
| package top.charles7c.cnadmin.common.consts; | ||||
|  | ||||
| import lombok.AccessLevel; | ||||
| import lombok.NoArgsConstructor; | ||||
|  | ||||
| /** | ||||
|  * @author Charles7c | ||||
|  * @since 2023/1/10 20:06 | ||||
|  */ | ||||
| @NoArgsConstructor(access = AccessLevel.PRIVATE) | ||||
| public class RegExpConstants { | ||||
|  | ||||
|     /** | ||||
|      * 密码正则(必须包含字母和数字的组合,可以使用特殊字符,长度在6-32之间) | ||||
|      */ | ||||
|     public static final String PASSWORD = "^(?=.*\\d)(?=.*[a-z]).{6,32}$"; | ||||
| } | ||||
| @@ -23,6 +23,9 @@ import cn.hutool.core.codec.Base64; | ||||
| import cn.hutool.crypto.SecureUtil; | ||||
| import cn.hutool.crypto.asymmetric.KeyType; | ||||
|  | ||||
| import top.charles7c.cnadmin.common.config.properties.RsaProperties; | ||||
| import top.charles7c.cnadmin.common.util.validate.ValidationUtils; | ||||
|  | ||||
| /** | ||||
|  * 加密/解密工具类 | ||||
|  * | ||||
| @@ -45,6 +48,19 @@ public class SecureUtils { | ||||
|         return Base64.encode(SecureUtil.rsa(null, publicKey).encrypt(data, KeyType.PublicKey)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 私钥解密 | ||||
|      * | ||||
|      * @param data | ||||
|      *            要解密的内容(Base64 加密过) | ||||
|      * @return 解密后的内容 | ||||
|      */ | ||||
|     public static String decryptByRsaPrivateKey(String data) { | ||||
|         String privateKey = RsaProperties.PRIVATE_KEY; | ||||
|         ValidationUtils.exIfBlank(privateKey, "请配置 RSA 私钥"); | ||||
|         return decryptByRsaPrivateKey(data, privateKey); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 私钥解密 | ||||
|      * | ||||
|   | ||||
| @@ -44,9 +44,9 @@ public class LoginRequest implements Serializable { | ||||
|     private String username; | ||||
|  | ||||
|     /** | ||||
|      * 密码 | ||||
|      * 密码(加密后) | ||||
|      */ | ||||
|     @Schema(description = "密码") | ||||
|     @Schema(description = "密码(加密后)") | ||||
|     @NotBlank(message = "密码不能为空") | ||||
|     private String password; | ||||
|  | ||||
|   | ||||
| @@ -0,0 +1,52 @@ | ||||
| /* | ||||
|  * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
|  | ||||
| package top.charles7c.cnadmin.system.model.request; | ||||
|  | ||||
| import java.io.Serializable; | ||||
|  | ||||
| import javax.validation.constraints.NotBlank; | ||||
|  | ||||
| import lombok.Data; | ||||
|  | ||||
| import io.swagger.v3.oas.annotations.media.Schema; | ||||
|  | ||||
| /** | ||||
|  * 修改密码信息 | ||||
|  * | ||||
|  * @author Charles7c | ||||
|  * @since 2023/1/9 23:28 | ||||
|  */ | ||||
| @Data | ||||
| @Schema(description = "修改密码信息") | ||||
| public class UpdatePasswordRequest implements Serializable { | ||||
|  | ||||
|     private static final long serialVersionUID = 1L; | ||||
|  | ||||
|     /** | ||||
|      * 当前密码(加密后) | ||||
|      */ | ||||
|     @Schema(description = "当前密码(加密后)") | ||||
|     @NotBlank(message = "当前密码不能为空") | ||||
|     private String oldPassword; | ||||
|  | ||||
|     /** | ||||
|      * 新密码(加密后) | ||||
|      */ | ||||
|     @Schema(description = "新密码(加密后)") | ||||
|     @NotBlank(message = "新密码不能为空") | ||||
|     private String newPassword; | ||||
| } | ||||
| @@ -55,4 +55,16 @@ public interface UserService { | ||||
|      *            用户信息 | ||||
|      */ | ||||
|     void update(SysUser user); | ||||
|  | ||||
|     /** | ||||
|      * 修改密码 | ||||
|      * | ||||
|      * @param oldPassword | ||||
|      *            当前密码 | ||||
|      * @param newPassword | ||||
|      *            新密码 | ||||
|      * @param userId | ||||
|      *            用户 ID | ||||
|      */ | ||||
|     void updatePassword(String oldPassword, String newPassword, Long userId); | ||||
| } | ||||
|   | ||||
| @@ -17,6 +17,7 @@ | ||||
| package top.charles7c.cnadmin.system.service.impl; | ||||
|  | ||||
| import java.io.File; | ||||
| import java.time.LocalDateTime; | ||||
|  | ||||
| import lombok.RequiredArgsConstructor; | ||||
|  | ||||
| @@ -34,8 +35,10 @@ import cn.hutool.core.util.StrUtil; | ||||
| import top.charles7c.cnadmin.common.config.properties.LocalStorageProperties; | ||||
| import top.charles7c.cnadmin.common.model.dto.LoginUser; | ||||
| import top.charles7c.cnadmin.common.util.FileUtils; | ||||
| import top.charles7c.cnadmin.common.util.SecureUtils; | ||||
| import top.charles7c.cnadmin.common.util.helper.LoginHelper; | ||||
| import top.charles7c.cnadmin.common.util.validate.CheckUtils; | ||||
| import top.charles7c.cnadmin.common.util.validate.ValidationUtils; | ||||
| import top.charles7c.cnadmin.system.mapper.UserMapper; | ||||
| import top.charles7c.cnadmin.system.model.entity.SysUser; | ||||
| import top.charles7c.cnadmin.system.service.UserService; | ||||
| @@ -91,9 +94,43 @@ public class UserServiceImpl implements UserService { | ||||
|         userMapper.updateById(user); | ||||
|  | ||||
|         // 更新登录用户信息 | ||||
|         SysUser sysUser = userMapper.selectById(user.getUserId()); | ||||
|         SysUser sysUser = this.getById(user.getUserId()); | ||||
|         LoginUser loginUser = LoginHelper.getLoginUser(); | ||||
|         BeanUtil.copyProperties(sysUser, loginUser); | ||||
|         LoginHelper.updateLoginUser(loginUser); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     @Transactional(rollbackFor = Exception.class) | ||||
|     public void updatePassword(String oldPassword, String newPassword, Long userId) { | ||||
|         SysUser sysUser = this.getById(userId); | ||||
|         ValidationUtils.exIfNotEqual(sysUser.getPassword(), SecureUtils.md5Salt(oldPassword, userId.toString()), | ||||
|             "当前密码错误"); | ||||
|  | ||||
|         // 更新密码和密码重置时间 | ||||
|         LocalDateTime now = LocalDateTime.now(); | ||||
|         userMapper.update(null, | ||||
|             new LambdaUpdateWrapper<SysUser>() | ||||
|                 .set(SysUser::getPassword, SecureUtils.md5Salt(newPassword, userId.toString())) | ||||
|                 .set(SysUser::getPwdResetTime, now).eq(SysUser::getUserId, userId)); | ||||
|  | ||||
|         // 更新登录用户信息 | ||||
|         LoginUser loginUser = LoginHelper.getLoginUser(); | ||||
|         loginUser.setPwdResetTime(now); | ||||
|         LoginHelper.updateLoginUser(loginUser); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 根据 ID 查询 | ||||
|      * | ||||
|      * @param userId | ||||
|      *            用户 ID | ||||
|      * @return 用户信息 | ||||
|      */ | ||||
|     private SysUser getById(Long userId) { | ||||
|         ValidationUtils.exIfNull(userId, "用户不存在"); | ||||
|         SysUser sysUser = userMapper.selectById(userId); | ||||
|         ValidationUtils.exIfNull(sysUser, String.format("ID为 [%s] 的用户已不存在", userId)); | ||||
|         return sysUser; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -19,4 +19,12 @@ export interface UpdateBasicInfoReq { | ||||
| } | ||||
| export function updateBasicInfo(req: UpdateBasicInfoReq) { | ||||
|   return axios.patch('/system/user/center/basic/info', req); | ||||
| } | ||||
|  | ||||
| export interface UpdatePasswordReq { | ||||
|   oldPassword: string; | ||||
|   newPassword: string; | ||||
| } | ||||
| export function updatePassword(req: UpdatePasswordReq) { | ||||
|   return axios.patch('/system/user/center/password', req); | ||||
| } | ||||
| @@ -105,9 +105,9 @@ | ||||
|   const loginConfig = useStorage('login-config', { | ||||
|     rememberMe: true, | ||||
|     username: 'admin', // 演示默认值 | ||||
|     password: '123456', // 演示默认值 | ||||
|     password: 'admin123', // 演示默认值 | ||||
|     // username: !debug ? '' : 'admin', // 演示默认值 | ||||
|     // password: !debug ? '' : '123456', // 演示默认值 | ||||
|     // password: !debug ? '' : 'admin123', // 演示默认值 | ||||
|   }); | ||||
|  | ||||
|   const loginForm = reactive({ | ||||
|   | ||||
| @@ -19,6 +19,7 @@ | ||||
|       <a-input | ||||
|         v-model="formData.username" | ||||
|         :placeholder="$t('userCenter.basicInfo.placeholder.username')" | ||||
|         size="large" | ||||
|         max-length="50" | ||||
|       /> | ||||
|     </a-form-item> | ||||
| @@ -35,6 +36,7 @@ | ||||
|       <a-input | ||||
|         v-model="formData.nickname" | ||||
|         :placeholder="$t('userCenter.basicInfo.placeholder.nickname')" | ||||
|         size="large" | ||||
|         max-length="32" | ||||
|       /> | ||||
|     </a-form-item> | ||||
|   | ||||
| @@ -1,10 +1,85 @@ | ||||
| <template> | ||||
|   <a-modal v-model:visible="updatePasswordVisible" :title="$t('userCenter.SecuritySettings.form.password.modal.title')" @cancel="handleCancelUpdatePassword" @before-ok="handleBeforeOkUpdatePassword"> | ||||
|     <a-form | ||||
|       ref="formPasswordRef" | ||||
|       :model="formPasswordData" | ||||
|     > | ||||
|       <a-form-item | ||||
|         field="oldPassword" | ||||
|         :rules="{ required: true, message: $t('userCenter.SecuritySettings.form.password.oldPassword.placeholder') }" | ||||
|         :validate-trigger="['change', 'blur']" | ||||
|         :label="$t('userCenter.SecuritySettings.form.password.oldPassword.label')" | ||||
|       > | ||||
|         <a-input-password | ||||
|           v-model="formPasswordData.oldPassword" | ||||
|           :placeholder="$t('userCenter.SecuritySettings.form.password.oldPassword.placeholder')" | ||||
|           size="large" | ||||
|           allow-clear | ||||
|           max-length="50" | ||||
|         > | ||||
|         </a-input-password> | ||||
|       </a-form-item> | ||||
|       <a-form-item | ||||
|         field="newPassword" | ||||
|         :rules="[ | ||||
|           { | ||||
|             required: true, | ||||
|             message: $t('userCenter.SecuritySettings.form.password.error.newPassword.required'), | ||||
|           }, | ||||
|           { | ||||
|             match: /^(?=.*\d)(?=.*[a-z]).{6,32}$/, | ||||
|             message: $t('userCenter.SecuritySettings.form.password.newPassword.placeholder') | ||||
|           } | ||||
|         ]" | ||||
|         :validate-trigger="['change', 'blur']" | ||||
|         :label="$t('userCenter.SecuritySettings.form.password.newPassword.label')" | ||||
|       > | ||||
|         <a-input-password | ||||
|           v-model="formPasswordData.newPassword" | ||||
|           :placeholder="$t('userCenter.SecuritySettings.form.password.newPassword.placeholder')" | ||||
|           size="large" | ||||
|           allow-clear | ||||
|           max-length="50" | ||||
|         > | ||||
|         </a-input-password> | ||||
|       </a-form-item> | ||||
|       <a-form-item | ||||
|         field="rePassword" | ||||
|         :rules="[ | ||||
|           { | ||||
|             required: true, | ||||
|             message: $t('userCenter.SecuritySettings.form.password.rePassword.placeholder'), | ||||
|           }, | ||||
|           { | ||||
|             validator: (value, callback) => { | ||||
|               if (value !== formPasswordData.newPassword) { | ||||
|                 callback($t('userCenter.SecuritySettings.form.password.error.rePassword.notequal')) | ||||
|               } else { | ||||
|                 callback() | ||||
|               } | ||||
|             } | ||||
|           } | ||||
|         ]" | ||||
|         :validate-trigger="['change', 'blur']" | ||||
|         :label="$t('userCenter.SecuritySettings.form.password.rePassword.label')" | ||||
|       > | ||||
|         <a-input-password | ||||
|           v-model="formPasswordData.rePassword" | ||||
|           :placeholder="$t('userCenter.SecuritySettings.form.password.rePassword.placeholder')" | ||||
|           size="large" | ||||
|           allow-clear | ||||
|           max-length="50" | ||||
|         > | ||||
|         </a-input-password> | ||||
|       </a-form-item> | ||||
|     </a-form> | ||||
|   </a-modal> | ||||
|   <a-list :bordered="false"> | ||||
|     <a-list-item> | ||||
|       <a-list-item-meta> | ||||
|         <template #avatar> | ||||
|           <a-typography-paragraph> | ||||
|             {{ $t('userCenter.SecuritySettings.form.label.password') }} | ||||
|             {{ $t('userCenter.SecuritySettings.label.password') }} | ||||
|           </a-typography-paragraph> | ||||
|         </template> | ||||
|         <template #description> | ||||
| @@ -17,7 +92,7 @@ | ||||
|             </a-typography-paragraph> | ||||
|           </div> | ||||
|           <div class="operation"> | ||||
|             <a-link> | ||||
|             <a-link @click="handleClickUpdatePassword"> | ||||
|               {{ $t('userCenter.SecuritySettings.button.update') }} | ||||
|             </a-link> | ||||
|           </div> | ||||
| @@ -76,9 +151,49 @@ | ||||
| </template> | ||||
|  | ||||
| <script lang="ts" setup> | ||||
|   import { reactive, ref } from 'vue'; | ||||
|   import { useLoginStore } from '@/store'; | ||||
|   import { FormInstance } from "@arco-design/web-vue/es/form"; | ||||
|   import useLoading from "@/hooks/loading"; | ||||
|   import { updatePassword } from "@/api/system/user-center"; | ||||
|   import { Message } from "@arco-design/web-vue"; | ||||
|   import { encryptByRsa } from "@/utils/encrypt"; | ||||
|  | ||||
|   const { loading, setLoading } = useLoading(); | ||||
|   const loginStore = useLoginStore(); | ||||
|   const formPasswordRef = ref<FormInstance>(); | ||||
|   const updatePasswordVisible = ref(false); | ||||
|   const formPasswordData = reactive({ | ||||
|     oldPassword: '', | ||||
|     newPassword: '', | ||||
|     rePassword: '', | ||||
|   }); | ||||
|  | ||||
|   const handleClickUpdatePassword = () => { | ||||
|     updatePasswordVisible.value = true; | ||||
|   }; | ||||
|  | ||||
|   const handleBeforeOkUpdatePassword = async () => { | ||||
|     const errors = await formPasswordRef.value?.validate(); | ||||
|     if (loading.value) return false; | ||||
|     if (errors) return false; | ||||
|     setLoading(true); | ||||
|     try { | ||||
|       const res = await updatePassword({ | ||||
|         oldPassword: encryptByRsa(formPasswordData.oldPassword) || '', | ||||
|         newPassword: encryptByRsa(formPasswordData.newPassword) || '', | ||||
|       }); | ||||
|       if (res.success) Message.success(res.msg); | ||||
|     } finally { | ||||
|       setLoading(false); | ||||
|     } | ||||
|     return true; | ||||
|   }; | ||||
|  | ||||
|   const handleCancelUpdatePassword = () => { | ||||
|     updatePasswordVisible.value = false; | ||||
|     formPasswordRef.value?.resetFields() | ||||
|   }; | ||||
| </script> | ||||
|  | ||||
| <style scoped lang="less"> | ||||
|   | ||||
| @@ -18,9 +18,19 @@ export default { | ||||
|   'userCenter.reset': 'Reset', | ||||
|  | ||||
|   'userCenter.tab.securitySettings': 'Security Settings', | ||||
|   'userCenter.SecuritySettings.form.label.password': 'Login Password', | ||||
|   'userCenter.SecuritySettings.label.password': 'Login Password', | ||||
|   'userCenter.SecuritySettings.placeholder.password': | ||||
|     'You have not set a password yet. The password must contain at least six letters, digits, and special characters except Spaces.', | ||||
|   'userCenter.SecuritySettings.form.password.modal.title': 'Update login password', | ||||
|   'userCenter.SecuritySettings.form.password.oldPassword.label': 'Old password', | ||||
|   'userCenter.SecuritySettings.form.password.oldPassword.placeholder': 'Please enter old password', | ||||
|   'userCenter.SecuritySettings.form.password.newPassword.label': 'New password', | ||||
|   'userCenter.SecuritySettings.form.password.error.newPassword.required': 'Please enter new password', | ||||
|   'userCenter.SecuritySettings.form.password.newPassword.placeholder': 'Password contains 6 to 32 digits and letters', | ||||
|   'userCenter.SecuritySettings.form.password.rePassword.label': 'Confirm password', | ||||
|   'userCenter.SecuritySettings.form.password.rePassword.placeholder': 'Please enter new password again', | ||||
|   'userCenter.SecuritySettings.form.password.error.rePassword.notequal': 'Two passwords are different', | ||||
|  | ||||
|   'userCenter.SecuritySettings.form.label.phone': 'Phone', | ||||
|   'userCenter.SecuritySettings.placeholder.phone': | ||||
|     'You have not set a phone yet. The phone binding can be used to retrieve passwords and receive notifications and SMS login.', | ||||
|   | ||||
| @@ -18,9 +18,19 @@ export default { | ||||
|   'userCenter.reset': '重置', | ||||
|  | ||||
|   'userCenter.tab.securitySettings': '安全设置', | ||||
|   'userCenter.SecuritySettings.form.label.password': '登录密码', | ||||
|   'userCenter.SecuritySettings.label.password': '登录密码', | ||||
|   'userCenter.SecuritySettings.placeholder.password': | ||||
|     '您暂未设置密码,密码至少6位字符,支持数字、字母和除空格外的特殊字符。', | ||||
|   'userCenter.SecuritySettings.form.password.modal.title': '修改登录密码', | ||||
|   'userCenter.SecuritySettings.form.password.oldPassword.label': '当前密码', | ||||
|   'userCenter.SecuritySettings.form.password.oldPassword.placeholder': '请输入当前密码', | ||||
|   'userCenter.SecuritySettings.form.password.newPassword.label': '新密码', | ||||
|   'userCenter.SecuritySettings.form.password.error.newPassword.required': '请输入新密码', | ||||
|   'userCenter.SecuritySettings.form.password.newPassword.placeholder': '密码长度6到32位,同时包含数字和字母', | ||||
|   'userCenter.SecuritySettings.form.password.rePassword.label': '确认新密码', | ||||
|   'userCenter.SecuritySettings.form.password.rePassword.placeholder': '请再次输入新密码', | ||||
|   'userCenter.SecuritySettings.form.password.error.rePassword.notequal': '两次输入的密码不一致', | ||||
|  | ||||
|   'userCenter.SecuritySettings.form.label.phone': '安全手机', | ||||
|   'userCenter.SecuritySettings.placeholder.phone': | ||||
|     '您暂未设置手机号,绑定手机号可以用来找回密码、接收通知、短信登录等。', | ||||
|   | ||||
| @@ -36,7 +36,6 @@ import top.charles7c.cnadmin.auth.model.request.LoginRequest; | ||||
| import top.charles7c.cnadmin.auth.model.vo.LoginVO; | ||||
| import top.charles7c.cnadmin.auth.model.vo.UserInfoVO; | ||||
| import top.charles7c.cnadmin.auth.service.LoginService; | ||||
| import top.charles7c.cnadmin.common.config.properties.RsaProperties; | ||||
| import top.charles7c.cnadmin.common.model.dto.LoginUser; | ||||
| import top.charles7c.cnadmin.common.model.vo.R; | ||||
| import top.charles7c.cnadmin.common.util.ExceptionUtils; | ||||
| @@ -72,8 +71,8 @@ public class LoginController { | ||||
|         ValidationUtils.exIfCondition(() -> !captcha.equalsIgnoreCase(loginRequest.getCaptcha()), "验证码错误"); | ||||
|  | ||||
|         // 用户登录 | ||||
|         String rawPassword = ExceptionUtils | ||||
|             .exToNull(() -> SecureUtils.decryptByRsaPrivateKey(loginRequest.getPassword(), RsaProperties.PRIVATE_KEY)); | ||||
|         String rawPassword = | ||||
|             ExceptionUtils.exToNull(() -> SecureUtils.decryptByRsaPrivateKey(loginRequest.getPassword())); | ||||
|         ValidationUtils.exIfBlank(rawPassword, "密码解密失败"); | ||||
|         String token = loginService.login(loginRequest.getUsername(), rawPassword); | ||||
|         return R.ok(new LoginVO().setToken(token)); | ||||
|   | ||||
| @@ -30,15 +30,20 @@ import org.springframework.web.multipart.MultipartFile; | ||||
|  | ||||
| import cn.hutool.core.bean.BeanUtil; | ||||
| import cn.hutool.core.io.file.FileNameUtil; | ||||
| import cn.hutool.core.util.ReUtil; | ||||
| import cn.hutool.core.util.StrUtil; | ||||
|  | ||||
| import top.charles7c.cnadmin.common.config.properties.LocalStorageProperties; | ||||
| import top.charles7c.cnadmin.common.consts.FileConstants; | ||||
| import top.charles7c.cnadmin.common.consts.RegExpConstants; | ||||
| import top.charles7c.cnadmin.common.model.vo.R; | ||||
| import top.charles7c.cnadmin.common.util.ExceptionUtils; | ||||
| import top.charles7c.cnadmin.common.util.SecureUtils; | ||||
| import top.charles7c.cnadmin.common.util.helper.LoginHelper; | ||||
| import top.charles7c.cnadmin.common.util.validate.ValidationUtils; | ||||
| import top.charles7c.cnadmin.system.model.entity.SysUser; | ||||
| import top.charles7c.cnadmin.system.model.request.UpdateBasicInfoRequest; | ||||
| import top.charles7c.cnadmin.system.model.request.UpdatePasswordRequest; | ||||
| import top.charles7c.cnadmin.system.model.vo.AvatarVO; | ||||
| import top.charles7c.cnadmin.system.service.UserService; | ||||
|  | ||||
| @@ -85,4 +90,24 @@ public class UserCenterController { | ||||
|         userService.update(user); | ||||
|         return R.ok("修改成功"); | ||||
|     } | ||||
|  | ||||
|     @Operation(summary = "修改密码", description = "修改用户登录密码") | ||||
|     @PatchMapping("/password") | ||||
|     public R updatePassword(@Validated @RequestBody UpdatePasswordRequest updatePasswordRequest) { | ||||
|         // 解密 | ||||
|         String rawOldPassword = | ||||
|             ExceptionUtils.exToNull(() -> SecureUtils.decryptByRsaPrivateKey(updatePasswordRequest.getOldPassword())); | ||||
|         ValidationUtils.exIfBlank(rawOldPassword, "当前密码解密失败"); | ||||
|         String rawNewPassword = | ||||
|             ExceptionUtils.exToNull(() -> SecureUtils.decryptByRsaPrivateKey(updatePasswordRequest.getNewPassword())); | ||||
|         ValidationUtils.exIfBlank(rawNewPassword, "新密码解密失败"); | ||||
|  | ||||
|         // 校验 | ||||
|         ValidationUtils.exIfCondition(() -> !ReUtil.isMatch(RegExpConstants.PASSWORD, rawNewPassword), | ||||
|             "密码长度6到32位,同时包含数字和字母"); | ||||
|  | ||||
|         // 修改密码 | ||||
|         userService.updatePassword(rawOldPassword, rawNewPassword, LoginHelper.getUserId()); | ||||
|         return R.ok("修改成功"); | ||||
|     } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user