refactor: 取消用户默认密码,改为表单填写密码

1.修复 Sonar 扫描问题
2.优化部分代码
This commit is contained in:
Charles7c 2024-02-02 23:44:21 +08:00
parent b9ce3f56f1
commit 3d77aa91ee
17 changed files with 111 additions and 61 deletions

View File

@ -46,11 +46,6 @@ public class SysConstants {
*/ */
public static final String ALL_PERMISSION = StringConstants.ASTERISK; public static final String ALL_PERMISSION = StringConstants.ASTERISK;
/**
* 默认密码
*/
public static final String DEFAULT_PASSWORD = "123456";
/** /**
* 账号登录 URI * 账号登录 URI
*/ */

View File

@ -0,0 +1,45 @@
/*
* 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.continew.admin.system.model.req;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* 用户密码重置信息
*
* @author Charles7c
* @since 2024/2/2 22:50
*/
@Data
@Schema(description = "用户密码重置信息")
public class UserPasswordResetReq implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 新密码加密
*/
@Schema(description = "新密码(加密)", example = "Gzc78825P5baH190lRuZFb9KJxRt/psN2jiyOMPoc5WRcCvneCwqDm3Q33BZY56EzyyVy7vQu7jQwYTK4j1+5w==")
@NotBlank(message = "新密码不能为空")
private String newPassword;
}

View File

@ -28,6 +28,7 @@ import top.charles7c.continew.admin.common.constant.RegexConstants;
import top.charles7c.continew.admin.common.enums.DisEnableStatusEnum; import top.charles7c.continew.admin.common.enums.DisEnableStatusEnum;
import top.charles7c.continew.admin.common.enums.GenderEnum; import top.charles7c.continew.admin.common.enums.GenderEnum;
import top.charles7c.continew.starter.extension.crud.model.req.BaseReq; import top.charles7c.continew.starter.extension.crud.model.req.BaseReq;
import top.charles7c.continew.starter.extension.crud.util.ValidateGroup;
import java.io.Serial; import java.io.Serial;
import java.util.List; import java.util.List;
@ -61,6 +62,13 @@ public class UserReq extends BaseReq {
@Pattern(regexp = RegexConstants.GENERAL_NAME, message = "昵称长度为 2 到 30 位,可以包含中文、字母、数字、下划线,短横线") @Pattern(regexp = RegexConstants.GENERAL_NAME, message = "昵称长度为 2 到 30 位,可以包含中文、字母、数字、下划线,短横线")
private String nickname; private String nickname;
/**
* 密码加密
*/
@Schema(description = "密码(加密)", example = "E7c72TH+LDxKTwavjM99W1MdI9Lljh79aPKiv3XB9MXcplhm7qJ1BJCj28yaflbdVbfc366klMtjLIWQGqb0qw==")
@NotBlank(message = "密码不能为空", groups = ValidateGroup.Crud.Add.class)
private String password;
/** /**
* 邮箱 * 邮箱
*/ */

View File

@ -20,6 +20,7 @@ import org.springframework.web.multipart.MultipartFile;
import top.charles7c.continew.admin.system.model.entity.UserDO; import top.charles7c.continew.admin.system.model.entity.UserDO;
import top.charles7c.continew.admin.system.model.query.UserQuery; import top.charles7c.continew.admin.system.model.query.UserQuery;
import top.charles7c.continew.admin.system.model.req.UserBasicInfoUpdateReq; import top.charles7c.continew.admin.system.model.req.UserBasicInfoUpdateReq;
import top.charles7c.continew.admin.system.model.req.UserPasswordResetReq;
import top.charles7c.continew.admin.system.model.req.UserReq; import top.charles7c.continew.admin.system.model.req.UserReq;
import top.charles7c.continew.admin.system.model.req.UserRoleUpdateReq; import top.charles7c.continew.admin.system.model.req.UserRoleUpdateReq;
import top.charles7c.continew.admin.system.model.resp.UserDetailResp; import top.charles7c.continew.admin.system.model.resp.UserDetailResp;
@ -92,9 +93,10 @@ public interface UserService extends BaseService<UserResp, UserDetailResp, UserQ
/** /**
* 重置密码 * 重置密码
* *
* @param id ID * @param req 重置信息
* @param id ID
*/ */
void resetPassword(Long id); void resetPassword(UserPasswordResetReq req, Long id);
/** /**
* 修改角色 * 修改角色

View File

@ -33,13 +33,13 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import top.charles7c.continew.admin.common.constant.CacheConstants; import top.charles7c.continew.admin.common.constant.CacheConstants;
import top.charles7c.continew.admin.common.constant.SysConstants;
import top.charles7c.continew.admin.common.enums.DisEnableStatusEnum; import top.charles7c.continew.admin.common.enums.DisEnableStatusEnum;
import top.charles7c.continew.admin.common.util.helper.LoginHelper; import top.charles7c.continew.admin.common.util.helper.LoginHelper;
import top.charles7c.continew.admin.system.mapper.UserMapper; import top.charles7c.continew.admin.system.mapper.UserMapper;
import top.charles7c.continew.admin.system.model.entity.UserDO; import top.charles7c.continew.admin.system.model.entity.UserDO;
import top.charles7c.continew.admin.system.model.query.UserQuery; import top.charles7c.continew.admin.system.model.query.UserQuery;
import top.charles7c.continew.admin.system.model.req.UserBasicInfoUpdateReq; import top.charles7c.continew.admin.system.model.req.UserBasicInfoUpdateReq;
import top.charles7c.continew.admin.system.model.req.UserPasswordResetReq;
import top.charles7c.continew.admin.system.model.req.UserReq; import top.charles7c.continew.admin.system.model.req.UserReq;
import top.charles7c.continew.admin.system.model.req.UserRoleUpdateReq; import top.charles7c.continew.admin.system.model.req.UserRoleUpdateReq;
import top.charles7c.continew.admin.system.model.resp.UserDetailResp; import top.charles7c.continew.admin.system.model.resp.UserDetailResp;
@ -50,8 +50,8 @@ import top.charles7c.continew.admin.system.service.UserRoleService;
import top.charles7c.continew.admin.system.service.UserService; import top.charles7c.continew.admin.system.service.UserService;
import top.charles7c.continew.starter.core.constant.StringConstants; import top.charles7c.continew.starter.core.constant.StringConstants;
import top.charles7c.continew.starter.core.util.validate.CheckUtils; import top.charles7c.continew.starter.core.util.validate.CheckUtils;
import top.charles7c.continew.starter.extension.crud.service.impl.BaseServiceImpl;
import top.charles7c.continew.starter.extension.crud.service.CommonUserService; import top.charles7c.continew.starter.extension.crud.service.CommonUserService;
import top.charles7c.continew.starter.extension.crud.service.impl.BaseServiceImpl;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.Collection; import java.util.Collection;
@ -92,16 +92,13 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, UserDO, UserRes
String phone = req.getPhone(); String phone = req.getPhone();
CheckUtils.throwIf(StrUtil.isNotBlank(phone) && this.isPhoneExists(phone, null), "新增失败,[{}] 已存在", phone); CheckUtils.throwIf(StrUtil.isNotBlank(phone) && this.isPhoneExists(phone, null), "新增失败,[{}] 已存在", phone);
req.setStatus(DisEnableStatusEnum.ENABLE); req.setStatus(DisEnableStatusEnum.ENABLE);
req.setPassword(passwordEncoder.encode(req.getPassword()));
} }
@Override @Override
protected void afterAdd(UserReq req, UserDO user) { protected void afterAdd(UserReq req, UserDO user) {
Long userId = user.getId(); Long userId = user.getId();
baseMapper.lambdaUpdate() baseMapper.lambdaUpdate().set(UserDO::getPwdResetTime, LocalDateTime.now()).eq(UserDO::getId, userId).update();
.set(UserDO::getPassword, passwordEncoder.encode(SysConstants.DEFAULT_PASSWORD))
.set(UserDO::getPwdResetTime, LocalDateTime.now())
.eq(UserDO::getId, userId)
.update();
// 保存用户和角色关联 // 保存用户和角色关联
userRoleService.add(req.getRoleIds(), userId); userRoleService.add(req.getRoleIds(), userId);
} }
@ -166,9 +163,8 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, UserDO, UserRes
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public String uploadAvatar(MultipartFile avatarFile, Long id) { public String uploadAvatar(MultipartFile avatarFile, Long id) {
String avatarImageType = FileNameUtil.extName(avatarFile.getOriginalFilename()); String avatarImageType = FileNameUtil.extName(avatarFile.getOriginalFilename());
CheckUtils.throwIf(!StrUtil CheckUtils.throwIf(!StrUtil.equalsAnyIgnoreCase(avatarImageType, avatarSupportSuffix), "头像仅支持 {} 格式的图片", String
.equalsAnyIgnoreCase(avatarImageType, avatarSupportSuffix), "头像仅支持 {} 格式的图片", String .join(StringConstants.CHINESE_COMMA, avatarSupportSuffix));
.join(StringConstants.CHINESE_COMMA, avatarSupportSuffix));
// 上传新头像 // 上传新头像
UserDO user = super.getById(id); UserDO user = super.getById(id);
FileInfo fileInfo = fileService.upload(avatarFile); FileInfo fileInfo = fileService.upload(avatarFile);
@ -234,9 +230,9 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, UserDO, UserRes
} }
@Override @Override
public void resetPassword(Long id) { public void resetPassword(UserPasswordResetReq req, Long id) {
UserDO user = super.getById(id); UserDO user = super.getById(id);
user.setPassword(passwordEncoder.encode(SysConstants.DEFAULT_PASSWORD)); user.setPassword(passwordEncoder.encode(req.getNewPassword()));
user.setPwdResetTime(LocalDateTime.now()); user.setPwdResetTime(LocalDateTime.now());
baseMapper.updateById(user); baseMapper.updateById(user);
} }

View File

@ -63,7 +63,7 @@ public class SocialAuthController {
@Operation(summary = "三方账号登录授权", description = "三方账号登录授权") @Operation(summary = "三方账号登录授权", description = "三方账号登录授权")
@Parameter(name = "source", description = "来源", example = "gitee", in = ParameterIn.PATH) @Parameter(name = "source", description = "来源", example = "gitee", in = ParameterIn.PATH)
@GetMapping("/{source}") @GetMapping("/{source}")
public R authorize(@PathVariable String source) { public R<String> authorize(@PathVariable String source) {
AuthRequest authRequest = this.getAuthRequest(source); AuthRequest authRequest = this.getAuthRequest(source);
return R.ok("操作成功", authRequest.authorize(AuthStateUtils.createState())); return R.ok("操作成功", authRequest.authorize(AuthStateUtils.createState()));
} }

View File

@ -105,7 +105,7 @@ public class CaptchaController {
@Operation(summary = "获取邮箱验证码", description = "发送验证码到指定邮箱") @Operation(summary = "获取邮箱验证码", description = "发送验证码到指定邮箱")
@GetMapping("/mail") @GetMapping("/mail")
public R getMailCaptcha(@NotBlank(message = "邮箱不能为空") @Pattern(regexp = RegexPool.EMAIL, message = "邮箱格式错误") String email) throws MessagingException { public R<Void> getMailCaptcha(@NotBlank(message = "邮箱不能为空") @Pattern(regexp = RegexPool.EMAIL, message = "邮箱格式错误") String email) throws MessagingException {
String limitKeyPrefix = CacheConstants.LIMIT_KEY_PREFIX; String limitKeyPrefix = CacheConstants.LIMIT_KEY_PREFIX;
String captchaKeyPrefix = CacheConstants.CAPTCHA_KEY_PREFIX; String captchaKeyPrefix = CacheConstants.CAPTCHA_KEY_PREFIX;
String limitCaptchaKey = limitKeyPrefix + captchaKeyPrefix + email; String limitCaptchaKey = limitKeyPrefix + captchaKeyPrefix + email;
@ -129,9 +129,9 @@ public class CaptchaController {
@Operation(summary = "获取短信验证码", description = "发送验证码到指定手机号") @Operation(summary = "获取短信验证码", description = "发送验证码到指定手机号")
@GetMapping("/sms") @GetMapping("/sms")
public R getSmsCaptcha(@NotBlank(message = "手机号不能为空") @Pattern(regexp = RegexPool.MOBILE, message = "手机号格式错误") String phone, public R<Void> getSmsCaptcha(@NotBlank(message = "手机号不能为空") @Pattern(regexp = RegexPool.MOBILE, message = "手机号格式错误") String phone,
CaptchaVO captchaReq, CaptchaVO captchaReq,
HttpServletRequest request) { HttpServletRequest request) {
// 行为验证码校验 // 行为验证码校验
ResponseModel verificationRes = captchaService.verification(captchaReq); ResponseModel verificationRes = captchaService.verification(captchaReq);
ValidationUtils.throwIfNotEqual(verificationRes.getRepCode(), RepCodeEnum.SUCCESS.getCode(), verificationRes ValidationUtils.throwIfNotEqual(verificationRes.getRepCode(), RepCodeEnum.SUCCESS.getCode(), verificationRes

View File

@ -62,7 +62,7 @@ public class OnlineUserController {
@Parameter(name = "token", description = "令牌", example = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpblR5cGUiOiJsb2dpbiIsImxvZ2luSWQiOjEsInJuU3RyIjoiTUd6djdyOVFoeHEwdVFqdFAzV3M5YjVJRzh4YjZPSEUifQ.7q7U3ouoN7WPhH2kUEM7vPe5KF3G_qavSG-vRgIxKvE", in = ParameterIn.PATH) @Parameter(name = "token", description = "令牌", example = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpblR5cGUiOiJsb2dpbiIsImxvZ2luSWQiOjEsInJuU3RyIjoiTUd6djdyOVFoeHEwdVFqdFAzV3M5YjVJRzh4YjZPSEUifQ.7q7U3ouoN7WPhH2kUEM7vPe5KF3G_qavSG-vRgIxKvE", in = ParameterIn.PATH)
@SaCheckPermission("monitor:online:user:delete") @SaCheckPermission("monitor:online:user:delete")
@DeleteMapping("/{token}") @DeleteMapping("/{token}")
public R kickout(@PathVariable String token) { public R<Void> kickout(@PathVariable String token) {
String currentToken = StpUtil.getTokenValue(); String currentToken = StpUtil.getTokenValue();
CheckUtils.throwIfEqual(token, currentToken, "不能强退自己"); CheckUtils.throwIfEqual(token, currentToken, "不能强退自己");
StpUtil.kickoutByTokenValue(token); StpUtil.kickoutByTokenValue(token);

View File

@ -56,8 +56,8 @@ public class AnnouncementController extends BaseController<AnnouncementService,
@Override @Override
@SaCheckPermission("system:announcement:update") @SaCheckPermission("system:announcement:update")
public R update(@Validated(ValidateGroup.Crud.Update.class) @RequestBody AnnouncementReq req, public R<Void> update(@Validated(ValidateGroup.Crud.Update.class) @RequestBody AnnouncementReq req,
@PathVariable Long id) { @PathVariable Long id) {
this.checkTime(req); this.checkTime(req);
return super.update(req, id); return super.update(req, id);
} }

View File

@ -55,7 +55,7 @@ public class MenuController extends BaseController<MenuService, MenuResp, MenuRe
@Override @Override
@SaCheckPermission("system:menu:update") @SaCheckPermission("system:menu:update")
public R update(@Validated(ValidateGroup.Crud.Update.class) @RequestBody MenuReq req, @PathVariable Long id) { public R<Void> update(@Validated(ValidateGroup.Crud.Update.class) @RequestBody MenuReq req, @PathVariable Long id) {
this.checkPath(req); this.checkPath(req);
return super.update(req, id); return super.update(req, id);
} }

View File

@ -61,7 +61,7 @@ public class MessageController {
@Operation(summary = "删除数据", description = "删除数据") @Operation(summary = "删除数据", description = "删除数据")
@Parameter(name = "ids", description = "ID 列表", example = "1,2", in = ParameterIn.PATH) @Parameter(name = "ids", description = "ID 列表", example = "1,2", in = ParameterIn.PATH)
@DeleteMapping("/{ids}") @DeleteMapping("/{ids}")
public R delete(@PathVariable List<Long> ids) { public R<Void> delete(@PathVariable List<Long> ids) {
baseService.delete(ids); baseService.delete(ids);
return R.ok("删除成功"); return R.ok("删除成功");
} }
@ -69,7 +69,7 @@ public class MessageController {
@Operation(summary = "标记已读", description = "将消息标记为已读状态") @Operation(summary = "标记已读", description = "将消息标记为已读状态")
@Parameter(name = "ids", description = "消息ID列表", example = "1,2", in = ParameterIn.QUERY) @Parameter(name = "ids", description = "消息ID列表", example = "1,2", in = ParameterIn.QUERY)
@PatchMapping("/read") @PatchMapping("/read")
public R readMessage(@RequestParam(required = false) List<Long> ids) { public R<Void> readMessage(@RequestParam(required = false) List<Long> ids) {
messageUserService.readMessage(ids); messageUserService.readMessage(ids);
return R.ok(); return R.ok();
} }

View File

@ -59,7 +59,7 @@ public class OptionController {
@Operation(summary = "修改参数", description = "修改参数") @Operation(summary = "修改参数", description = "修改参数")
@SaCheckPermission("system:config:update") @SaCheckPermission("system:config:update")
@PatchMapping @PatchMapping
public R update(@Validated @RequestBody List<OptionReq> req) { public R<Void> update(@Validated @RequestBody List<OptionReq> req) {
optionService.update(req); optionService.update(req);
return R.ok(); return R.ok();
} }
@ -67,7 +67,7 @@ public class OptionController {
@Operation(summary = "重置参数", description = "重置参数") @Operation(summary = "重置参数", description = "重置参数")
@SaCheckPermission("system:config:reset") @SaCheckPermission("system:config:reset")
@PatchMapping("/value") @PatchMapping("/value")
public R resetValue(@Validated @RequestBody OptionResetValueReq req) { public R<Void> resetValue(@Validated @RequestBody OptionResetValueReq req) {
optionService.resetValue(req); optionService.resetValue(req);
return R.ok(); return R.ok();
} }

View File

@ -80,14 +80,14 @@ public class UserCenterController {
@Operation(summary = "修改基础信息", description = "修改用户基础信息") @Operation(summary = "修改基础信息", description = "修改用户基础信息")
@PatchMapping("/basic/info") @PatchMapping("/basic/info")
public R updateBasicInfo(@Validated @RequestBody UserBasicInfoUpdateReq req) { public R<Void> updateBasicInfo(@Validated @RequestBody UserBasicInfoUpdateReq req) {
userService.updateBasicInfo(req, LoginHelper.getUserId()); userService.updateBasicInfo(req, LoginHelper.getUserId());
return R.ok("修改成功"); return R.ok("修改成功");
} }
@Operation(summary = "修改密码", description = "修改用户登录密码") @Operation(summary = "修改密码", description = "修改用户登录密码")
@PatchMapping("/password") @PatchMapping("/password")
public R updatePassword(@Validated @RequestBody UserPasswordUpdateReq updateReq) { public R<Void> updatePassword(@Validated @RequestBody UserPasswordUpdateReq updateReq) {
String rawOldPassword = ExceptionUtils.exToNull(() -> SecureUtils.decryptByRsaPrivateKey(updateReq String rawOldPassword = ExceptionUtils.exToNull(() -> SecureUtils.decryptByRsaPrivateKey(updateReq
.getOldPassword())); .getOldPassword()));
ValidationUtils.throwIfNull(rawOldPassword, "当前密码解密失败"); ValidationUtils.throwIfNull(rawOldPassword, "当前密码解密失败");
@ -97,12 +97,12 @@ public class UserCenterController {
ValidationUtils.throwIf(!ReUtil ValidationUtils.throwIf(!ReUtil
.isMatch(RegexConstants.PASSWORD, rawNewPassword), "密码长度为 6 到 32 位,可以包含字母、数字、下划线,特殊字符,同时包含字母和数字"); .isMatch(RegexConstants.PASSWORD, rawNewPassword), "密码长度为 6 到 32 位,可以包含字母、数字、下划线,特殊字符,同时包含字母和数字");
userService.updatePassword(rawOldPassword, rawNewPassword, LoginHelper.getUserId()); userService.updatePassword(rawOldPassword, rawNewPassword, LoginHelper.getUserId());
return R.ok("修改成功"); return R.ok("修改成功,请牢记你的新密码");
} }
@Operation(summary = "修改手机号", description = "修改手机号") @Operation(summary = "修改手机号", description = "修改手机号")
@PatchMapping("/phone") @PatchMapping("/phone")
public R updatePhone(@Validated @RequestBody UserPhoneUpdateReq updateReq) { public R<Void> updatePhone(@Validated @RequestBody UserPhoneUpdateReq updateReq) {
String rawCurrentPassword = ExceptionUtils.exToNull(() -> SecureUtils.decryptByRsaPrivateKey(updateReq String rawCurrentPassword = ExceptionUtils.exToNull(() -> SecureUtils.decryptByRsaPrivateKey(updateReq
.getCurrentPassword())); .getCurrentPassword()));
ValidationUtils.throwIfBlank(rawCurrentPassword, "当前密码解密失败"); ValidationUtils.throwIfBlank(rawCurrentPassword, "当前密码解密失败");
@ -117,7 +117,7 @@ public class UserCenterController {
@Operation(summary = "修改邮箱", description = "修改用户邮箱") @Operation(summary = "修改邮箱", description = "修改用户邮箱")
@PatchMapping("/email") @PatchMapping("/email")
public R updateEmail(@Validated @RequestBody UserEmailUpdateRequest updateReq) { public R<Void> updateEmail(@Validated @RequestBody UserEmailUpdateRequest updateReq) {
String rawCurrentPassword = ExceptionUtils.exToNull(() -> SecureUtils.decryptByRsaPrivateKey(updateReq String rawCurrentPassword = ExceptionUtils.exToNull(() -> SecureUtils.decryptByRsaPrivateKey(updateReq
.getCurrentPassword())); .getCurrentPassword()));
ValidationUtils.throwIfBlank(rawCurrentPassword, "当前密码解密失败"); ValidationUtils.throwIfBlank(rawCurrentPassword, "当前密码解密失败");
@ -147,7 +147,7 @@ public class UserCenterController {
@Operation(summary = "绑定三方账号", description = "绑定三方账号") @Operation(summary = "绑定三方账号", description = "绑定三方账号")
@Parameter(name = "source", description = "来源", example = "gitee", in = ParameterIn.PATH) @Parameter(name = "source", description = "来源", example = "gitee", in = ParameterIn.PATH)
@PostMapping("/social/{source}") @PostMapping("/social/{source}")
public R bindSocial(@PathVariable String source, @RequestBody AuthCallback callback) { public R<Void> bindSocial(@PathVariable String source, @RequestBody AuthCallback callback) {
AuthRequest authRequest = authRequestFactory.get(source); AuthRequest authRequest = authRequestFactory.get(source);
AuthResponse<AuthUser> response = authRequest.login(callback); AuthResponse<AuthUser> response = authRequest.login(callback);
ValidationUtils.throwIf(!response.ok(), response.getMsg()); ValidationUtils.throwIf(!response.ok(), response.getMsg());
@ -159,7 +159,7 @@ public class UserCenterController {
@Operation(summary = "解绑三方账号", description = "解绑三方账号") @Operation(summary = "解绑三方账号", description = "解绑三方账号")
@Parameter(name = "source", description = "来源", example = "gitee", in = ParameterIn.PATH) @Parameter(name = "source", description = "来源", example = "gitee", in = ParameterIn.PATH)
@DeleteMapping("/social/{source}") @DeleteMapping("/social/{source}")
public R unbindSocial(@PathVariable String source) { public R<Void> unbindSocial(@PathVariable String source) {
userSocialService.deleteBySourceAndUserId(source, LoginHelper.getUserId()); userSocialService.deleteBySourceAndUserId(source, LoginHelper.getUserId());
return R.ok("解绑成功"); return R.ok("解绑成功");
} }

View File

@ -16,26 +16,28 @@
package top.charles7c.continew.admin.webapi.system; package top.charles7c.continew.admin.webapi.system;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.ReUtil;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn; import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PatchMapping; import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import top.charles7c.continew.admin.common.constant.RegexConstants;
import cn.dev33.satoken.annotation.SaCheckPermission; import top.charles7c.continew.admin.common.util.SecureUtils;
import top.charles7c.continew.admin.common.constant.SysConstants;
import top.charles7c.continew.admin.system.model.query.UserQuery; import top.charles7c.continew.admin.system.model.query.UserQuery;
import top.charles7c.continew.admin.system.model.req.UserPasswordResetReq;
import top.charles7c.continew.admin.system.model.req.UserReq; import top.charles7c.continew.admin.system.model.req.UserReq;
import top.charles7c.continew.admin.system.model.req.UserRoleUpdateReq; import top.charles7c.continew.admin.system.model.req.UserRoleUpdateReq;
import top.charles7c.continew.admin.system.model.resp.UserDetailResp; import top.charles7c.continew.admin.system.model.resp.UserDetailResp;
import top.charles7c.continew.admin.system.model.resp.UserResp; import top.charles7c.continew.admin.system.model.resp.UserResp;
import top.charles7c.continew.admin.system.service.UserService; import top.charles7c.continew.admin.system.service.UserService;
import top.charles7c.continew.starter.core.util.ExceptionUtils;
import top.charles7c.continew.starter.core.util.validate.ValidationUtils;
import top.charles7c.continew.starter.extension.crud.annotation.CrudRequestMapping; import top.charles7c.continew.starter.extension.crud.annotation.CrudRequestMapping;
import top.charles7c.continew.starter.extension.crud.controller.BaseController; import top.charles7c.continew.starter.extension.crud.controller.BaseController;
import top.charles7c.continew.starter.extension.crud.util.ValidateGroup; import top.charles7c.continew.starter.extension.crud.util.ValidateGroup;
@ -56,24 +58,34 @@ public class UserController extends BaseController<UserService, UserResp, UserDe
@Override @Override
@SaCheckPermission("system:user:add") @SaCheckPermission("system:user:add")
public R<Long> add(@Validated(ValidateGroup.Crud.Add.class) @RequestBody UserReq req) { public R<Long> add(@Validated(ValidateGroup.Crud.Add.class) @RequestBody UserReq req) {
String rawPassword = ExceptionUtils.exToNull(() -> SecureUtils.decryptByRsaPrivateKey(req.getPassword()));
ValidationUtils.throwIfNull(rawPassword, "密码解密失败");
ValidationUtils.throwIf(!ReUtil
.isMatch(RegexConstants.PASSWORD, rawPassword), "密码长度为 6 到 32 位,可以包含字母、数字、下划线,特殊字符,同时包含字母和数字");
req.setPassword(rawPassword);
Long id = baseService.add(req); Long id = baseService.add(req);
return R.ok(String.format("新增成功,请牢记默认密码:%s", SysConstants.DEFAULT_PASSWORD), id); return R.ok("新增成功", id);
} }
@Operation(summary = "重置密码", description = "重置用户登录密码为默认密码") @Operation(summary = "重置密码", description = "重置用户登录密码为默认密码")
@Parameter(name = "id", description = "ID", example = "1", in = ParameterIn.PATH) @Parameter(name = "id", description = "ID", example = "1", in = ParameterIn.PATH)
@SaCheckPermission("system:user:password:reset") @SaCheckPermission("system:user:password:reset")
@PatchMapping("/{id}/password") @PatchMapping("/{id}/password")
public R resetPassword(@PathVariable Long id) { public R<Void> resetPassword(@Validated @RequestBody UserPasswordResetReq req, @PathVariable Long id) {
baseService.resetPassword(id); String rawNewPassword = ExceptionUtils.exToNull(() -> SecureUtils.decryptByRsaPrivateKey(req.getNewPassword()));
return R.ok(String.format("重置密码成功,请牢记默认密码:%s", SysConstants.DEFAULT_PASSWORD)); ValidationUtils.throwIfNull(rawNewPassword, "新密码解密失败");
ValidationUtils.throwIf(!ReUtil
.isMatch(RegexConstants.PASSWORD, rawNewPassword), "密码长度为 6 到 32 位,可以包含字母、数字、下划线,特殊字符,同时包含字母和数字");
req.setNewPassword(rawNewPassword);
baseService.resetPassword(req, id);
return R.ok("重置密码成功");
} }
@Operation(summary = "分配角色", description = "为用户新增或移除角色") @Operation(summary = "分配角色", description = "为用户新增或移除角色")
@Parameter(name = "id", description = "ID", example = "1", in = ParameterIn.PATH) @Parameter(name = "id", description = "ID", example = "1", in = ParameterIn.PATH)
@SaCheckPermission("system:user:role:update") @SaCheckPermission("system:user:role:update")
@PatchMapping("/{id}/role") @PatchMapping("/{id}/role")
public R updateRole(@Validated @RequestBody UserRoleUpdateReq updateReq, @PathVariable Long id) { public R<Void> updateRole(@Validated @RequestBody UserRoleUpdateReq updateReq, @PathVariable Long id) {
baseService.updateRole(updateReq, id); baseService.updateRole(updateReq, id);
return R.ok("分配成功"); return R.ok("分配成功");
} }

View File

@ -89,7 +89,7 @@ public class GeneratorController {
@Parameter(name = "tableName", description = "表名称", required = true, example = "sys_user", in = ParameterIn.PATH) @Parameter(name = "tableName", description = "表名称", required = true, example = "sys_user", in = ParameterIn.PATH)
@SaCheckPermission("tool:generator:list") @SaCheckPermission("tool:generator:list")
@PostMapping("/config/{tableName}") @PostMapping("/config/{tableName}")
public R saveConfig(@Validated @RequestBody GenConfigReq req, @PathVariable String tableName) { public R<Void> saveConfig(@Validated @RequestBody GenConfigReq req, @PathVariable String tableName) {
generatorService.saveConfig(req, tableName); generatorService.saveConfig(req, tableName);
return R.ok("保存成功"); return R.ok("保存成功");
} }
@ -106,7 +106,7 @@ public class GeneratorController {
@Parameter(name = "tableName", description = "表名称", required = true, example = "sys_user", in = ParameterIn.PATH) @Parameter(name = "tableName", description = "表名称", required = true, example = "sys_user", in = ParameterIn.PATH)
@SaCheckPermission("tool:generator:list") @SaCheckPermission("tool:generator:list")
@PostMapping("/{tableName}") @PostMapping("/{tableName}")
public R generate(@PathVariable String tableName) { public R<Void> generate(@PathVariable String tableName) {
ValidationUtils.throwIf(projectProperties.isProduction(), "仅支持在开发环境生成代码"); ValidationUtils.throwIf(projectProperties.isProduction(), "仅支持在开发环境生成代码");
generatorService.generate(tableName); generatorService.generate(tableName);
return R.ok("生成成功,请查看生成代码是否正确"); return R.ok("生成成功,请查看生成代码是否正确");

View File

@ -258,8 +258,4 @@ spring.servlet:
max-request-size: 20MB max-request-size: 20MB
## 头像支持格式配置 ## 头像支持格式配置
avatar: avatar:
support-suffix: support-suffix: jpg,jpeg,png,gif
- jpg
- jpeg
- png
- gif

View File

@ -258,8 +258,4 @@ spring.servlet:
max-request-size: 20MB max-request-size: 20MB
## 头像支持格式配置 ## 头像支持格式配置
avatar: avatar:
support-suffix: support-suffix: jpg,jpeg,png,gif
- jpg
- jpeg
- png
- gif