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 分页信息
*/
@Operation(summary = "分页查询列表")
@Operation(summary = "分页查询列表", description = "分页查询列表")
@ResponseBody
@GetMapping
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 树列表信息
*/
@Operation(summary = "查询树列表")
@Operation(summary = "查询树列表", description = "查询树列表")
@ResponseBody
@GetMapping("/tree")
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 列表信息
*/
@Operation(summary = "查询列表")
@Operation(summary = "查询列表", description = "查询列表")
@ResponseBody
@GetMapping("/list")
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
* @return 详情信息
*/
@Operation(summary = "查看详情")
@Parameter(name = "id", description = "ID", in = ParameterIn.PATH)
@Operation(summary = "查看详情", description = "查看详情")
@Parameter(name = "id", description = "ID", example = "1", in = ParameterIn.PATH)
@ResponseBody
@GetMapping("/{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
*/
@Operation(summary = "新增数据")
@Operation(summary = "新增数据", description = "新增数据")
@ResponseBody
@PostMapping
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
* @return /
*/
@Operation(summary = "修改数据")
@Operation(summary = "修改数据", description = "修改数据")
@Parameter(name = "id", description = "ID", example = "1", in = ParameterIn.PATH)
@ResponseBody
@PutMapping("/{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 列表
* @return /
*/
@Operation(summary = "删除数据")
@Parameter(name = "ids", description = "ID 列表", in = ParameterIn.PATH)
@Operation(summary = "删除数据", description = "删除数据")
@Parameter(name = "ids", description = "ID 列表", example = "1,2", in = ParameterIn.PATH)
@ResponseBody
@DeleteMapping("/{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
* 响应对象
*/
@Operation(summary = "导出数据")
@Operation(summary = "导出数据", description = "导出数据")
@GetMapping("/export")
public void export(Q query, SortQuery sortQuery, HttpServletResponse response) {
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();
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);
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)
private Boolean disabled;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -58,7 +58,6 @@ public class MenuServiceImpl extends BaseServiceImpl<MenuMapper, MenuDO, MenuVO,
String title = request.getTitle();
boolean isExists = this.checkNameExists(title, request.getParentId(), null);
CheckUtils.throwIf(isExists, "新增失败,[{}] 已存在", title);
request.setStatus(DisEnableStatusEnum.ENABLE);
return super.add(request);
}
@ -70,7 +69,6 @@ public class MenuServiceImpl extends BaseServiceImpl<MenuMapper, MenuDO, MenuVO,
String title = request.getTitle();
boolean isExists = this.checkNameExists(title, request.getParentId(), id);
CheckUtils.throwIf(isExists, "修改失败,[{}] 已存在", title);
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);
String code = request.getCode();
CheckUtils.throwIf(this.checkCodeExists(code, null), "新增失败,[{}] 已存在", code);
// 新增信息
request.setStatus(DisEnableStatusEnum.ENABLE);
Long roleId = super.add(request);
@ -101,7 +100,6 @@ public class RoleServiceImpl extends BaseServiceImpl<RoleMapper, RoleDO, RoleVO,
CheckUtils.throwIfNotEqual(request.getDataScope(), oldDataScope, "[{}] 是系统内置角色,不允许修改角色数据权限",
oldRole.getName());
}
// 更新信息
super.update(request, id);
// 更新关联信息
@ -128,7 +126,6 @@ public class RoleServiceImpl extends BaseServiceImpl<RoleMapper, RoleDO, RoleVO,
CheckUtils.throwIf(isSystemData::isPresent, "所选角色 [{}] 是系统内置角色,不允许删除",
isSystemData.orElseGet(RoleDO::new).getName());
CheckUtils.throwIf(userRoleService.countByRoleIds(ids) > 0, "所选角色存在用户关联,请解除关联后重试");
// 删除角色和菜单关联
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);
String phone = request.getPhone();
CheckUtils.throwIf(StrUtil.isNotBlank(phone) && this.checkPhoneExists(phone, null), "新增失败,[{}] 已存在", phone);
// 新增信息
request.setStatus(DisEnableStatusEnum.ENABLE);
Long userId = super.add(request);
@ -125,7 +124,6 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, UserDO, UserVO,
CollUtil.disjunction(request.getRoleIds(), userRoleService.listRoleIdByUserId(id));
CheckUtils.throwIfNotEmpty(disjunctionRoleIds, "[{}] 是系统内置用户,不允许变更所属角色", oldUser.getNickname());
}
// 更新信息
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();
CheckUtils.throwIf(isSystemData::isPresent, "所选用户 [{}] 是系统内置用户,不允许删除",
isSystemData.orElseGet(UserDO::new).getNickname());
// 删除用户和角色关联
userRoleService.deleteByUserIds(ids);
// 删除用户
@ -169,18 +166,15 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, UserDO, UserVO,
String[] avatarSupportImgTypes = FileConsts.AVATAR_SUPPORTED_IMG_TYPES;
CheckUtils.throwIf(!StrUtil.equalsAnyIgnoreCase(avatarImageType, avatarSupportImgTypes), "头像仅支持 {} 格式的图片",
String.join(StringConsts.CHINESE_COMMA, avatarSupportImgTypes));
UserDO user = super.getById(id);
// 上传新头像
UserDO user = super.getById(id);
String avatarPath = localStorageProperties.getPath().getAvatar();
File newAvatarFile = FileUtils.upload(avatarFile, avatarPath, false);
CheckUtils.throwIfNull(newAvatarFile, "上传头像失败");
assert null != newAvatarFile;
// 更新用户头像
String newAvatar = newAvatarFile.getName();
baseMapper.lambdaUpdate().set(UserDO::getAvatar, newAvatar).eq(UserDO::getId, id).update();
// 删除原头像
String oldAvatar = user.getAvatar();
if (StrUtil.isNotBlank(oldAvatar)) {
@ -203,7 +197,6 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, UserDO, UserVO,
CheckUtils.throwIfEqual(newPassword, oldPassword, "新密码不能与当前密码相同");
UserDO user = super.getById(id);
CheckUtils.throwIfNotEqual(SecureUtils.md5Salt(oldPassword, id.toString()), user.getPassword(), "当前密码错误");
// 更新密码和密码重置时间
LocalDateTime now = LocalDateTime.now();
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();
CheckUtils.throwIf(count > 0, "邮箱已绑定其他账号,请更换其他邮箱");
CheckUtils.throwIfEqual(newEmail, user.getEmail(), "新邮箱不能与当前邮箱相同");
// 更新邮箱
baseMapper.lambdaUpdate().set(UserDO::getEmail, newEmail).eq(UserDO::getId, id).update();
}

View File

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

View File

@ -48,15 +48,6 @@
{{ $t('workplace.docs.changelog') }}
</a-link>
</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-link
href="https://doc.charles7c.top/require.html"
@ -66,6 +57,15 @@
{{ $t('workplace.docs.require') }}
</a-link>
</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-card>
</template>

View File

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

View File

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

View File

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

View File

@ -31,7 +31,10 @@
<script lang="ts" setup>
import { computed, ref } from 'vue';
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';
const props = defineProps({

View File

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

View File

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

View File

@ -1,5 +1,8 @@
<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-button long>
{{ $t('realTimeMonitor.quickOperation.changeClarity') }}

View File

@ -1,7 +1,10 @@
<template>
<a-card class="general-card" :title="$t('realTimeMonitor.title.studioInfo')">
<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
:placeholder="`王立群${$t(
'realTimeMonitor.studioInfo.placeholder.studioTitle'
@ -27,7 +30,9 @@
<a-input-search />
</a-form-item>
</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>
</template>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -19,6 +19,8 @@ package top.charles7c.cnadmin.webapi.controller.monitor;
import lombok.RequiredArgsConstructor;
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 org.springframework.validation.annotation.Validated;
@ -49,20 +51,22 @@ public class OnlineUserController {
private final OnlineUserService onlineUserService;
@Operation(summary = "分页查询列表")
@Operation(summary = "分页查询列表", description = "分页查询列表")
@SaCheckPermission("monitor:online:user:list")
@GetMapping
public R<PageDataVO<OnlineUserVO>> page(OnlineUserQuery query, @Validated PageQuery 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")
@DeleteMapping("/{token}")
public R kickout(@PathVariable String token) {
String currentToken = StpUtil.getTokenValue();
CheckUtils.throwIfEqual(token, currentToken, "不能强退当前登录");
CheckUtils.throwIfEqual(token, currentToken, "不能强退自己");
StpUtil.kickoutByTokenValue(token);
return R.ok("强退成功");
}

View File

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

View File

@ -17,6 +17,8 @@
package top.charles7c.cnadmin.webapi.controller.system;
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 org.springframework.validation.annotation.Validated;
@ -59,6 +61,7 @@ public class UserController extends BaseController<UserService, UserVO, UserDeta
}
@Operation(summary = "重置密码", description = "重置用户登录密码为默认密码")
@Parameter(name = "id", description = "ID", example = "1", in = ParameterIn.PATH)
@SaCheckPermission("system:user:password:reset")
@PatchMapping("/{id}/password")
public R resetPassword(@PathVariable Long id) {
@ -67,9 +70,10 @@ public class UserController extends BaseController<UserService, UserVO, UserDeta
}
@Operation(summary = "分配角色", description = "为用户新增或移除角色")
@Parameter(name = "id", description = "ID", example = "1", in = ParameterIn.PATH)
@SaCheckPermission("system:user:role:update")
@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);
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.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
@ -67,10 +66,8 @@ public class GeneratorController {
}
@Operation(summary = "查询字段配置列表", description = "查询字段配置列表")
@Parameters({
@Parameter(name = "tableName", description = "表名称", required = true, example = "sys_user",
in = ParameterIn.PATH),
@Parameter(name = "requireSync", description = "是否需要同步", example = "true", in = ParameterIn.QUERY)})
@Parameter(name = "tableName", description = "表名称", required = true, example = "sys_user", in = ParameterIn.PATH)
@Parameter(name = "requireSync", description = "是否需要同步", example = "false", in = ParameterIn.QUERY)
@SaCheckPermission("tool:generator:list")
@GetMapping("/field/{tableName}")
public R<List<FieldConfigDO>> listFieldConfig(@PathVariable String tableName,