style: 部分代码优化

1.格式优化:去除部分多余空行(较少代码段区分尽量不添加空行)、注释(代码尽量自解释)
2.完善部分 Swagger 注解信息
3.修复部分前后端警告
This commit is contained in:
Charles7c 2023-09-10 18:01:44 +08:00
parent b874ca0782
commit a3082e72a9
34 changed files with 116 additions and 99 deletions

View File

@ -78,6 +78,6 @@ public @interface CrudRequestMapping {
/** /**
* 导出 * 导出
*/ */
EXPORT,; EXPORT,
} }
} }

View File

@ -74,7 +74,7 @@ public abstract class BaseController<S extends BaseService<V, D, Q, C>, V, D, Q,
* 分页查询条件 * 分页查询条件
* @return 分页信息 * @return 分页信息
*/ */
@Operation(summary = "分页查询列表") @Operation(summary = "分页查询列表", description = "分页查询列表")
@ResponseBody @ResponseBody
@GetMapping @GetMapping
public R<PageDataVO<V>> page(Q query, @Validated PageQuery pageQuery) { public R<PageDataVO<V>> page(Q query, @Validated PageQuery pageQuery) {
@ -92,7 +92,7 @@ public abstract class BaseController<S extends BaseService<V, D, Q, C>, V, D, Q,
* 排序查询条件 * 排序查询条件
* @return 树列表信息 * @return 树列表信息
*/ */
@Operation(summary = "查询树列表") @Operation(summary = "查询树列表", description = "查询树列表")
@ResponseBody @ResponseBody
@GetMapping("/tree") @GetMapping("/tree")
public R<List<Tree<Long>>> tree(Q query, SortQuery sortQuery) { public R<List<Tree<Long>>> tree(Q query, SortQuery sortQuery) {
@ -110,7 +110,7 @@ public abstract class BaseController<S extends BaseService<V, D, Q, C>, V, D, Q,
* 排序查询条件 * 排序查询条件
* @return 列表信息 * @return 列表信息
*/ */
@Operation(summary = "查询列表") @Operation(summary = "查询列表", description = "查询列表")
@ResponseBody @ResponseBody
@GetMapping("/list") @GetMapping("/list")
public R<List<V>> list(Q query, SortQuery sortQuery) { public R<List<V>> list(Q query, SortQuery sortQuery) {
@ -126,8 +126,8 @@ public abstract class BaseController<S extends BaseService<V, D, Q, C>, V, D, Q,
* ID * ID
* @return 详情信息 * @return 详情信息
*/ */
@Operation(summary = "查看详情") @Operation(summary = "查看详情", description = "查看详情")
@Parameter(name = "id", description = "ID", in = ParameterIn.PATH) @Parameter(name = "id", description = "ID", example = "1", in = ParameterIn.PATH)
@ResponseBody @ResponseBody
@GetMapping("/{id}") @GetMapping("/{id}")
public R<D> get(@PathVariable Long id) { public R<D> get(@PathVariable Long id) {
@ -143,7 +143,7 @@ public abstract class BaseController<S extends BaseService<V, D, Q, C>, V, D, Q,
* 创建信息 * 创建信息
* @return 自增 ID * @return 自增 ID
*/ */
@Operation(summary = "新增数据") @Operation(summary = "新增数据", description = "新增数据")
@ResponseBody @ResponseBody
@PostMapping @PostMapping
public R<Long> add(@Validated(ValidateGroup.Crud.Add.class) @RequestBody C request) { public R<Long> add(@Validated(ValidateGroup.Crud.Add.class) @RequestBody C request) {
@ -161,7 +161,8 @@ public abstract class BaseController<S extends BaseService<V, D, Q, C>, V, D, Q,
* ID * ID
* @return / * @return /
*/ */
@Operation(summary = "修改数据") @Operation(summary = "修改数据", description = "修改数据")
@Parameter(name = "id", description = "ID", example = "1", in = ParameterIn.PATH)
@ResponseBody @ResponseBody
@PutMapping("/{id}") @PutMapping("/{id}")
public R update(@Validated(ValidateGroup.Crud.Update.class) @RequestBody C request, @PathVariable Long id) { public R update(@Validated(ValidateGroup.Crud.Update.class) @RequestBody C request, @PathVariable Long id) {
@ -177,8 +178,8 @@ public abstract class BaseController<S extends BaseService<V, D, Q, C>, V, D, Q,
* ID 列表 * ID 列表
* @return / * @return /
*/ */
@Operation(summary = "删除数据") @Operation(summary = "删除数据", description = "删除数据")
@Parameter(name = "ids", description = "ID 列表", in = ParameterIn.PATH) @Parameter(name = "ids", description = "ID 列表", example = "1,2", in = ParameterIn.PATH)
@ResponseBody @ResponseBody
@DeleteMapping("/{ids}") @DeleteMapping("/{ids}")
public R delete(@PathVariable List<Long> ids) { public R delete(@PathVariable List<Long> ids) {
@ -197,7 +198,7 @@ public abstract class BaseController<S extends BaseService<V, D, Q, C>, V, D, Q,
* @param response * @param response
* 响应对象 * 响应对象
*/ */
@Operation(summary = "导出数据") @Operation(summary = "导出数据", description = "导出数据")
@GetMapping("/export") @GetMapping("/export")
public void export(Q query, SortQuery sortQuery, HttpServletResponse response) { public void export(Q query, SortQuery sortQuery, HttpServletResponse response) {
this.checkPermission(Api.EXPORT); this.checkPermission(Api.EXPORT);

View File

@ -151,7 +151,9 @@ public abstract class BaseServiceImpl<M extends BaseMapper<T>, T extends BaseDO,
// 设置排序 // 设置排序
Sort sort = Opt.ofNullable(sortQuery).orElseGet(SortQuery::new).getSort(); Sort sort = Opt.ofNullable(sortQuery).orElseGet(SortQuery::new).getSort();
for (Sort.Order order : sort) { for (Sort.Order order : sort) {
queryWrapper.orderBy(null != order, order.isAscending(), StrUtil.toUnderlineCase(order.getProperty())); if (null != order) {
queryWrapper.orderBy(true, order.isAscending(), StrUtil.toUnderlineCase(order.getProperty()));
}
} }
List<T> entityList = baseMapper.selectList(queryWrapper); List<T> entityList = baseMapper.selectList(queryWrapper);
return BeanUtil.copyToList(entityList, targetClass); return BeanUtil.copyToList(entityList, targetClass);

View File

@ -68,6 +68,7 @@ public class BaseVO implements Serializable {
/** /**
* 是否禁用修改 * 是否禁用修改
*/ */
@Schema(description = "是否禁用修改", example = "true")
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
private Boolean disabled; private Boolean disabled;
} }

View File

@ -68,8 +68,9 @@ public class RedisConfiguration extends CachingConfigurerSupport {
*/ */
@Bean @Bean
public RedisCacheConfiguration redisCacheConfiguration(CacheProperties cacheProperties) { public RedisCacheConfiguration redisCacheConfiguration(CacheProperties cacheProperties) {
ObjectMapper objectMapperCopy = ObjectMapper objectMapperCopy = objectMapper.copy();
objectMapper.copy().enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY); objectMapperCopy.activateDefaultTyping(objectMapperCopy.getPolymorphicTypeValidator(),
ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig() RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer())) .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
.serializeValuesWith(RedisSerializationContext.SerializationPair .serializeValuesWith(RedisSerializationContext.SerializationPair

View File

@ -16,8 +16,6 @@
package top.charles7c.cnadmin.common.config.easyexcel; package top.charles7c.cnadmin.common.config.easyexcel;
import java.math.BigDecimal;
import com.alibaba.excel.converters.Converter; import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.GlobalConfiguration; import com.alibaba.excel.metadata.GlobalConfiguration;
@ -26,6 +24,7 @@ import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty; import com.alibaba.excel.metadata.property.ExcelContentProperty;
import cn.hutool.core.convert.Convert; import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.NumberUtil;
/** /**
* Easy Excel 大数值转换器Excel 中对长度超过 15 位的数值输入是有限制的 16 位开始无论录入什么数字均会变为 0因此输入时只能以文本的形式进行录入 * Easy Excel 大数值转换器Excel 中对长度超过 15 位的数值输入是有限制的 16 位开始无论录入什么数字均会变为 0因此输入时只能以文本的形式进行录入
@ -71,7 +70,7 @@ public class ExcelBigNumberConverter implements Converter<Long> {
return new WriteCellData<>(str); return new WriteCellData<>(str);
} }
} }
WriteCellData<Object> writeCellData = new WriteCellData<>(BigDecimal.valueOf(value)); WriteCellData<Object> writeCellData = new WriteCellData<>(NumberUtil.toBigDecimal(value));
writeCellData.setType(CellDataTypeEnum.NUMBER); writeCellData.setType(CellDataTypeEnum.NUMBER);
return writeCellData; return writeCellData;
} }

View File

@ -74,9 +74,9 @@ public class GlobalErrorHandler extends BasicErrorController {
response.setContentType(MediaType.APPLICATION_JSON_VALUE); response.setContentType(MediaType.APPLICATION_JSON_VALUE);
objectMapper.writeValue(response.getWriter(), result); objectMapper.writeValue(response.getWriter(), result);
} catch (IOException e) { } catch (IOException e) {
log.error("请求地址 [{}]发生 IO 异常。", path, e); log.error("请求地址 [{}]默认错误处理时发生 IO 异常。", path, e);
} }
log.error("请求地址 [{}],发生异常,错误信息:{}。", path, JSONUtil.toJsonStr(errorAttributeMap)); log.error("请求地址 [{}],发生错误,错误信息:{}。", path, JSONUtil.toJsonStr(errorAttributeMap));
return null; return null;
} }
@ -88,7 +88,7 @@ public class GlobalErrorHandler extends BasicErrorController {
HttpStatus status = super.getStatus(request); HttpStatus status = super.getStatus(request);
R<Object> result = R.fail(status.value(), (String)errorAttributeMap.get("error")); R<Object> result = R.fail(status.value(), (String)errorAttributeMap.get("error"));
result.setData(path); result.setData(path);
log.error("请求地址 [{}],发生异常,错误信息:{}。", path, JSONUtil.toJsonStr(errorAttributeMap)); log.error("请求地址 [{}],发生错误,错误信息:{}。", path, JSONUtil.toJsonStr(errorAttributeMap));
return new ResponseEntity<>(BeanUtil.beanToMap(result), status); return new ResponseEntity<>(BeanUtil.beanToMap(result), status);
} }
} }

View File

@ -72,7 +72,7 @@ public class LoginHelper {
/** /**
* 获取登录用户信息 * 获取登录用户信息
* *
* @return 登录用户信息 * @return 登录用户信息获取 TokenSession 时如未登录会抛出异常
*/ */
public static LoginUser getLoginUser() { public static LoginUser getLoginUser() {
LoginUser loginUser = (LoginUser)SaHolder.getStorage().get(CacheConsts.LOGIN_USER_KEY); LoginUser loginUser = (LoginUser)SaHolder.getStorage().get(CacheConsts.LOGIN_USER_KEY);

View File

@ -75,15 +75,12 @@ public class LoginServiceImpl implements LoginService {
CheckUtils.throwIfEqual(DisEnableStatusEnum.DISABLE, user.getStatus(), "此账号已被禁用,如有疑问,请联系管理员"); CheckUtils.throwIfEqual(DisEnableStatusEnum.DISABLE, user.getStatus(), "此账号已被禁用,如有疑问,请联系管理员");
DeptDetailVO deptDetailVO = deptService.get(user.getDeptId()); DeptDetailVO deptDetailVO = deptService.get(user.getDeptId());
CheckUtils.throwIfEqual(DisEnableStatusEnum.DISABLE, deptDetailVO.getStatus(), "此账号部门已被禁用,如有疑问,请联系管理员"); CheckUtils.throwIfEqual(DisEnableStatusEnum.DISABLE, deptDetailVO.getStatus(), "此账号部门已被禁用,如有疑问,请联系管理员");
// 登录并缓存用户信息
// 登录
LoginUser loginUser = BeanUtil.copyProperties(user, LoginUser.class); LoginUser loginUser = BeanUtil.copyProperties(user, LoginUser.class);
loginUser.setPermissions(permissionService.listPermissionByUserId(userId)); loginUser.setPermissions(permissionService.listPermissionByUserId(userId));
loginUser.setRoleCodes(permissionService.listRoleCodeByUserId(userId)); loginUser.setRoleCodes(permissionService.listRoleCodeByUserId(userId));
loginUser.setRoles(roleService.listByUserId(userId)); loginUser.setRoles(roleService.listByUserId(userId));
LoginHelper.login(loginUser); LoginHelper.login(loginUser);
// 返回令牌
return StpUtil.getTokenValue(); return StpUtil.getTokenValue();
} }
@ -93,7 +90,6 @@ public class LoginServiceImpl implements LoginService {
if (CollUtil.isEmpty(roleCodeSet)) { if (CollUtil.isEmpty(roleCodeSet)) {
return new ArrayList<>(0); return new ArrayList<>(0);
} }
// 查询菜单列表 // 查询菜单列表
Set<MenuVO> menuSet = new LinkedHashSet<>(); Set<MenuVO> menuSet = new LinkedHashSet<>();
if (roleCodeSet.contains(SysConsts.ADMIN_ROLE_CODE)) { if (roleCodeSet.contains(SysConsts.ADMIN_ROLE_CODE)) {
@ -103,7 +99,6 @@ public class LoginServiceImpl implements LoginService {
} }
List<MenuVO> menuList = List<MenuVO> menuList =
menuSet.stream().filter(m -> !MenuTypeEnum.BUTTON.equals(m.getType())).collect(Collectors.toList()); menuSet.stream().filter(m -> !MenuTypeEnum.BUTTON.equals(m.getType())).collect(Collectors.toList());
// 构建路由树 // 构建路由树
TreeField treeField = MenuVO.class.getDeclaredAnnotation(TreeField.class); TreeField treeField = MenuVO.class.getDeclaredAnnotation(TreeField.class);
TreeNodeConfig treeNodeConfig = TreeUtils.genTreeNodeConfig(treeField); TreeNodeConfig treeNodeConfig = TreeUtils.genTreeNodeConfig(treeField);
@ -112,7 +107,6 @@ public class LoginServiceImpl implements LoginService {
tree.setParentId(m.getParentId()); tree.setParentId(m.getParentId());
tree.setName(m.getTitle()); tree.setName(m.getTitle());
tree.setWeight(m.getSort()); tree.setWeight(m.getSort());
tree.putExtra("path", m.getPath()); tree.putExtra("path", m.getPath());
tree.putExtra("name", m.getName()); tree.putExtra("name", m.getName());
tree.putExtra("component", m.getComponent()); tree.putExtra("component", m.getComponent());

View File

@ -68,7 +68,6 @@ public class DeptServiceImpl extends BaseServiceImpl<DeptMapper, DeptDO, DeptVO,
String name = request.getName(); String name = request.getName();
boolean isExists = this.checkNameExists(name, request.getParentId(), null); boolean isExists = this.checkNameExists(name, request.getParentId(), null);
CheckUtils.throwIf(isExists, "新增失败,[{}] 已存在", name); CheckUtils.throwIf(isExists, "新增失败,[{}] 已存在", name);
request.setAncestors(this.getAncestors(request.getParentId())); request.setAncestors(this.getAncestors(request.getParentId()));
request.setStatus(DisEnableStatusEnum.DISABLE); request.setStatus(DisEnableStatusEnum.DISABLE);
return super.add(request); return super.add(request);
@ -99,7 +98,6 @@ public class DeptServiceImpl extends BaseServiceImpl<DeptMapper, DeptDO, DeptVO,
CheckUtils.throwIf(DisEnableStatusEnum.ENABLE.equals(newStatus) CheckUtils.throwIf(DisEnableStatusEnum.ENABLE.equals(newStatus)
&& DisEnableStatusEnum.DISABLE.equals(oldParentDept.getStatus()), "启用 [{}] 前,请先启用其所有上级部门", oldName); && DisEnableStatusEnum.DISABLE.equals(oldParentDept.getStatus()), "启用 [{}] 前,请先启用其所有上级部门", oldName);
} }
// 变更上级部门 // 变更上级部门
if (ObjectUtil.notEqual(request.getParentId(), oldParentId)) { if (ObjectUtil.notEqual(request.getParentId(), oldParentId)) {
// 更新祖级列表 // 更新祖级列表
@ -121,7 +119,6 @@ public class DeptServiceImpl extends BaseServiceImpl<DeptMapper, DeptDO, DeptVO,
isSystemData.orElseGet(DeptDO::new).getName()); isSystemData.orElseGet(DeptDO::new).getName());
CheckUtils.throwIf(this.countChildren(ids) > 0, "所选部门存在下级部门,不允许删除"); CheckUtils.throwIf(this.countChildren(ids) > 0, "所选部门存在下级部门,不允许删除");
CheckUtils.throwIf(userService.countByDeptIds(ids) > 0, "所选部门存在用户关联,请解除关联后重试"); CheckUtils.throwIf(userService.countByDeptIds(ids) > 0, "所选部门存在用户关联,请解除关联后重试");
// 删除角色和部门关联 // 删除角色和部门关联
roleDeptService.deleteByDeptIds(ids); roleDeptService.deleteByDeptIds(ids);
// 删除部门 // 删除部门

View File

@ -58,7 +58,6 @@ public class MenuServiceImpl extends BaseServiceImpl<MenuMapper, MenuDO, MenuVO,
String title = request.getTitle(); String title = request.getTitle();
boolean isExists = this.checkNameExists(title, request.getParentId(), null); boolean isExists = this.checkNameExists(title, request.getParentId(), null);
CheckUtils.throwIf(isExists, "新增失败,[{}] 已存在", title); CheckUtils.throwIf(isExists, "新增失败,[{}] 已存在", title);
request.setStatus(DisEnableStatusEnum.ENABLE); request.setStatus(DisEnableStatusEnum.ENABLE);
return super.add(request); return super.add(request);
} }
@ -70,7 +69,6 @@ public class MenuServiceImpl extends BaseServiceImpl<MenuMapper, MenuDO, MenuVO,
String title = request.getTitle(); String title = request.getTitle();
boolean isExists = this.checkNameExists(title, request.getParentId(), id); boolean isExists = this.checkNameExists(title, request.getParentId(), id);
CheckUtils.throwIf(isExists, "修改失败,[{}] 已存在", title); CheckUtils.throwIf(isExists, "修改失败,[{}] 已存在", title);
super.update(request, id); super.update(request, id);
} }

View File

@ -72,7 +72,6 @@ public class RoleServiceImpl extends BaseServiceImpl<RoleMapper, RoleDO, RoleVO,
CheckUtils.throwIf(this.checkNameExists(name, null), "新增失败,[{}] 已存在", name); CheckUtils.throwIf(this.checkNameExists(name, null), "新增失败,[{}] 已存在", name);
String code = request.getCode(); String code = request.getCode();
CheckUtils.throwIf(this.checkCodeExists(code, null), "新增失败,[{}] 已存在", code); CheckUtils.throwIf(this.checkCodeExists(code, null), "新增失败,[{}] 已存在", code);
// 新增信息 // 新增信息
request.setStatus(DisEnableStatusEnum.ENABLE); request.setStatus(DisEnableStatusEnum.ENABLE);
Long roleId = super.add(request); Long roleId = super.add(request);
@ -101,7 +100,6 @@ public class RoleServiceImpl extends BaseServiceImpl<RoleMapper, RoleDO, RoleVO,
CheckUtils.throwIfNotEqual(request.getDataScope(), oldDataScope, "[{}] 是系统内置角色,不允许修改角色数据权限", CheckUtils.throwIfNotEqual(request.getDataScope(), oldDataScope, "[{}] 是系统内置角色,不允许修改角色数据权限",
oldRole.getName()); oldRole.getName());
} }
// 更新信息 // 更新信息
super.update(request, id); super.update(request, id);
// 更新关联信息 // 更新关联信息
@ -128,7 +126,6 @@ public class RoleServiceImpl extends BaseServiceImpl<RoleMapper, RoleDO, RoleVO,
CheckUtils.throwIf(isSystemData::isPresent, "所选角色 [{}] 是系统内置角色,不允许删除", CheckUtils.throwIf(isSystemData::isPresent, "所选角色 [{}] 是系统内置角色,不允许删除",
isSystemData.orElseGet(RoleDO::new).getName()); isSystemData.orElseGet(RoleDO::new).getName());
CheckUtils.throwIf(userRoleService.countByRoleIds(ids) > 0, "所选角色存在用户关联,请解除关联后重试"); CheckUtils.throwIf(userRoleService.countByRoleIds(ids) > 0, "所选角色存在用户关联,请解除关联后重试");
// 删除角色和菜单关联 // 删除角色和菜单关联
roleMenuService.deleteByRoleIds(ids); roleMenuService.deleteByRoleIds(ids);
// 删除角色和部门关联 // 删除角色和部门关联

View File

@ -92,7 +92,6 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, UserDO, UserVO,
CheckUtils.throwIf(StrUtil.isNotBlank(email) && this.checkEmailExists(email, null), "新增失败,[{}] 已存在", email); CheckUtils.throwIf(StrUtil.isNotBlank(email) && this.checkEmailExists(email, null), "新增失败,[{}] 已存在", email);
String phone = request.getPhone(); String phone = request.getPhone();
CheckUtils.throwIf(StrUtil.isNotBlank(phone) && this.checkPhoneExists(phone, null), "新增失败,[{}] 已存在", phone); CheckUtils.throwIf(StrUtil.isNotBlank(phone) && this.checkPhoneExists(phone, null), "新增失败,[{}] 已存在", phone);
// 新增信息 // 新增信息
request.setStatus(DisEnableStatusEnum.ENABLE); request.setStatus(DisEnableStatusEnum.ENABLE);
Long userId = super.add(request); Long userId = super.add(request);
@ -125,7 +124,6 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, UserDO, UserVO,
CollUtil.disjunction(request.getRoleIds(), userRoleService.listRoleIdByUserId(id)); CollUtil.disjunction(request.getRoleIds(), userRoleService.listRoleIdByUserId(id));
CheckUtils.throwIfNotEmpty(disjunctionRoleIds, "[{}] 是系统内置用户,不允许变更所属角色", oldUser.getNickname()); CheckUtils.throwIfNotEmpty(disjunctionRoleIds, "[{}] 是系统内置用户,不允许变更所属角色", oldUser.getNickname());
} }
// 更新信息 // 更新信息
super.update(request, id); super.update(request, id);
// 保存用户和角色关联 // 保存用户和角色关联
@ -141,7 +139,6 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, UserDO, UserVO,
Optional<UserDO> isSystemData = list.stream().filter(u -> DataTypeEnum.SYSTEM.equals(u.getType())).findFirst(); Optional<UserDO> isSystemData = list.stream().filter(u -> DataTypeEnum.SYSTEM.equals(u.getType())).findFirst();
CheckUtils.throwIf(isSystemData::isPresent, "所选用户 [{}] 是系统内置用户,不允许删除", CheckUtils.throwIf(isSystemData::isPresent, "所选用户 [{}] 是系统内置用户,不允许删除",
isSystemData.orElseGet(UserDO::new).getNickname()); isSystemData.orElseGet(UserDO::new).getNickname());
// 删除用户和角色关联 // 删除用户和角色关联
userRoleService.deleteByUserIds(ids); userRoleService.deleteByUserIds(ids);
// 删除用户 // 删除用户
@ -169,18 +166,15 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, UserDO, UserVO,
String[] avatarSupportImgTypes = FileConsts.AVATAR_SUPPORTED_IMG_TYPES; String[] avatarSupportImgTypes = FileConsts.AVATAR_SUPPORTED_IMG_TYPES;
CheckUtils.throwIf(!StrUtil.equalsAnyIgnoreCase(avatarImageType, avatarSupportImgTypes), "头像仅支持 {} 格式的图片", CheckUtils.throwIf(!StrUtil.equalsAnyIgnoreCase(avatarImageType, avatarSupportImgTypes), "头像仅支持 {} 格式的图片",
String.join(StringConsts.CHINESE_COMMA, avatarSupportImgTypes)); String.join(StringConsts.CHINESE_COMMA, avatarSupportImgTypes));
UserDO user = super.getById(id);
// 上传新头像 // 上传新头像
UserDO user = super.getById(id);
String avatarPath = localStorageProperties.getPath().getAvatar(); String avatarPath = localStorageProperties.getPath().getAvatar();
File newAvatarFile = FileUtils.upload(avatarFile, avatarPath, false); File newAvatarFile = FileUtils.upload(avatarFile, avatarPath, false);
CheckUtils.throwIfNull(newAvatarFile, "上传头像失败"); CheckUtils.throwIfNull(newAvatarFile, "上传头像失败");
assert null != newAvatarFile; assert null != newAvatarFile;
// 更新用户头像 // 更新用户头像
String newAvatar = newAvatarFile.getName(); String newAvatar = newAvatarFile.getName();
baseMapper.lambdaUpdate().set(UserDO::getAvatar, newAvatar).eq(UserDO::getId, id).update(); baseMapper.lambdaUpdate().set(UserDO::getAvatar, newAvatar).eq(UserDO::getId, id).update();
// 删除原头像 // 删除原头像
String oldAvatar = user.getAvatar(); String oldAvatar = user.getAvatar();
if (StrUtil.isNotBlank(oldAvatar)) { if (StrUtil.isNotBlank(oldAvatar)) {
@ -203,7 +197,6 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, UserDO, UserVO,
CheckUtils.throwIfEqual(newPassword, oldPassword, "新密码不能与当前密码相同"); CheckUtils.throwIfEqual(newPassword, oldPassword, "新密码不能与当前密码相同");
UserDO user = super.getById(id); UserDO user = super.getById(id);
CheckUtils.throwIfNotEqual(SecureUtils.md5Salt(oldPassword, id.toString()), user.getPassword(), "当前密码错误"); CheckUtils.throwIfNotEqual(SecureUtils.md5Salt(oldPassword, id.toString()), user.getPassword(), "当前密码错误");
// 更新密码和密码重置时间 // 更新密码和密码重置时间
LocalDateTime now = LocalDateTime.now(); LocalDateTime now = LocalDateTime.now();
baseMapper.lambdaUpdate().set(UserDO::getPassword, SecureUtils.md5Salt(newPassword, id.toString())) baseMapper.lambdaUpdate().set(UserDO::getPassword, SecureUtils.md5Salt(newPassword, id.toString()))
@ -218,7 +211,6 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, UserDO, UserVO,
Long count = baseMapper.lambdaQuery().eq(UserDO::getEmail, newEmail).count(); Long count = baseMapper.lambdaQuery().eq(UserDO::getEmail, newEmail).count();
CheckUtils.throwIf(count > 0, "邮箱已绑定其他账号,请更换其他邮箱"); CheckUtils.throwIf(count > 0, "邮箱已绑定其他账号,请更换其他邮箱");
CheckUtils.throwIfEqual(newEmail, user.getEmail(), "新邮箱不能与当前邮箱相同"); CheckUtils.throwIfEqual(newEmail, user.getEmail(), "新邮箱不能与当前邮箱相同");
// 更新邮箱 // 更新邮箱
baseMapper.lambdaUpdate().set(UserDO::getEmail, newEmail).eq(UserDO::getId, id).update(); baseMapper.lambdaUpdate().set(UserDO::getEmail, newEmail).eq(UserDO::getId, id).update();
} }

View File

@ -15,8 +15,7 @@ const LIST: AppRouteRecordRaw = {
{ {
name: 'SearchTable', name: 'SearchTable',
path: 'search-table', // The midline path complies with SEO specifications path: 'search-table', // The midline path complies with SEO specifications
component: () => component: () => import('@/views/demo/list/search-table/index.vue'),
import('@/views/demo/list/search-table/index.vue'),
meta: { meta: {
locale: 'menu.list.searchTable', locale: 'menu.list.searchTable',
requiresAuth: true, requiresAuth: true,

View File

@ -48,15 +48,6 @@
{{ $t('workplace.docs.changelog') }} {{ $t('workplace.docs.changelog') }}
</a-link> </a-link>
</a-col> </a-col>
<a-col :span="12">
<a-link
href="https://blog.charles7c.top"
target="_blank"
rel="noopener"
>
{{ $t('workplace.docs.authorSite') }}👋
</a-link>
</a-col>
<a-col :span="12"> <a-col :span="12">
<a-link <a-link
href="https://doc.charles7c.top/require.html" href="https://doc.charles7c.top/require.html"
@ -66,6 +57,15 @@
{{ $t('workplace.docs.require') }} {{ $t('workplace.docs.require') }}
</a-link> </a-link>
</a-col> </a-col>
<a-col :span="12">
<a-link
href="https://blog.charles7c.top"
target="_blank"
rel="noopener"
>
{{ $t('workplace.docs.authorSite') }}👋
</a-link>
</a-col>
</a-row> </a-row>
</a-card> </a-card>
</template> </template>

View File

@ -14,8 +14,8 @@ export default {
'workplace.docs.userGuide': 'User Guide', 'workplace.docs.userGuide': 'User Guide',
'workplace.docs.faq': 'FAQ', 'workplace.docs.faq': 'FAQ',
'workplace.docs.changelog': 'Change Log', 'workplace.docs.changelog': 'Change Log',
'workplace.docs.authorSite': 'Author Site',
'workplace.docs.require': 'Require', 'workplace.docs.require': 'Require',
'workplace.docs.authorSite': 'Author Site',
'workplace.announcement': 'Announcement', 'workplace.announcement': 'Announcement',
'workplace.recently.visited': 'Recently Visited', 'workplace.recently.visited': 'Recently Visited',
'workplace.record.nodata': 'No data', 'workplace.record.nodata': 'No data',

View File

@ -14,8 +14,8 @@ export default {
'workplace.docs.userGuide': '使用指南', 'workplace.docs.userGuide': '使用指南',
'workplace.docs.faq': '常见问题', 'workplace.docs.faq': '常见问题',
'workplace.docs.changelog': '更新日志', 'workplace.docs.changelog': '更新日志',
'workplace.docs.authorSite': '作者主页',
'workplace.docs.require': '需求墙', 'workplace.docs.require': '需求墙',
'workplace.docs.authorSite': '作者主页',
'workplace.announcement': '公告', 'workplace.announcement': '公告',
'workplace.recently.visited': '最近访问', 'workplace.recently.visited': '最近访问',
'workplace.record.nodata': '暂无数据', 'workplace.record.nodata': '暂无数据',

View File

@ -50,7 +50,10 @@
<script lang="ts" setup> <script lang="ts" setup>
import { ref } from 'vue'; import { ref } from 'vue';
import useLoading from '@/hooks/loading'; import useLoading from '@/hooks/loading';
import { queryPopularAuthor, PopularAuthorRes } from '@/api/demo/visualization'; import {
queryPopularAuthor,
PopularAuthorRes,
} from '@/api/demo/visualization';
const { loading, setLoading } = useLoading(); const { loading, setLoading } = useLoading();
const tableData = ref<PopularAuthorRes>({ list: [] }); const tableData = ref<PopularAuthorRes>({ list: [] });

View File

@ -31,7 +31,10 @@
<script lang="ts" setup> <script lang="ts" setup>
import { computed, ref } from 'vue'; import { computed, ref } from 'vue';
import useLoading from '@/hooks/loading'; import useLoading from '@/hooks/loading';
import { queryDataChainGrowth, DataChainGrowth } from '@/api/demo/visualization'; import {
queryDataChainGrowth,
DataChainGrowth,
} from '@/api/demo/visualization';
import useChartOption from '@/hooks/chart-option'; import useChartOption from '@/hooks/chart-option';
const props = defineProps({ const props = defineProps({

View File

@ -36,7 +36,9 @@
<icon-face-smile-fill /> <icon-face-smile-fill />
</template> </template>
</a-Input> </a-Input>
<a-button type="primary">{{ $t('realTimeMonitor.chat.update') }}</a-button> <a-button type="primary">{{
$t('realTimeMonitor.chat.update')
}}</a-button>
</a-space> </a-space>
</div> </div>
</a-card> </a-card>

View File

@ -12,16 +12,26 @@
</a-tabs> </a-tabs>
<div class="data-statistic-content"> <div class="data-statistic-content">
<a-radio-group :default-value="3" type="button"> <a-radio-group :default-value="3" type="button">
<a-radio :value="1">{{ $t('realTimeMonitor.liveMethod.normal') }}</a-radio> <a-radio :value="1">{{
<a-radio :value="2">{{ $t('realTimeMonitor.liveMethod.flowControl') }}</a-radio> $t('realTimeMonitor.liveMethod.normal')
<a-radio :value="3">{{ $t('realTimeMonitor.liveMethod.video') }}</a-radio> }}</a-radio>
<a-radio :value="2">{{
$t('realTimeMonitor.liveMethod.flowControl')
}}</a-radio>
<a-radio :value="3">{{
$t('realTimeMonitor.liveMethod.video')
}}</a-radio>
<a-radio :value="4">{{ $t('realTimeMonitor.liveMethod.web') }}</a-radio> <a-radio :value="4">{{ $t('realTimeMonitor.liveMethod.web') }}</a-radio>
</a-radio-group> </a-radio-group>
<div class="data-statistic-list-wrapper"> <div class="data-statistic-list-wrapper">
<div class="data-statistic-list-header"> <div class="data-statistic-list-header">
<a-button type="text">{{ $t('realTimeMonitor.editCarousel') }}</a-button> <a-button type="text">{{
<a-button disabled>{{ $t('realTimeMonitor.startCarousel') }}</a-button> $t('realTimeMonitor.editCarousel')
}}</a-button>
<a-button disabled>{{
$t('realTimeMonitor.startCarousel')
}}</a-button>
</div> </div>
<div class="data-statistic-list-content"> <div class="data-statistic-list-content">
<DataStatisticList /> <DataStatisticList />

View File

@ -1,5 +1,8 @@
<template> <template>
<a-card class="general-card" :title="$t('realTimeMonitor.title.quickOperation')"> <a-card
class="general-card"
:title="$t('realTimeMonitor.title.quickOperation')"
>
<a-space direction="vertical" fill :size="10"> <a-space direction="vertical" fill :size="10">
<a-button long> <a-button long>
{{ $t('realTimeMonitor.quickOperation.changeClarity') }} {{ $t('realTimeMonitor.quickOperation.changeClarity') }}

View File

@ -1,7 +1,10 @@
<template> <template>
<a-card class="general-card" :title="$t('realTimeMonitor.title.studioInfo')"> <a-card class="general-card" :title="$t('realTimeMonitor.title.studioInfo')">
<a-form :model="{}" layout="vertical"> <a-form :model="{}" layout="vertical">
<a-form-item :label="$t('realTimeMonitor.studioInfo.label.studioTitle')" required> <a-form-item
:label="$t('realTimeMonitor.studioInfo.label.studioTitle')"
required
>
<a-input <a-input
:placeholder="`王立群${$t( :placeholder="`王立群${$t(
'realTimeMonitor.studioInfo.placeholder.studioTitle' 'realTimeMonitor.studioInfo.placeholder.studioTitle'
@ -27,7 +30,9 @@
<a-input-search /> <a-input-search />
</a-form-item> </a-form-item>
</a-form> </a-form>
<a-button type="primary">{{ $t('realTimeMonitor.studioInfo.btn.fresh') }}</a-button> <a-button type="primary">{{
$t('realTimeMonitor.studioInfo.btn.fresh')
}}</a-button>
</a-card> </a-card>
</template> </template>

View File

@ -4,7 +4,9 @@
:title="$t('realTimeMonitor.studioStatus.title.studioStatus')" :title="$t('realTimeMonitor.studioStatus.title.studioStatus')"
> >
<template #extra> <template #extra>
<a-tag color="green">{{ $t('realTimeMonitor.studioStatus.smooth') }}</a-tag> <a-tag color="green">{{
$t('realTimeMonitor.studioStatus.smooth')
}}</a-tag>
</template> </template>
<a-descriptions layout="horizontal" :data="dataStatus" :column="2"> <a-descriptions layout="horizontal" :data="dataStatus" :column="2">
<template #label="{ label }"> <template #label="{ label }">

View File

@ -1,5 +1,8 @@
<template> <template>
<a-card class="general-card" :title="$t('realTimeMonitor.title.studioPreview')"> <a-card
class="general-card"
:title="$t('realTimeMonitor.title.studioPreview')"
>
<template #extra> <template #extra>
<icon-more /> <icon-more />
</template> </template>
@ -7,15 +10,20 @@
<img <img
src="http://p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/c788fc704d32cf3b1136c7d45afc2669.png~tplv-uwbnlip3yd-webp.webp" src="http://p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/c788fc704d32cf3b1136c7d45afc2669.png~tplv-uwbnlip3yd-webp.webp"
class="studio-preview" class="studio-preview"
alt="Studio Preview"
/> />
<div class="studio-bar"> <div class="studio-bar">
<div v-if="userInfo"> <div v-if="userInfo">
<a-space :size="12"> <a-space :size="12">
<a-avatar :size="24"> <a-avatar :size="24">
<img :src="getAvatar(userInfo.avatar, userInfo.gender)" /> <img
:src="getAvatar(userInfo.avatar, userInfo.gender)"
alt="Avatar"
/>
</a-avatar> </a-avatar>
<a-typography-text> <a-typography-text>
{{ userInfo.nickname }} {{ $t('realTimeMonitor.studioPreview.studio') }} {{ userInfo.nickname }}
{{ $t('realTimeMonitor.studioPreview.studio') }}
</a-typography-text> </a-typography-text>
</a-space> </a-space>
</div> </div>

View File

@ -84,9 +84,7 @@
size="small" size="small"
:disabled="currentToken === record.token" :disabled="currentToken === record.token"
:title=" :title="
currentToken === record.token currentToken === record.token ? '不能强退自己' : '强退'
? '不能强退当前登录用户'
: '强退'
" "
> >
<template #icon><icon-delete /></template>强退 <template #icon><icon-delete /></template>强退

View File

@ -68,13 +68,11 @@ public class LoginController {
@Operation(summary = "用户登录", description = "根据用户名和密码进行登录认证") @Operation(summary = "用户登录", description = "根据用户名和密码进行登录认证")
@PostMapping("/login") @PostMapping("/login")
public R<LoginVO> login(@Validated @RequestBody LoginRequest loginRequest) { public R<LoginVO> login(@Validated @RequestBody LoginRequest loginRequest) {
// 校验验证码
String captchaKey = RedisUtils.formatKey(CacheConsts.CAPTCHA_KEY_PREFIX, loginRequest.getUuid()); String captchaKey = RedisUtils.formatKey(CacheConsts.CAPTCHA_KEY_PREFIX, loginRequest.getUuid());
String captcha = RedisUtils.getCacheObject(captchaKey); String captcha = RedisUtils.getCacheObject(captchaKey);
ValidationUtils.throwIfBlank(captcha, "验证码已失效"); ValidationUtils.throwIfBlank(captcha, "验证码已失效");
RedisUtils.deleteCacheObject(captchaKey); RedisUtils.deleteCacheObject(captchaKey);
ValidationUtils.throwIfNotEqualIgnoreCase(loginRequest.getCaptcha(), captcha, "验证码错误"); ValidationUtils.throwIfNotEqualIgnoreCase(loginRequest.getCaptcha(), captcha, "验证码错误");
// 用户登录 // 用户登录
String rawPassword = String rawPassword =
ExceptionUtils.exToNull(() -> SecureUtils.decryptByRsaPrivateKey(loginRequest.getPassword())); ExceptionUtils.exToNull(() -> SecureUtils.decryptByRsaPrivateKey(loginRequest.getPassword()));

View File

@ -73,7 +73,6 @@ public class CaptchaController {
// 生成验证码 // 生成验证码
CaptchaProperties.CaptchaImage captchaImage = captchaProperties.getImage(); CaptchaProperties.CaptchaImage captchaImage = captchaProperties.getImage();
Captcha captcha = captchaImage.getCaptcha(); Captcha captcha = captchaImage.getCaptcha();
// 保存验证码 // 保存验证码
String uuid = IdUtil.fastUUID(); String uuid = IdUtil.fastUUID();
String captchaKey = RedisUtils.formatKey(CacheConsts.CAPTCHA_KEY_PREFIX, uuid); String captchaKey = RedisUtils.formatKey(CacheConsts.CAPTCHA_KEY_PREFIX, uuid);

View File

@ -25,6 +25,8 @@ import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
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.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;
@ -92,6 +94,7 @@ public class CommonController {
} }
@Operation(summary = "查询枚举字典", description = "查询枚举字典列表") @Operation(summary = "查询枚举字典", description = "查询枚举字典列表")
@Parameter(name = "enumTypeName", description = "枚举类型名称", example = "DataScopeEnum", in = ParameterIn.PATH)
@GetMapping("/dict/enum/{enumTypeName}") @GetMapping("/dict/enum/{enumTypeName}")
public R<List<LabelValueVO>> listEnumDict(@PathVariable String enumTypeName) { public R<List<LabelValueVO>> listEnumDict(@PathVariable String enumTypeName) {
// 扫描所有 BaseEnum 枚举基类的子类 // 扫描所有 BaseEnum 枚举基类的子类

View File

@ -19,6 +19,8 @@ package top.charles7c.cnadmin.webapi.controller.monitor;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
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.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;
@ -55,7 +57,7 @@ public class LogController {
private final LogService logService; private final LogService logService;
@Log(module = "登录日志") @Log(module = "登录日志")
@Operation(summary = "分页查询登录日志列表") @Operation(summary = "分页查询登录日志列表", description = "分页查询登录日志列表")
@GetMapping("/login") @GetMapping("/login")
public R<PageDataVO<LoginLogVO>> page(LoginLogQuery query, @Validated PageQuery pageQuery) { public R<PageDataVO<LoginLogVO>> page(LoginLogQuery query, @Validated PageQuery pageQuery) {
PageDataVO<LoginLogVO> pageDataVO = logService.page(query, pageQuery); PageDataVO<LoginLogVO> pageDataVO = logService.page(query, pageQuery);
@ -63,7 +65,7 @@ public class LogController {
} }
@Log(module = "操作日志") @Log(module = "操作日志")
@Operation(summary = "分页查询操作日志列表") @Operation(summary = "分页查询操作日志列表", description = "分页查询操作日志列表")
@GetMapping("/operation") @GetMapping("/operation")
public R<PageDataVO<OperationLogVO>> page(OperationLogQuery query, @Validated PageQuery pageQuery) { public R<PageDataVO<OperationLogVO>> page(OperationLogQuery query, @Validated PageQuery pageQuery) {
PageDataVO<OperationLogVO> pageDataVO = logService.page(query, pageQuery); PageDataVO<OperationLogVO> pageDataVO = logService.page(query, pageQuery);
@ -71,7 +73,7 @@ public class LogController {
} }
@Log(module = "系统日志") @Log(module = "系统日志")
@Operation(summary = "分页查询系统日志列表") @Operation(summary = "分页查询系统日志列表", description = "分页查询系统日志列表")
@GetMapping("/system") @GetMapping("/system")
public R<PageDataVO<SystemLogVO>> page(SystemLogQuery query, @Validated PageQuery pageQuery) { public R<PageDataVO<SystemLogVO>> page(SystemLogQuery query, @Validated PageQuery pageQuery) {
PageDataVO<SystemLogVO> pageDataVO = logService.page(query, pageQuery); PageDataVO<SystemLogVO> pageDataVO = logService.page(query, pageQuery);
@ -79,7 +81,8 @@ public class LogController {
} }
@Log(module = "系统日志") @Log(module = "系统日志")
@Operation(summary = "查看系统日志详情") @Operation(summary = "查看系统日志详情", description = "查看系统日志详情")
@Parameter(name = "id", description = "ID", example = "1", in = ParameterIn.PATH)
@GetMapping("/system/{id}") @GetMapping("/system/{id}")
public R<SystemLogDetailVO> get(@PathVariable Long id) { public R<SystemLogDetailVO> get(@PathVariable Long id) {
SystemLogDetailVO detailVO = logService.get(id); SystemLogDetailVO detailVO = logService.get(id);

View File

@ -19,6 +19,8 @@ package top.charles7c.cnadmin.webapi.controller.monitor;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
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.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;
@ -49,20 +51,22 @@ public class OnlineUserController {
private final OnlineUserService onlineUserService; private final OnlineUserService onlineUserService;
@Operation(summary = "分页查询列表") @Operation(summary = "分页查询列表", description = "分页查询列表")
@SaCheckPermission("monitor:online:user:list") @SaCheckPermission("monitor:online:user:list")
@GetMapping @GetMapping
public R<PageDataVO<OnlineUserVO>> page(OnlineUserQuery query, @Validated PageQuery pageQuery) { public R<PageDataVO<OnlineUserVO>> page(OnlineUserQuery query, @Validated PageQuery pageQuery) {
return R.ok(onlineUserService.page(query, pageQuery)); return R.ok(onlineUserService.page(query, pageQuery));
} }
@Operation(summary = "强退在线用户") @Operation(summary = "强退在线用户", description = "强退在线用户")
@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 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);
return R.ok("强退成功"); return R.ok("强退成功");
} }

View File

@ -62,8 +62,6 @@ public class UserCenterController {
@PostMapping("/avatar") @PostMapping("/avatar")
public R<AvatarVO> uploadAvatar(@NotNull(message = "头像不能为空") MultipartFile avatarFile) { public R<AvatarVO> uploadAvatar(@NotNull(message = "头像不能为空") MultipartFile avatarFile) {
ValidationUtils.throwIf(avatarFile::isEmpty, "头像不能为空"); ValidationUtils.throwIf(avatarFile::isEmpty, "头像不能为空");
// 上传头像
String newAvatar = userService.uploadAvatar(avatarFile, LoginHelper.getUserId()); String newAvatar = userService.uploadAvatar(avatarFile, LoginHelper.getUserId());
return R.ok("上传成功", AvatarVO.builder().avatar(newAvatar).build()); return R.ok("上传成功", AvatarVO.builder().avatar(newAvatar).build());
} }
@ -86,8 +84,6 @@ public class UserCenterController {
ValidationUtils.throwIfBlank(rawNewPassword, "新密码解密失败"); ValidationUtils.throwIfBlank(rawNewPassword, "新密码解密失败");
ValidationUtils.throwIf(!ReUtil.isMatch(RegexConsts.PASSWORD, rawNewPassword), ValidationUtils.throwIf(!ReUtil.isMatch(RegexConsts.PASSWORD, rawNewPassword),
"密码长度为 6 到 32 位,可以包含字母、数字、下划线,特殊字符,同时包含字母和数字"); "密码长度为 6 到 32 位,可以包含字母、数字、下划线,特殊字符,同时包含字母和数字");
// 修改密码
userService.updatePassword(rawOldPassword, rawNewPassword, LoginHelper.getUserId()); userService.updatePassword(rawOldPassword, rawNewPassword, LoginHelper.getUserId());
return R.ok("修改成功"); return R.ok("修改成功");
} }
@ -99,14 +95,12 @@ public class UserCenterController {
ExceptionUtils.exToNull(() -> SecureUtils.decryptByRsaPrivateKey(updateEmailRequest.getCurrentPassword())); ExceptionUtils.exToNull(() -> SecureUtils.decryptByRsaPrivateKey(updateEmailRequest.getCurrentPassword()));
ValidationUtils.throwIfBlank(rawCurrentPassword, "当前密码解密失败"); ValidationUtils.throwIfBlank(rawCurrentPassword, "当前密码解密失败");
// 校验验证码
String captchaKey = RedisUtils.formatKey(CacheConsts.CAPTCHA_KEY_PREFIX, updateEmailRequest.getNewEmail()); String captchaKey = RedisUtils.formatKey(CacheConsts.CAPTCHA_KEY_PREFIX, updateEmailRequest.getNewEmail());
String captcha = RedisUtils.getCacheObject(captchaKey); String captcha = RedisUtils.getCacheObject(captchaKey);
ValidationUtils.throwIfBlank(captcha, "验证码已失效"); ValidationUtils.throwIfBlank(captcha, "验证码已失效");
ValidationUtils.throwIfNotEqualIgnoreCase(updateEmailRequest.getCaptcha(), captcha, "验证码错误"); ValidationUtils.throwIfNotEqualIgnoreCase(updateEmailRequest.getCaptcha(), captcha, "验证码错误");
RedisUtils.deleteCacheObject(captchaKey); RedisUtils.deleteCacheObject(captchaKey);
// 修改邮箱
userService.updateEmail(updateEmailRequest.getNewEmail(), rawCurrentPassword, LoginHelper.getUserId()); userService.updateEmail(updateEmailRequest.getNewEmail(), rawCurrentPassword, LoginHelper.getUserId());
return R.ok("修改成功"); return R.ok("修改成功");
} }

View File

@ -17,6 +17,8 @@
package top.charles7c.cnadmin.webapi.controller.system; package top.charles7c.cnadmin.webapi.controller.system;
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.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;
@ -59,6 +61,7 @@ public class UserController extends BaseController<UserService, UserVO, UserDeta
} }
@Operation(summary = "重置密码", description = "重置用户登录密码为默认密码") @Operation(summary = "重置密码", description = "重置用户登录密码为默认密码")
@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 resetPassword(@PathVariable Long id) {
@ -67,9 +70,10 @@ public class UserController extends BaseController<UserService, UserVO, UserDeta
} }
@Operation(summary = "分配角色", description = "为用户新增或移除角色") @Operation(summary = "分配角色", description = "为用户新增或移除角色")
@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(@PathVariable Long id, @Validated @RequestBody UpdateUserRoleRequest request) { public R updateRole(@Validated @RequestBody UpdateUserRoleRequest request, @PathVariable Long id) {
baseService.updateRole(request, id); baseService.updateRole(request, id);
return R.ok("分配成功"); return R.ok("分配成功");
} }

View File

@ -23,7 +23,6 @@ import lombok.RequiredArgsConstructor;
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.Parameters;
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;
@ -67,10 +66,8 @@ public class GeneratorController {
} }
@Operation(summary = "查询字段配置列表", description = "查询字段配置列表") @Operation(summary = "查询字段配置列表", description = "查询字段配置列表")
@Parameters({ @Parameter(name = "tableName", description = "表名称", required = true, example = "sys_user", in = ParameterIn.PATH)
@Parameter(name = "tableName", description = "表名称", required = true, example = "sys_user", @Parameter(name = "requireSync", description = "是否需要同步", example = "false", in = ParameterIn.QUERY)
in = ParameterIn.PATH),
@Parameter(name = "requireSync", description = "是否需要同步", example = "true", in = ParameterIn.QUERY)})
@SaCheckPermission("tool:generator:list") @SaCheckPermission("tool:generator:list")
@GetMapping("/field/{tableName}") @GetMapping("/field/{tableName}")
public R<List<FieldConfigDO>> listFieldConfig(@PathVariable String tableName, public R<List<FieldConfigDO>> listFieldConfig(@PathVariable String tableName,