fix: 修复很多bug

This commit is contained in:
Bunny 2024-10-24 23:39:09 +08:00
parent e5c71400ad
commit d5850f66dd
30 changed files with 605 additions and 454 deletions

View File

@ -1,17 +1,16 @@
package cn.bunny.dao.vo.quartz;
import cn.bunny.dao.vo.common.BaseVo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.*;
@EqualsAndHashCode(callSuper = true)
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Schema(name = "SchedulersGroupVo", title = "任务调度分组返回对象", description = "任务调度分组返回对象")
public class SchedulersGroupVo {
public class SchedulersGroupVo extends BaseVo {
@Schema(name = "groupName", title = "分组名称")
private String groupName;

View File

@ -0,0 +1,121 @@
package cn.bunny.dao.vo.system.configuration;
import com.alibaba.fastjson2.annotation.JSONField;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Schema(name = "WebConfigurationVo对象", title = "前端配置选项", description = "前端配置选项")
public class WebConfigurationVo {
@Schema(name = "Version", description = "应用程序的版本")
@JSONField(format = "Version")
private String version;
@Schema(name = "Title", description = "应用程序的标题")
@JSONField(format = "Title")
private String title;
@Schema(name = "Copyright", description = "版权信息")
@JSONField(format = "Copyright")
private String copyright;
@Schema(name = "FixedHeader", description = "头部是否固定")
@JSONField(format = "FixedHeader")
private boolean fixedHeader;
@Schema(name = "HiddenSideBar", description = "侧边栏是否隐藏")
@JSONField(format = "FixedHeader")
private boolean hiddenSideBar;
@Schema(name = "MultiTagsCache", description = "是否缓存多个标签")
@JSONField(format = "FixedHeader")
private boolean multiTagsCache;
@Schema(name = "KeepAlive", description = "是否持久化")
@JSONField(format = "FixedHeader")
private boolean keepAlive;
@Schema(name = "Locale", description = "语言类型")
@JSONField(format = "Locale")
private String locale;
@Schema(name = "Layout", description = "应用程序的布局")
@JSONField(name = "Layout")
private String layout;
@Schema(name = "Theme", description = "应用程序的主题")
@JSONField(format = "FixedHeader")
private String theme;
@Schema(name = "DarkMode", description = "是否启用深色模式")
@JSONField(format = "FixedHeader")
private boolean darkMode;
@Schema(name = "OverallStyle", description = "应用程序的整体样式")
@JSONField(format = "FixedHeader")
private String overallStyle;
@Schema(name = "Grey", description = "是否启用灰色模式")
@JSONField(format = "FixedHeader")
private boolean grey;
@Schema(name = "Weak", description = "色弱模式")
@JSONField(format = "FixedHeader")
private boolean weak;
@Schema(name = "HideTabs", description = "是否隐藏选项卡")
@JSONField(format = "HideTabs")
private boolean hideTabs;
@Schema(name = "HideFooter", description = "是否隐藏页脚")
@JSONField(format = "HideFooter")
private boolean hideFooter;
@Schema(name = "Stretch", description = "是否拉伸显示")
@JSONField(format = "Stretch")
private boolean stretch;
@Schema(name = "SidebarStatus", description = "侧边栏的状态")
@JSONField(format = "SidebarStatus")
private boolean sidebarStatus;
@Schema(name = "EpThemeColor", description = "主题颜色")
@JSONField(format = "EpThemeColor")
private String epThemeColor;
@Schema(name = "ShowLogo", description = "是否显示logo")
@JSONField(format = "ShowLogo")
private boolean showLogo;
@Schema(name = "ShowModel", description = "要显示的模型")
@JSONField(format = "ShowModel")
private String showModel;
@Schema(name = "MenuArrowIconNoTransition", description = "菜单箭头图标是否没有过渡效果")
@JSONField(format = "MenuArrowIconNoTransition")
private boolean menuArrowIconNoTransition;
@Schema(name = "CachingAsyncRoutes", description = "是否缓存异步路由")
@JSONField(format = "CachingAsyncRoutes")
private boolean cachingAsyncRoutes;
@Schema(name = "TooltipEffect", description = "工具提示的效果")
@JSONField(format = "TooltipEffect")
private String tooltipEffect;
@Schema(name = "ResponsiveStorageNameSpace", description = "响应式存储的命名空间")
@JSONField(format = "ResponsiveStorageNameSpace")
private String responsiveStorageNameSpace;
@Schema(name = "MenuSearchHistory", description = "菜单搜索历史")
@JSONField(format = "MenuSearchHistory")
private int menuSearchHistory;
}

File diff suppressed because it is too large Load Diff

View File

@ -28,7 +28,7 @@ public class RolePowerController {
@Autowired
private RolePowerService rolePowerService;
@Operation(summary = "根据角色id获取权限内容", description = "角色列获取已选择的权限")
@Operation(summary = "根据角色id获取权限内容", description = "根据角色id获取权限内容")
@GetMapping("noManage/getPowerListByRoleId")
public Mono<Result<List<String>>> getPowerListByRoleId(Long id) {
List<String> voList = rolePowerService.getPowerListByRoleId(id);
@ -37,8 +37,8 @@ public class RolePowerController {
@Operation(summary = "为角色分配权限", description = "为角色分配权限")
@PostMapping("assignPowersToRole")
public Mono<Result<String>> assignPowersToRole(@Valid @RequestBody AssignPowersToRoleDto dto) {
public Result<String> assignPowersToRole(@Valid @RequestBody AssignPowersToRoleDto dto) {
rolePowerService.assignPowersToRole(dto);
return Mono.just(Result.success());
return Result.success();
}
}

View File

@ -59,7 +59,7 @@ public class RouterController {
return Mono.just(Result.success(voPageResult));
}
@Operation(summary = "管理菜单列", description = "管理菜单列")
@Operation(summary = "管理菜单列", description = "管理菜单列")
@GetMapping("getMenusList")
public Mono<Result<List<RouterManageVo>>> getMenusList(RouterManageDto dto) {
List<RouterManageVo> voPageResult = routerService.getMenusList(dto);

View File

@ -39,7 +39,7 @@ public interface PowerMapper extends BaseMapper<Power> {
void deleteBatchIdsWithPhysics(List<Long> ids);
/**
* * 根据用户id查询当前用户所有角色
* * 根据用户id查询当前用户所有权限
*
* @param userId 用户id
*/

View File

@ -1,5 +1,6 @@
package cn.bunny.services.mapper;
import cn.bunny.dao.entity.system.Power;
import cn.bunny.dao.entity.system.RolePower;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
@ -38,4 +39,12 @@ public interface RolePowerMapper extends BaseMapper<RolePower> {
* @return 已选择的权限列表
*/
List<RolePower> selectPowerListByRoleId(Long roleId);
/**
* * 根据角色id列表获取权限内容
*
* @param roleIds 角色id列表
* @return 已选择的权限列表
*/
List<Power> selectPowerListByRoleIds(List<Long> roleIds);
}

View File

@ -30,4 +30,5 @@ public interface UserRoleMapper extends BaseMapper<UserRole> {
* @param roleIds 角色id列表
*/
void deleteBatchIdsByRoleIdsWithPhysics(List<Long> roleIds);
}

View File

@ -83,7 +83,6 @@ public class WebSecurityConfig {
"/", "/ws/**",
"/*/*/noAuth/**", "/*/noAuth/**", "/noAuth/**",
"/media.ico", "/favicon.ico", "*.html", "/webjars/**", "/v3/api-docs/**", "swagger-ui/**",
"/*/files/**",
"/error", "/*/i18n/getI18n",
};
return web -> web.ignoring().requestMatchers(annotations)

View File

@ -1,7 +1,7 @@
package cn.bunny.services.security.custom;
import cn.bunny.common.service.context.BaseContext;
import cn.bunny.dao.entity.system.AdminUser;
import cn.bunny.dao.vo.system.user.LoginVo;
import java.util.List;
@ -9,15 +9,29 @@ import java.util.List;
* 检查是否是管理员
*/
public class CustomCheckIsAdmin {
public static boolean checkAdmin(List<String> roleList, LoginVo loginVo) {
/**
* 判断是否是管理员
*
* @param roleList 角色代码列表
* @return 是否是管理员
*/
public static boolean checkAdmin(List<String> roleList) {
// 判断是否是超级管理员
if (loginVo.getId().equals(1L)) return true;
if (BaseContext.getUserId().equals(1L)) return true;
// 判断是否是 admin
return roleList.stream().anyMatch(role -> role.equals("admin"));
}
/**
* 判断是否是管理员
*
* @param roleList 角色代码列表
* @param permissions 权限列表
* @param adminUser 用户信息
* @return 是否是管理员
*/
public static boolean checkAdmin(List<String> roleList, List<String> permissions, AdminUser adminUser) {
// 判断是否是超级管理员
boolean isIdAdmin = adminUser.getId().equals(1L);

View File

@ -2,8 +2,9 @@ package cn.bunny.services.security.service.impl;
import cn.bunny.common.service.context.BaseContext;
import cn.bunny.dao.entity.system.Power;
import cn.bunny.dao.vo.system.user.LoginVo;
import cn.bunny.dao.entity.system.Role;
import cn.bunny.services.mapper.PowerMapper;
import cn.bunny.services.mapper.RoleMapper;
import cn.bunny.services.security.custom.CustomCheckIsAdmin;
import jakarta.servlet.http.HttpServletRequest;
import lombok.SneakyThrows;
@ -15,6 +16,7 @@ import org.springframework.security.core.Authentication;
import org.springframework.security.web.access.intercept.RequestAuthorizationContext;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.util.List;
import java.util.function.Supplier;
@ -31,6 +33,9 @@ public class CustomAuthorizationManagerServiceImpl implements AuthorizationManag
@Autowired
private PowerMapper powerMapper;
@Autowired
private RoleMapper roleMapper;
@SneakyThrows
@Override
public AuthorizationDecision check(Supplier<Authentication> authentication, RequestAuthorizationContext context) {
@ -47,25 +52,29 @@ public class CustomAuthorizationManagerServiceImpl implements AuthorizationManag
* @param request 请求url地址
*/
private Boolean hasAuth(HttpServletRequest request) {
// 角色代码列表
LoginVo loginVo = BaseContext.getLoginVo();
List<String> roleCodeList = loginVo.getRoles();
// 根据用户ID查询角色数据
Long userId = BaseContext.getUserId();
List<Role> roleList = roleMapper.selectListByUserId(userId);
// 角色代码
List<String> roleCodeList = roleList.stream().map(Role::getRoleCode).toList();
// 判断是否是管理员用户
boolean checkedAdmin = CustomCheckIsAdmin.checkAdmin(roleCodeList, loginVo);
boolean checkedAdmin = CustomCheckIsAdmin.checkAdmin(roleCodeList);
if (checkedAdmin) return true;
// 判断请求地址是否是 noManage 不需要被验证的
String requestURI = request.getRequestURI();
if (requestURI.contains("noManage")) return true;
// 不是 admin查询角色权限关系表,根据权限码查询可以访问URL
List<String> powerCodes = loginVo.getPermissions();
List<Power> powerList = powerMapper.selectListByPowerCodes(powerCodes);
// 根据角色列表查询权限信息
List<Power> powerList = powerMapper.selectListByUserId(userId);
// 判断是否与请求路径匹配
return powerList.stream()
.anyMatch(power -> AntPathRequestMatcher.antMatcher(power.getRequestUrl()).matches(request) ||
requestURI.matches(power.getRequestUrl()));
return powerList.stream().map(Power::getRequestUrl)
.anyMatch(requestUrl -> {
boolean antMatcher = StringUtils.hasText(requestUrl) && new AntPathRequestMatcher(requestUrl).matches(request);
return antMatcher || requestURI.matches(requestUrl);
});
}
}

View File

@ -17,7 +17,6 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.validation.Valid;
import org.springframework.beans.BeanUtils;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
@ -68,14 +67,14 @@ public class MenuIconServiceImpl extends ServiceImpl<MenuIconMapper, MenuIcon> i
* @return 图标返回列表
*/
@Override
@Cacheable(cacheNames = "menuIcon", key = "'menuIconList'", cacheManager = "cacheManagerWithMouth")
public List<MenuIconVo> getIconNameList(String iconName) {
return list(Wrappers.<MenuIcon>lambdaQuery().like(MenuIcon::getIconName, iconName))
.stream().map(menuIcon -> {
MenuIconVo menuIconVo = new MenuIconVo();
BeanUtils.copyProperties(menuIcon, menuIconVo);
return menuIconVo;
}).collect(Collectors.collectingAndThen(
})
.collect(Collectors.collectingAndThen(
Collectors.toMap(
MenuIconVo::getIconName,
i -> i,

View File

@ -44,8 +44,8 @@ public class RolePowerServiceImpl extends ServiceImpl<RolePowerMapper, RolePower
List<Long> powerIds = dto.getPowerIds();
Long roleId = dto.getRoleId();
// 删除所有权限
baseMapper.deleteBatchPowerIdsWithPhysics(powerIds);
// 删除这个角色下所有权限
baseMapper.deleteBatchRoleIdsWithPhysics(List.of(roleId));
// 保存分配数据
List<RolePower> rolePowerList = powerIds.stream().map(powerId -> {

View File

@ -77,7 +77,7 @@ public class RouterServiceImpl extends ServiceImpl<RouterMapper, Router> impleme
List<UserRouterVo> list = new ArrayList<>();
// 查询用户角色判断是否是管理员角色
boolean isAdmin = CustomCheckIsAdmin.checkAdmin(roleList, loginVo);
boolean isAdmin = CustomCheckIsAdmin.checkAdmin(roleList);
if (isAdmin) routerList = list();
else {
List<Long> routerIds = baseMapper.selectListByUserId(loginVo.getId());
@ -220,7 +220,11 @@ public class RouterServiceImpl extends ServiceImpl<RouterMapper, Router> impleme
List<Long> longList = list(Wrappers.<Router>lambdaQuery().in(Router::getParentId, ids)).stream().map(Router::getId).toList();
ids.addAll(longList);
baseMapper.deleteBatchIdsWithPhysics(ids);
// 逻辑删除
removeBatchByIds(ids);
// 物理删除
// baseMapper.deleteBatchIdsWithPhysics(ids);
}
/**

View File

@ -84,6 +84,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, AdminUser> implemen
@Autowired
private EmailTemplateMapper emailTemplateMapper;
@Autowired
private RoleMapper roleMapper;
@ -392,18 +393,21 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, AdminUser> implemen
// 分页查询菜单图标
IPage<AdminUserAndDept> page = baseMapper.selectListByPage(pageParams, dto);
List<AdminUserVo> voList = page.getRecords().stream().map(AdminUser -> {
// 如果存在用户头像则设置用户头像
String avatar = AdminUser.getAvatar();
if (StringUtils.hasText(avatar)) {
avatar = minioUtil.getObjectNameFullPath(avatar);
}
List<AdminUserVo> voList = page.getRecords().stream()
.map(adminUser -> {
// 如果存在用户头像则设置用户头像
String avatar = adminUser.getAvatar();
if (StringUtils.hasText(avatar)) {
avatar = minioUtil.getObjectNameFullPath(avatar);
}
AdminUserVo adminUserVo = new AdminUserVo();
BeanUtils.copyProperties(AdminUser, adminUserVo);
adminUserVo.setAvatar(avatar);
return adminUserVo;
}).toList();
AdminUserVo adminUserVo = new AdminUserVo();
BeanUtils.copyProperties(adminUser, adminUserVo);
adminUserVo.setAvatar(avatar);
return adminUserVo;
})
.filter(adminUserVo -> !adminUserVo.getId().equals(1L))
.toList();
return PageResult.<AdminUserVo>builder()
.list(voList)

View File

@ -21,7 +21,7 @@ mybatis-plus:
logic-not-delete-value: 0 # 逻辑未删除值
configuration:
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 查看日志
# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 查看日志
bunny:
master:
@ -43,5 +43,5 @@ bunny:
secretKey: "02120212"
bucket-name: auth-admin
backPath: "D:\\MyFolder\\backup"
bashPath: "D:\\MyFolder"
backPath: "D:\\MyData\\backup"
bashPath: "D:\\MyData"

View File

@ -79,7 +79,7 @@ management:
web:
exposure:
include: "*"
base-path: /admin
base-path: /admin/actuator
info:
env:
enabled: true

View File

@ -27,6 +27,7 @@
<include refid="Base_Column_List"/>
from sys_dept
<where>
is_deleted = 0
<if test="dto.parentId != null and dto.parentId != ''">
and parent_id like CONCAT('%',#{dto.parentId},'%')
</if>

View File

@ -29,6 +29,7 @@
<include refid="Base_Column_List"/>
from sys_email_template
<where>
is_deleted = 0
<if test="dto.templateName != null and dto.templateName != ''">
and template_name like CONCAT('%',#{dto.templateName},'%')
</if>

View File

@ -29,6 +29,7 @@
<include refid="Base_Column_List"/>
from sys_email_users
<where>
is_deleted = 0
<if test="dto.email != null and dto.email != ''">
and email like CONCAT('%',#{dto.email},'%')
</if>

View File

@ -28,6 +28,7 @@
<include refid="Base_Column_List"/>
from sys_files
<where>
is_deleted = 0
<if test="dto.filename != null and dto.filename != ''">
and filename like CONCAT('%',#{dto.filename},'%')
</if>

View File

@ -36,6 +36,7 @@
<include refid="Base_Column_List"/>
from sys_i18n
<where>
is_deleted = 0
<if test="dto.keyName != null and dto.keyName != ''">
and key_name like CONCAT('%',#{dto.keyName},'%')
</if>

View File

@ -25,6 +25,7 @@
<include refid="Base_Column_List"/>
from sys_menu_icon
<where>
is_deleted = 0
<if test="dto.iconCode != null and dto.iconCode != ''">
and icon_code like CONCAT('%',#{dto.iconCode},'%')
</if>

View File

@ -27,6 +27,7 @@
<include refid="Base_Column_List"/>
from sys_power
<where>
is_deleted = 0
<if test="dto.powerCode != null and dto.powerCode != ''">
and power_code like CONCAT('%',#{dto.powerCode},'%')
</if>
@ -50,7 +51,7 @@
</foreach>
</delete>
<!-- 根据用户id查询当前用户所有角色 -->
<!-- 根据用户id查询当前用户所有权限 -->
<select id="selectListByUserId" resultType="cn.bunny.dao.entity.system.Power">
SELECT p.*
FROM sys_user u,
@ -58,6 +59,7 @@
sys_role_power rp,
sys_power p
WHERE u.id = ur.user_id
AND u.is_deleted = 0
AND ur.role_id = rp.role_id
AND rp.power_id = p.id
AND u.id = #{userId}

View File

@ -25,6 +25,7 @@
<include refid="Base_Column_List"/>
from sys_role
<where>
is_deleted = 0
<if test="dto.roleCode != null and dto.roleCode != ''">
and role_code like CONCAT('%',#{dto.roleCode},'%')
</if>
@ -52,6 +53,7 @@
sys_role r,
sys_user_role ur
WHERE u.id = ur.user_id
AND u.is_deleted = 0
AND r.id = ur.role_id
AND ur.user_id = #{userId}
</select>

View File

@ -46,4 +46,15 @@
where role_id = #{roleId}
</select>
<!-- 根据角色id列表获取权限内容 -->
<select id="selectPowerListByRoleIds" resultType="cn.bunny.dao.entity.system.Power">
SELECT power.*
FROM sys_role_power rp
LEFT JOIN sys_role role ON rp.role_id = role.id
LEFT JOIN sys_power power ON rp.power_id = power.id AND rp.role_id in
<foreach collection="roleIds" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
</select>
</mapper>

View File

@ -44,7 +44,8 @@
LEFT JOIN sys_user user ON user_role.user_id = user.id
LEFT JOIN sys_router_role router_role ON user_role.role_id = router_role.role_id
LEFT JOIN sys_router router ON router_role.router_id = router.id
WHERE user.id = #{userId}
WHERE user.is_deleted = 0
AND user.id = #{userId}
</select>
<!-- 递归查询所有父级Id直到查询到父级Id为0 -->
@ -69,6 +70,7 @@
select *
from sys_router
<where>
is_deleted = 0
<if test="dto.title != null and dto.title != ''">
and title like CONCAT('%',#{dto.title},'%')
</if>

View File

@ -30,6 +30,7 @@
<include refid="Base_Column_List"/>
from log_quartz_execute
<where>
is_deleted = 0
<if test="dto.jobName != null and dto.jobName != ''">
and job_name like CONCAT('%',#{dto.jobName},'%')
</if>

View File

@ -31,6 +31,7 @@
<include refid="Base_Column_List"/>
from log_user_login
<where>
is_deleted = 0
<if test="dto.username != null and dto.username != ''">
and username like CONCAT('%',#{dto.username},'%')
</if>

View File

@ -34,6 +34,7 @@
user.*,user_dept.dept_id
from sys_user user left join sys_user_dept user_dept on user.id = user_dept.user_id
<where>
user.is_deleted = 0
<if test="dto.username != null and dto.username != ''">
and username like CONCAT('%',#{dto.username},'%')
</if>
@ -62,7 +63,7 @@
</foreach>
</if>
</where>
order by update_time desc
</select>
<!-- 查询用户 -->