diff --git a/springboot/fastbee-admin/src/main/java/com/fastbee/web/controller/monitor/CacheController.java b/springboot/fastbee-admin/src/main/java/com/fastbee/web/controller/monitor/CacheController.java index fe38cdd0..5e85e4af 100644 --- a/springboot/fastbee-admin/src/main/java/com/fastbee/web/controller/monitor/CacheController.java +++ b/springboot/fastbee-admin/src/main/java/com/fastbee/web/controller/monitor/CacheController.java @@ -7,6 +7,7 @@ import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; +import java.util.TreeSet; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @@ -26,7 +27,7 @@ import com.fastbee.system.domain.SysCache; /** * 缓存监控 - * + * * @author ruoyi */ @Api(tags = "缓存监控") @@ -87,7 +88,7 @@ public class CacheController public AjaxResult getCacheKeys(@PathVariable String cacheName) { Set cacheKeys = redisTemplate.keys(cacheName + "*"); - return AjaxResult.success(cacheKeys); + return AjaxResult.success(new TreeSet<>(cacheKeys)); } @ApiOperation("缓存内容") diff --git a/springboot/fastbee-admin/src/main/java/com/fastbee/web/controller/monitor/SysUserOnlineController.java b/springboot/fastbee-admin/src/main/java/com/fastbee/web/controller/monitor/SysUserOnlineController.java index 68d132d6..23a56ac1 100644 --- a/springboot/fastbee-admin/src/main/java/com/fastbee/web/controller/monitor/SysUserOnlineController.java +++ b/springboot/fastbee-admin/src/main/java/com/fastbee/web/controller/monitor/SysUserOnlineController.java @@ -28,7 +28,7 @@ import com.fastbee.system.service.ISysUserOnlineService; /** * 在线用户监控 - * + * * @author ruoyi */ @Api(tags = "在线用户监控") @@ -54,24 +54,15 @@ public class SysUserOnlineController extends BaseController LoginUser user = redisCache.getCacheObject(key); if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName)) { - if (StringUtils.equals(ipaddr, user.getIpaddr()) && StringUtils.equals(userName, user.getUsername())) - { - userOnlineList.add(userOnlineService.selectOnlineByInfo(ipaddr, userName, user)); - } + userOnlineList.add(userOnlineService.selectOnlineByInfo(ipaddr, userName, user)); } else if (StringUtils.isNotEmpty(ipaddr)) { - if (StringUtils.equals(ipaddr, user.getIpaddr())) - { - userOnlineList.add(userOnlineService.selectOnlineByIpaddr(ipaddr, user)); - } + userOnlineList.add(userOnlineService.selectOnlineByIpaddr(ipaddr, user)); } else if (StringUtils.isNotEmpty(userName) && StringUtils.isNotNull(user.getUser())) { - if (StringUtils.equals(userName, user.getUsername())) - { - userOnlineList.add(userOnlineService.selectOnlineByUserName(userName, user)); - } + userOnlineList.add(userOnlineService.selectOnlineByUserName(userName, user)); } else { diff --git a/springboot/fastbee-admin/src/main/java/com/fastbee/web/controller/system/SysConfigController.java b/springboot/fastbee-admin/src/main/java/com/fastbee/web/controller/system/SysConfigController.java index d6584b31..7b48f986 100644 --- a/springboot/fastbee-admin/src/main/java/com/fastbee/web/controller/system/SysConfigController.java +++ b/springboot/fastbee-admin/src/main/java/com/fastbee/web/controller/system/SysConfigController.java @@ -93,7 +93,7 @@ public class SysConfigController extends BaseController @PostMapping public AjaxResult add(@Validated @RequestBody SysConfig config) { - if (configService.checkConfigKeyUnique(config)) + if (!configService.checkConfigKeyUnique(config)) { return error("新增参数'" + config.getConfigName() + "'失败,参数键名已存在"); } @@ -110,7 +110,7 @@ public class SysConfigController extends BaseController @PutMapping public AjaxResult edit(@Validated @RequestBody SysConfig config) { - if (configService.checkConfigKeyUnique(config)) + if (!configService.checkConfigKeyUnique(config)) { return error("修改参数'" + config.getConfigName() + "'失败,参数键名已存在"); } diff --git a/springboot/fastbee-admin/src/main/java/com/fastbee/web/controller/system/SysDeptController.java b/springboot/fastbee-admin/src/main/java/com/fastbee/web/controller/system/SysDeptController.java index 4c610555..8dbf3ac7 100644 --- a/springboot/fastbee-admin/src/main/java/com/fastbee/web/controller/system/SysDeptController.java +++ b/springboot/fastbee-admin/src/main/java/com/fastbee/web/controller/system/SysDeptController.java @@ -84,7 +84,7 @@ public class SysDeptController extends BaseController @PostMapping public AjaxResult add(@Validated @RequestBody SysDept dept) { - if (deptService.checkDeptNameUnique(dept)) + if (!deptService.checkDeptNameUnique(dept)) { return error("新增部门'" + dept.getDeptName() + "'失败,部门名称已存在"); } @@ -103,7 +103,7 @@ public class SysDeptController extends BaseController { Long deptId = dept.getDeptId(); deptService.checkDeptDataScope(deptId); - if (deptService.checkDeptNameUnique(dept)) + if (!deptService.checkDeptNameUnique(dept)) { return error("修改部门'" + dept.getDeptName() + "'失败,部门名称已存在"); } diff --git a/springboot/fastbee-admin/src/main/java/com/fastbee/web/controller/system/SysDictTypeController.java b/springboot/fastbee-admin/src/main/java/com/fastbee/web/controller/system/SysDictTypeController.java index 5bc0309c..40bac930 100644 --- a/springboot/fastbee-admin/src/main/java/com/fastbee/web/controller/system/SysDictTypeController.java +++ b/springboot/fastbee-admin/src/main/java/com/fastbee/web/controller/system/SysDictTypeController.java @@ -80,7 +80,7 @@ public class SysDictTypeController extends BaseController @PostMapping public AjaxResult add(@Validated @RequestBody SysDictType dict) { - if (dictTypeService.checkDictTypeUnique(dict)) + if (!dictTypeService.checkDictTypeUnique(dict)) { return error("新增字典'" + dict.getDictName() + "'失败,字典类型已存在"); } @@ -97,7 +97,7 @@ public class SysDictTypeController extends BaseController @PutMapping public AjaxResult edit(@Validated @RequestBody SysDictType dict) { - if (dictTypeService.checkDictTypeUnique(dict)) + if (!dictTypeService.checkDictTypeUnique(dict)) { return error("修改字典'" + dict.getDictName() + "'失败,字典类型已存在"); } diff --git a/springboot/fastbee-admin/src/main/java/com/fastbee/web/controller/system/SysMenuController.java b/springboot/fastbee-admin/src/main/java/com/fastbee/web/controller/system/SysMenuController.java index 6ae981a6..ff557654 100644 --- a/springboot/fastbee-admin/src/main/java/com/fastbee/web/controller/system/SysMenuController.java +++ b/springboot/fastbee-admin/src/main/java/com/fastbee/web/controller/system/SysMenuController.java @@ -94,7 +94,7 @@ public class SysMenuController extends BaseController @PostMapping public AjaxResult add(@Validated @RequestBody SysMenu menu) { - if (menuService.checkMenuNameUnique(menu)) + if (!menuService.checkMenuNameUnique(menu)) { return error("新增菜单'" + menu.getMenuName() + "'失败,菜单名称已存在"); } @@ -115,7 +115,7 @@ public class SysMenuController extends BaseController @PutMapping public AjaxResult edit(@Validated @RequestBody SysMenu menu) { - if (menuService.checkMenuNameUnique(menu)) + if (!menuService.checkMenuNameUnique(menu)) { return error("修改菜单'" + menu.getMenuName() + "'失败,菜单名称已存在"); } diff --git a/springboot/fastbee-admin/src/main/java/com/fastbee/web/controller/system/SysPostController.java b/springboot/fastbee-admin/src/main/java/com/fastbee/web/controller/system/SysPostController.java index 068c3c94..77d87b7b 100644 --- a/springboot/fastbee-admin/src/main/java/com/fastbee/web/controller/system/SysPostController.java +++ b/springboot/fastbee-admin/src/main/java/com/fastbee/web/controller/system/SysPostController.java @@ -83,11 +83,11 @@ public class SysPostController extends BaseController @PostMapping public AjaxResult add(@Validated @RequestBody SysPost post) { - if (postService.checkPostNameUnique(post)) + if (!postService.checkPostNameUnique(post)) { return error("新增岗位'" + post.getPostName() + "'失败,岗位名称已存在"); } - else if (postService.checkPostCodeUnique(post)) + else if (!postService.checkPostCodeUnique(post)) { return error("新增岗位'" + post.getPostName() + "'失败,岗位编码已存在"); } @@ -104,11 +104,11 @@ public class SysPostController extends BaseController @PutMapping public AjaxResult edit(@Validated @RequestBody SysPost post) { - if (postService.checkPostNameUnique(post)) + if (!postService.checkPostNameUnique(post)) { return error("修改岗位'" + post.getPostName() + "'失败,岗位名称已存在"); } - else if (postService.checkPostCodeUnique(post)) + else if (!postService.checkPostCodeUnique(post)) { return error("修改岗位'" + post.getPostName() + "'失败,岗位编码已存在"); } diff --git a/springboot/fastbee-admin/src/main/java/com/fastbee/web/controller/system/SysProfileController.java b/springboot/fastbee-admin/src/main/java/com/fastbee/web/controller/system/SysProfileController.java index 700e3c29..a6a735ae 100644 --- a/springboot/fastbee-admin/src/main/java/com/fastbee/web/controller/system/SysProfileController.java +++ b/springboot/fastbee-admin/src/main/java/com/fastbee/web/controller/system/SysProfileController.java @@ -30,6 +30,7 @@ import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import java.util.List; +import java.util.Map; /** * 个人信息 业务处理 @@ -78,29 +79,22 @@ public class SysProfileController extends BaseController public AjaxResult updateProfile(@RequestBody SysUser user) { LoginUser loginUser = getLoginUser(); - SysUser sysUser = loginUser.getUser(); - user.setUserName(sysUser.getUserName()); - if (StringUtils.isNotEmpty(user.getPhonenumber()) - && userService.checkPhoneUnique(user)) + SysUser currentUser = loginUser.getUser(); + currentUser.setNickName(user.getNickName()); + currentUser.setEmail(user.getEmail()); + currentUser.setPhonenumber(user.getPhonenumber()); + currentUser.setSex(user.getSex()); + if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(currentUser)) { return error("修改用户'" + user.getUserName() + "'失败,手机号码已存在"); } - if (StringUtils.isNotEmpty(user.getEmail()) - && userService.checkEmailUnique(user)) + if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(currentUser)) { - return error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在"); + return error("修改用户'" + loginUser.getUsername() + "'失败,邮箱账号已存在"); } - user.setUserId(sysUser.getUserId()); - user.setPassword(null); - user.setAvatar(null); - user.setDeptId(null); - if (userService.updateUserProfile(user) > 0) + if (userService.updateUserProfile(currentUser) > 0) { // 更新缓存用户信息 - sysUser.setNickName(user.getNickName()); - sysUser.setPhonenumber(user.getPhonenumber()); - sysUser.setEmail(user.getEmail()); - sysUser.setSex(user.getSex()); tokenService.setLoginUser(loginUser); return success(); } @@ -113,8 +107,10 @@ public class SysProfileController extends BaseController @ApiOperation("重置密码") @Log(title = "个人信息", businessType = BusinessType.UPDATE) @PutMapping("/updatePwd") - public AjaxResult updatePwd(String oldPassword, String newPassword) + public AjaxResult updatePwd(@RequestBody Map params) { + String oldPassword = params.get("oldPassword"); + String newPassword = params.get("newPassword"); LoginUser loginUser = getLoginUser(); String userName = loginUser.getUsername(); String password = loginUser.getPassword(); @@ -126,10 +122,11 @@ public class SysProfileController extends BaseController { return error("新密码不能与旧密码相同"); } - if (userService.resetUserPwd(userName, SecurityUtils.encryptPassword(newPassword)) > 0) + newPassword = SecurityUtils.encryptPassword(newPassword); + if (userService.resetUserPwd(userName, newPassword) > 0) { // 更新缓存用户密码 - loginUser.getUser().setPassword(SecurityUtils.encryptPassword(newPassword)); + loginUser.getUser().setPassword(newPassword); tokenService.setLoginUser(loginUser); return success(); } diff --git a/springboot/fastbee-admin/src/main/java/com/fastbee/web/controller/system/SysRoleController.java b/springboot/fastbee-admin/src/main/java/com/fastbee/web/controller/system/SysRoleController.java index 7edc24ce..19656800 100644 --- a/springboot/fastbee-admin/src/main/java/com/fastbee/web/controller/system/SysRoleController.java +++ b/springboot/fastbee-admin/src/main/java/com/fastbee/web/controller/system/SysRoleController.java @@ -102,11 +102,11 @@ public class SysRoleController extends BaseController @PostMapping public AjaxResult add(@Validated @RequestBody SysRole role) { - if (roleService.checkRoleNameUnique(role)) + if (!roleService.checkRoleNameUnique(role)) { return error("新增角色'" + role.getRoleName() + "'失败,角色名称已存在"); } - else if (roleService.checkRoleKeyUnique(role)) + else if (!roleService.checkRoleKeyUnique(role)) { return error("新增角色'" + role.getRoleName() + "'失败,角色权限已存在"); } @@ -126,11 +126,11 @@ public class SysRoleController extends BaseController { roleService.checkRoleAllowed(role); roleService.checkRoleDataScope(role.getRoleId()); - if (roleService.checkRoleNameUnique(role)) + if (!roleService.checkRoleNameUnique(role)) { return error("修改角色'" + role.getRoleName() + "'失败,角色名称已存在"); } - else if (roleService.checkRoleKeyUnique(role)) + else if (!roleService.checkRoleKeyUnique(role)) { return error("修改角色'" + role.getRoleName() + "'失败,角色权限已存在"); } @@ -142,8 +142,8 @@ public class SysRoleController extends BaseController LoginUser loginUser = getLoginUser(); if (StringUtils.isNotNull(loginUser.getUser()) && !loginUser.getUser().isAdmin()) { - loginUser.setPermissions(permissionService.getMenuPermission(loginUser.getUser())); loginUser.setUser(userService.selectUserByUserName(loginUser.getUser().getUserName())); + loginUser.setPermissions(permissionService.getMenuPermission(loginUser.getUser())); tokenService.setLoginUser(loginUser); } return success(); diff --git a/springboot/fastbee-admin/src/main/resources/i18n/messages.properties b/springboot/fastbee-admin/src/main/resources/i18n/messages.properties index 4098fc92..81e3735b 100644 --- a/springboot/fastbee-admin/src/main/resources/i18n/messages.properties +++ b/springboot/fastbee-admin/src/main/resources/i18n/messages.properties @@ -9,13 +9,14 @@ user.password.retry.limit.exceed=密码输入错误{0}次,帐户锁定{1}分 user.password.delete=对不起,您的账号已被删除 user.blocked=用户已封禁,请联系管理员 role.blocked=角色已封禁,请联系管理员 +login.blocked=很遗憾,访问IP已被列入系统黑名单 user.logout.success=退出成功 length.not.valid=长度必须在{min}到{max}个字符之间 user.username.not.valid=* 2到20个汉字、字母、数字或下划线组成,且必须以非数字开头 user.password.not.valid=* 5-50个字符 - + user.email.not.valid=邮箱格式错误 user.mobile.phone.number.not.valid=手机号格式错误 user.login.success=登录成功 diff --git a/springboot/fastbee-common/src/main/java/com/fastbee/common/annotation/Sensitive.java b/springboot/fastbee-common/src/main/java/com/fastbee/common/annotation/Sensitive.java new file mode 100644 index 00000000..6f1847ef --- /dev/null +++ b/springboot/fastbee-common/src/main/java/com/fastbee/common/annotation/Sensitive.java @@ -0,0 +1,24 @@ +package com.fastbee.common.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fastbee.common.config.serializer.SensitiveJsonSerializer; +import com.fastbee.common.enums.DesensitizedType; + +/** + * 数据脱敏注解 + * + * @author ruoyi + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +@JacksonAnnotationsInside +@JsonSerialize(using = SensitiveJsonSerializer.class) +public @interface Sensitive +{ + DesensitizedType desensitizedType(); +} diff --git a/springboot/fastbee-common/src/main/java/com/fastbee/common/config/serializer/SensitiveJsonSerializer.java b/springboot/fastbee-common/src/main/java/com/fastbee/common/config/serializer/SensitiveJsonSerializer.java new file mode 100644 index 00000000..add6efe4 --- /dev/null +++ b/springboot/fastbee-common/src/main/java/com/fastbee/common/config/serializer/SensitiveJsonSerializer.java @@ -0,0 +1,67 @@ +package com.fastbee.common.config.serializer; + +import java.io.IOException; +import java.util.Objects; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.BeanProperty; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.ContextualSerializer; +import com.fastbee.common.annotation.Sensitive; +import com.fastbee.common.core.domain.model.LoginUser; +import com.fastbee.common.enums.DesensitizedType; +import com.fastbee.common.utils.SecurityUtils; + +/** + * 数据脱敏序列化过滤 + * + * @author ruoyi + */ +public class SensitiveJsonSerializer extends JsonSerializer implements ContextualSerializer +{ + private DesensitizedType desensitizedType; + + @Override + public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException + { + if (desensitization()) + { + gen.writeString(desensitizedType.desensitizer().apply(value)); + } + else + { + gen.writeString(value); + } + } + + @Override + public JsonSerializer createContextual(SerializerProvider prov, BeanProperty property) + throws JsonMappingException + { + Sensitive annotation = property.getAnnotation(Sensitive.class); + if (Objects.nonNull(annotation) && Objects.equals(String.class, property.getType().getRawClass())) + { + this.desensitizedType = annotation.desensitizedType(); + return this; + } + return prov.findValueSerializer(property.getType(), property); + } + + /** + * 是否需要脱敏处理 + */ + private boolean desensitization() + { + try + { + LoginUser securityUser = SecurityUtils.getLoginUser(); + // 管理员不脱敏 + return !securityUser.getUser().isAdmin(); + } + catch (Exception e) + { + return true; + } + } +} diff --git a/springboot/fastbee-common/src/main/java/com/fastbee/common/constant/UserConstants.java b/springboot/fastbee-common/src/main/java/com/fastbee/common/constant/UserConstants.java index ee1193e4..44d54582 100644 --- a/springboot/fastbee-common/src/main/java/com/fastbee/common/constant/UserConstants.java +++ b/springboot/fastbee-common/src/main/java/com/fastbee/common/constant/UserConstants.java @@ -21,6 +21,9 @@ public class UserConstants /** 用户封禁状态 */ public static final String USER_DISABLE = "1"; + /** 角色正常状态 */ + public static final String ROLE_NORMAL = "0"; + /** 角色封禁状态 */ public static final String ROLE_DISABLE = "1"; diff --git a/springboot/fastbee-common/src/main/java/com/fastbee/common/core/domain/AjaxResult.java b/springboot/fastbee-common/src/main/java/com/fastbee/common/core/domain/AjaxResult.java index 9db8ee4e..697fab72 100644 --- a/springboot/fastbee-common/src/main/java/com/fastbee/common/core/domain/AjaxResult.java +++ b/springboot/fastbee-common/src/main/java/com/fastbee/common/core/domain/AjaxResult.java @@ -1,12 +1,13 @@ package com.fastbee.common.core.domain; import java.util.HashMap; +import java.util.Objects; import com.fastbee.common.constant.HttpStatus; import com.fastbee.common.utils.StringUtils; /** * 操作消息提醒 - * + * * @author ruoyi */ public class AjaxResult extends HashMap @@ -31,7 +32,7 @@ public class AjaxResult extends HashMap /** * 初始化一个新创建的 AjaxResult 对象 - * + * * @param code 状态码 * @param msg 返回内容 */ @@ -43,7 +44,7 @@ public class AjaxResult extends HashMap /** * 初始化一个新创建的 AjaxResult 对象 - * + * * @param code 状态码 * @param msg 返回内容 * @param data 数据对象 @@ -79,7 +80,7 @@ public class AjaxResult extends HashMap /** * 返回成功消息 - * + * * @return 成功消息 */ public static AjaxResult success() @@ -89,7 +90,7 @@ public class AjaxResult extends HashMap /** * 返回成功数据 - * + * * @return 成功消息 */ public static AjaxResult success(Object data) @@ -109,7 +110,7 @@ public class AjaxResult extends HashMap /** * 返回成功消息 - * + * * @param msg 返回内容 * @return 成功消息 */ @@ -120,7 +121,7 @@ public class AjaxResult extends HashMap /** * 返回成功消息 - * + * * @param msg 返回内容 * @param data 数据对象 * @return 成功消息 @@ -155,7 +156,7 @@ public class AjaxResult extends HashMap /** * 返回错误消息 - * + * * @return 错误消息 */ public static AjaxResult error() @@ -165,7 +166,7 @@ public class AjaxResult extends HashMap /** * 返回错误消息 - * + * * @param msg 返回内容 * @return 错误消息 */ @@ -176,7 +177,7 @@ public class AjaxResult extends HashMap /** * 返回错误消息 - * + * * @param msg 返回内容 * @param data 数据对象 * @return 错误消息 @@ -188,7 +189,7 @@ public class AjaxResult extends HashMap /** * 返回错误消息 - * + * * @param code 状态码 * @param msg 返回内容 * @return 错误消息 @@ -198,6 +199,36 @@ public class AjaxResult extends HashMap return new AjaxResult(code, msg, null); } + /** + * 是否为成功消息 + * + * @return 结果 + */ + public boolean isSuccess() + { + return Objects.equals(HttpStatus.SUCCESS, this.get(CODE_TAG)); + } + + /** + * 是否为警告消息 + * + * @return 结果 + */ + public boolean isWarn() + { + return Objects.equals(HttpStatus.WARN, this.get(CODE_TAG)); + } + + /** + * 是否为错误消息 + * + * @return 结果 + */ + public boolean isError() + { + return Objects.equals(HttpStatus.ERROR, this.get(CODE_TAG)); + } + /** * 方便链式调用 * diff --git a/springboot/fastbee-common/src/main/java/com/fastbee/common/core/domain/entity/SysMenu.java b/springboot/fastbee-common/src/main/java/com/fastbee/common/core/domain/entity/SysMenu.java index feee0421..92a73065 100644 --- a/springboot/fastbee-common/src/main/java/com/fastbee/common/core/domain/entity/SysMenu.java +++ b/springboot/fastbee-common/src/main/java/com/fastbee/common/core/domain/entity/SysMenu.java @@ -14,7 +14,7 @@ import com.fastbee.common.core.domain.BaseEntity; /** * 菜单权限表 sys_menu - * + * * @author ruoyi */ @ApiModel(value = "SysMenu", description = "菜单权限表 sys_menu") @@ -54,6 +54,9 @@ public class SysMenu extends BaseEntity @ApiModelProperty("路由参数") private String query; + /** 路由名称,默认和路由地址相同的驼峰格式(注意:因为vue3版本的router会删除名称相同路由,为避免名字的冲突,特殊情况可以自定义) */ + private String routeName; + /** 是否为外链(0是 1否) */ @ApiModelProperty("是否为外链(0是 1否)") private String isFrame; @@ -69,7 +72,7 @@ public class SysMenu extends BaseEntity /** 显示状态(0显示 1隐藏) */ @ApiModelProperty("显示状态(0显示 1隐藏)") private String visible; - + /** 菜单状态(0正常 1停用) */ @ApiModelProperty("菜单状态(0正常 1停用)") private String status; @@ -171,6 +174,16 @@ public class SysMenu extends BaseEntity this.query = query; } + public String getRouteName() + { + return routeName; + } + + public void setRouteName(String routeName) + { + this.routeName = routeName; + } + public String getIsFrame() { return isFrame; @@ -252,7 +265,7 @@ public class SysMenu extends BaseEntity { this.children = children; } - + @Override public String toString() { return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) @@ -262,6 +275,8 @@ public class SysMenu extends BaseEntity .append("orderNum", getOrderNum()) .append("path", getPath()) .append("component", getComponent()) + .append("query", getQuery()) + .append("routeName", getRouteName()) .append("isFrame", getIsFrame()) .append("IsCache", getIsCache()) .append("menuType", getMenuType()) diff --git a/springboot/fastbee-common/src/main/java/com/fastbee/common/core/domain/entity/SysUser.java b/springboot/fastbee-common/src/main/java/com/fastbee/common/core/domain/entity/SysUser.java index 6ccbf8e1..bff8749a 100644 --- a/springboot/fastbee-common/src/main/java/com/fastbee/common/core/domain/entity/SysUser.java +++ b/springboot/fastbee-common/src/main/java/com/fastbee/common/core/domain/entity/SysUser.java @@ -17,7 +17,7 @@ import com.fastbee.common.xss.Xss; /** * 用户对象 sys_user - * + * * @author ruoyi */ @ApiModel(value = "SysUser", description = "用户对象 sys_user") @@ -27,7 +27,7 @@ public class SysUser extends BaseEntity /** 用户ID */ @ApiModelProperty("用户ID") - @Excel(name = "用户序号", cellType = ColumnType.NUMERIC, prompt = "用户编号") + @Excel(name = "用户序号", type = Type.EXPORT, cellType = ColumnType.NUMERIC, prompt = "用户编号") private Long userId; /** 部门ID */ @@ -52,7 +52,7 @@ public class SysUser extends BaseEntity /** 手机号码 */ @ApiModelProperty("手机号码") - @Excel(name = "手机号码") + @Excel(name = "手机号码", cellType = ColumnType.TEXT) private String phonenumber; /** 用户性别 */ diff --git a/springboot/fastbee-common/src/main/java/com/fastbee/common/core/domain/model/LoginUser.java b/springboot/fastbee-common/src/main/java/com/fastbee/common/core/domain/model/LoginUser.java index a461282c..4b443930 100644 --- a/springboot/fastbee-common/src/main/java/com/fastbee/common/core/domain/model/LoginUser.java +++ b/springboot/fastbee-common/src/main/java/com/fastbee/common/core/domain/model/LoginUser.java @@ -13,8 +13,7 @@ import java.util.Set; * * @author ruoyi */ -public class LoginUser implements UserDetails -{ +public class LoginUser implements UserDetails { private static final long serialVersionUID = 1L; /** @@ -81,6 +80,29 @@ public class LoginUser implements UserDetails private Boolean neverExpire = Boolean.FALSE; + public LoginUser() { + } + + public LoginUser(SysUser user, Set permissions) { + this.user = user; + this.permissions = permissions; + } + + public LoginUser(Long userId, Long deptId, SysUser user, Set permissions) { + this.userId = userId; + this.deptId = deptId; + this.user = user; + this.permissions = permissions; + } + + public LoginUser(Long userId, Long deptId, String language, SysUser user, Set permissions) { + this.userId = userId; + this.deptId = deptId; + this.user = user; + this.language = language; + this.permissions = permissions; + } + public Boolean getNeverExpire() { return neverExpire; } @@ -105,33 +127,27 @@ public class LoginUser implements UserDetails this.language = language; } - public Long getUserId() - { + public Long getUserId() { return userId; } - public void setUserId(Long userId) - { + public void setUserId(Long userId) { this.userId = userId; } - public Long getDeptId() - { + public Long getDeptId() { return deptId; } - public void setDeptId(Long deptId) - { + public void setDeptId(Long deptId) { this.deptId = deptId; } - public String getToken() - { + public String getToken() { return token; } - public void setToken(String token) - { + public void setToken(String token) { this.token = token; } @@ -143,43 +159,15 @@ public class LoginUser implements UserDetails this.requestToken = requestToken; } - public LoginUser() - { - } - - public LoginUser(SysUser user, Set permissions) - { - this.user = user; - this.permissions = permissions; - } - - public LoginUser(Long userId, Long deptId, SysUser user, Set permissions) - { - this.userId = userId; - this.deptId = deptId; - this.user = user; - this.permissions = permissions; - } - - public LoginUser(Long userId, Long deptId, String language, SysUser user, Set permissions) - { - this.userId = userId; - this.deptId = deptId; - this.user = user; - this.language = language; - this.permissions = permissions; - } @JSONField(serialize = false) @Override - public String getPassword() - { + public String getPassword() { return user.getPassword(); } @Override - public String getUsername() - { + public String getUsername() { return user.getUserName(); } @@ -188,8 +176,7 @@ public class LoginUser implements UserDetails */ @JSONField(serialize = false) @Override - public boolean isAccountNonExpired() - { + public boolean isAccountNonExpired() { return true; } @@ -200,8 +187,7 @@ public class LoginUser implements UserDetails */ @JSONField(serialize = false) @Override - public boolean isAccountNonLocked() - { + public boolean isAccountNonLocked() { return true; } @@ -212,8 +198,7 @@ public class LoginUser implements UserDetails */ @JSONField(serialize = false) @Override - public boolean isCredentialsNonExpired() - { + public boolean isCredentialsNonExpired() { return true; } @@ -224,94 +209,76 @@ public class LoginUser implements UserDetails */ @JSONField(serialize = false) @Override - public boolean isEnabled() - { + public boolean isEnabled() { return true; } - public Long getLoginTime() - { + public Long getLoginTime() { return loginTime; } - public void setLoginTime(Long loginTime) - { + public void setLoginTime(Long loginTime) { this.loginTime = loginTime; } - public String getIpaddr() - { + public String getIpaddr() { return ipaddr; } - public void setIpaddr(String ipaddr) - { + public void setIpaddr(String ipaddr) { this.ipaddr = ipaddr; } - public String getLoginLocation() - { + public String getLoginLocation() { return loginLocation; } - public void setLoginLocation(String loginLocation) - { + public void setLoginLocation(String loginLocation) { this.loginLocation = loginLocation; } - public String getBrowser() - { + public String getBrowser() { return browser; } - public void setBrowser(String browser) - { + public void setBrowser(String browser) { this.browser = browser; } - public String getOs() - { + public String getOs() { return os; } - public void setOs(String os) - { + public void setOs(String os) { this.os = os; } - public Long getExpireTime() - { + public Long getExpireTime() { return expireTime; } - public void setExpireTime(Long expireTime) - { + public void setExpireTime(Long expireTime) { this.expireTime = expireTime; } - public Set getPermissions() - { + public Set getPermissions() { return permissions; } - public void setPermissions(Set permissions) - { + public void setPermissions(Set permissions) { this.permissions = permissions; } - public SysUser getUser() - { + public SysUser getUser() { return user; } - public void setUser(SysUser user) - { + public void setUser(SysUser user) { this.user = user; } @Override - public Collection getAuthorities() - { + public Collection getAuthorities() { return null; } } diff --git a/springboot/fastbee-common/src/main/java/com/fastbee/common/exception/file/FileUploadException.java b/springboot/fastbee-common/src/main/java/com/fastbee/common/exception/file/FileUploadException.java new file mode 100644 index 00000000..128de846 --- /dev/null +++ b/springboot/fastbee-common/src/main/java/com/fastbee/common/exception/file/FileUploadException.java @@ -0,0 +1,61 @@ +package com.fastbee.common.exception.file; + +import java.io.PrintStream; +import java.io.PrintWriter; + +/** + * 文件上传异常类 + * + * @author ruoyi + */ +public class FileUploadException extends Exception +{ + + private static final long serialVersionUID = 1L; + + private final Throwable cause; + + public FileUploadException() + { + this(null, null); + } + + public FileUploadException(final String msg) + { + this(msg, null); + } + + public FileUploadException(String msg, Throwable cause) + { + super(msg); + this.cause = cause; + } + + @Override + public void printStackTrace(PrintStream stream) + { + super.printStackTrace(stream); + if (cause != null) + { + stream.println("Caused by:"); + cause.printStackTrace(stream); + } + } + + @Override + public void printStackTrace(PrintWriter writer) + { + super.printStackTrace(writer); + if (cause != null) + { + writer.println("Caused by:"); + cause.printStackTrace(writer); + } + } + + @Override + public Throwable getCause() + { + return cause; + } +} diff --git a/springboot/fastbee-common/src/main/java/com/fastbee/common/exception/user/BlackListException.java b/springboot/fastbee-common/src/main/java/com/fastbee/common/exception/user/BlackListException.java new file mode 100644 index 00000000..942c5a4e --- /dev/null +++ b/springboot/fastbee-common/src/main/java/com/fastbee/common/exception/user/BlackListException.java @@ -0,0 +1,16 @@ +package com.fastbee.common.exception.user; + +/** + * 黑名单IP异常类 + * + * @author ruoyi + */ +public class BlackListException extends UserException +{ + private static final long serialVersionUID = 1L; + + public BlackListException() + { + super("login.blocked", null); + } +} diff --git a/springboot/fastbee-common/src/main/java/com/fastbee/common/exception/user/UserNotExistsException.java b/springboot/fastbee-common/src/main/java/com/fastbee/common/exception/user/UserNotExistsException.java new file mode 100644 index 00000000..fe925ae6 --- /dev/null +++ b/springboot/fastbee-common/src/main/java/com/fastbee/common/exception/user/UserNotExistsException.java @@ -0,0 +1,16 @@ +package com.fastbee.common.exception.user; + +/** + * 用户不存在异常类 + * + * @author ruoyi + */ +public class UserNotExistsException extends UserException +{ + private static final long serialVersionUID = 1L; + + public UserNotExistsException() + { + super("user.not.exists", null); + } +} diff --git a/springboot/fastbee-common/src/main/java/com/fastbee/common/filter/XssFilter.java b/springboot/fastbee-common/src/main/java/com/fastbee/common/filter/XssFilter.java index e5ec9238..c8484ba9 100644 --- a/springboot/fastbee-common/src/main/java/com/fastbee/common/filter/XssFilter.java +++ b/springboot/fastbee-common/src/main/java/com/fastbee/common/filter/XssFilter.java @@ -16,7 +16,7 @@ import com.fastbee.common.enums.HttpMethod; /** * 防止XSS攻击的过滤器 - * + * * @author ruoyi */ public class XssFilter implements Filter @@ -32,10 +32,10 @@ public class XssFilter implements Filter String tempExcludes = filterConfig.getInitParameter("excludes"); if (StringUtils.isNotEmpty(tempExcludes)) { - String[] url = tempExcludes.split(","); - for (int i = 0; url != null && i < url.length; i++) + String[] urls = tempExcludes.split(","); + for (String url : urls) { - excludes.add(url[i]); + excludes.add(url); } } } @@ -72,4 +72,4 @@ public class XssFilter implements Filter { } -} \ No newline at end of file +} diff --git a/springboot/fastbee-common/src/main/java/com/fastbee/common/utils/Arith.java b/springboot/fastbee-common/src/main/java/com/fastbee/common/utils/Arith.java index bea66b58..de9c3ae8 100644 --- a/springboot/fastbee-common/src/main/java/com/fastbee/common/utils/Arith.java +++ b/springboot/fastbee-common/src/main/java/com/fastbee/common/utils/Arith.java @@ -5,7 +5,7 @@ import java.math.RoundingMode; /** * 精确的浮点数运算 - * + * * @author ruoyi */ public class Arith @@ -108,7 +108,6 @@ public class Arith "The scale must be a positive integer or zero"); } BigDecimal b = new BigDecimal(Double.toString(v)); - BigDecimal one = BigDecimal.ONE; - return b.divide(one, scale, RoundingMode.HALF_UP).doubleValue(); + return b.divide(BigDecimal.ONE, scale, RoundingMode.HALF_UP).doubleValue(); } } diff --git a/springboot/fastbee-common/src/main/java/com/fastbee/common/utils/StringUtils.java b/springboot/fastbee-common/src/main/java/com/fastbee/common/utils/StringUtils.java index 8c0c39a4..ec5a2f46 100644 --- a/springboot/fastbee-common/src/main/java/com/fastbee/common/utils/StringUtils.java +++ b/springboot/fastbee-common/src/main/java/com/fastbee/common/utils/StringUtils.java @@ -379,6 +379,18 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils return new HashSet(str2List(str, sep, true, false)); } + /** + * 字符串转list + * + * @param str 字符串 + * @param sep 分隔符 + * @return list集合 + */ + public static final List str2List(String str, String sep) + { + return str2List(str, sep, true, false); + } + /** * 字符串转list * diff --git a/springboot/fastbee-common/src/main/java/com/fastbee/common/utils/http/HttpUtils.java b/springboot/fastbee-common/src/main/java/com/fastbee/common/utils/http/HttpUtils.java index bc348841..a2bfe046 100644 --- a/springboot/fastbee-common/src/main/java/com/fastbee/common/utils/http/HttpUtils.java +++ b/springboot/fastbee-common/src/main/java/com/fastbee/common/utils/http/HttpUtils.java @@ -21,6 +21,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.fastbee.common.constant.Constants; import com.fastbee.common.utils.StringUtils; +import org.springframework.http.MediaType; /** * 通用http发送方法 @@ -74,7 +75,7 @@ public class HttpUtils URLConnection connection = realUrl.openConnection(); connection.setRequestProperty("accept", "*/*"); connection.setRequestProperty("connection", "Keep-Alive"); - connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); + connection.setRequestProperty("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"); connection.connect(); in = new BufferedReader(new InputStreamReader(connection.getInputStream(), contentType)); String line; @@ -121,10 +122,23 @@ public class HttpUtils * 向指定 URL 发送POST方法的请求 * * @param url 发送请求的 URL - * @param param 请求参数,请求参数应该是 JSON String格式 的形式。 + * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 * @return 所代表远程资源的响应结果 */ public static String sendPost(String url, String param) + { + return sendPost(url, param, MediaType.APPLICATION_FORM_URLENCODED_VALUE); + } + + /** + * 向指定 URL 发送POST方法的请求 + * + * @param url 发送请求的 URL + * @param param 请求参数 + * @param contentType 内容类型 + * @return 所代表远程资源的响应结果 + */ + public static String sendPost(String url, String param, String contentType) { PrintWriter out = null; BufferedReader in = null; @@ -136,9 +150,9 @@ public class HttpUtils URLConnection conn = realUrl.openConnection(); conn.setRequestProperty("accept", "*/*"); conn.setRequestProperty("connection", "Keep-Alive"); - conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); + conn.setRequestProperty("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"); conn.setRequestProperty("Accept-Charset", "utf-8"); - conn.setRequestProperty("contentType", "utf-8"); + conn.setRequestProperty("Content-Type", contentType); conn.setDoOutput(true); conn.setDoInput(true); out = new PrintWriter(conn.getOutputStream()); @@ -190,6 +204,11 @@ public class HttpUtils } public static String sendSSLPost(String url, String param) + { + return sendSSLPost(url, param, MediaType.APPLICATION_FORM_URLENCODED_VALUE); + } + + public static String sendSSLPost(String url, String param, String contentType) { StringBuilder result = new StringBuilder(); String urlNameString = url + "?" + param; @@ -202,9 +221,9 @@ public class HttpUtils HttpsURLConnection conn = (HttpsURLConnection) console.openConnection(); conn.setRequestProperty("accept", "*/*"); conn.setRequestProperty("connection", "Keep-Alive"); - conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); + conn.setRequestProperty("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"); conn.setRequestProperty("Accept-Charset", "utf-8"); - conn.setRequestProperty("contentType", "utf-8"); + conn.setRequestProperty("Content-Type", contentType); conn.setDoOutput(true); conn.setDoInput(true); diff --git a/springboot/fastbee-common/src/main/java/com/fastbee/common/utils/poi/ExcelUtil.java b/springboot/fastbee-common/src/main/java/com/fastbee/common/utils/poi/ExcelUtil.java index a038da09..b61bc00e 100644 --- a/springboot/fastbee-common/src/main/java/com/fastbee/common/utils/poi/ExcelUtil.java +++ b/springboot/fastbee-common/src/main/java/com/fastbee/common/utils/poi/ExcelUtil.java @@ -51,6 +51,8 @@ public class ExcelUtil { private static final Logger log = LoggerFactory.getLogger(ExcelUtil.class); + public static final String SEPARATOR = ","; + public static final String FORMULA_REGEX_STR = "=|-|\\+|@"; public static final String[] FORMULA_STR = { "=", "-", "+", "@" }; @@ -316,7 +318,7 @@ public class ExcelUtil throw new IOException("文件sheet不存在"); } boolean isXSSFWorkbook = !(wb instanceof HSSFWorkbook); - Map pictures; + Map> pictures = null; if (isXSSFWorkbook) { pictures = getSheetPictures07((XSSFSheet) sheet, (XSSFWorkbook) wb); @@ -460,16 +462,15 @@ public class ExcelUtil } else if (ColumnType.IMAGE == attr.cellType() && StringUtils.isNotEmpty(pictures)) { - PictureData image = pictures.get(row.getRowNum() + "_" + entry.getKey()); - if (image == null) + StringBuilder propertyString = new StringBuilder(); + List images = pictures.get(row.getRowNum() + "_" + entry.getKey()); + for (PictureData picture : images) { - val = ""; - } - else - { - byte[] data = image.getData(); - val = FileUtils.writeImportBytes(data); + byte[] data = picture.getData(); + String fileName = FileUtils.writeImportBytes(data); + propertyString.append(fileName).append(SEPARATOR); } + val = StringUtils.stripEnd(propertyString.toString(), SEPARATOR); } ReflectUtils.invokeSetter(entity, propertyName, val); } @@ -993,12 +994,15 @@ public class ExcelUtil else if (ColumnType.IMAGE == attr.cellType()) { ClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, (short) cell.getColumnIndex(), cell.getRow().getRowNum(), (short) (cell.getColumnIndex() + 1), cell.getRow().getRowNum() + 1); - String imagePath = Convert.toStr(value); - if (StringUtils.isNotEmpty(imagePath)) + String propertyValue = Convert.toStr(value); + if (StringUtils.isNotEmpty(propertyValue)) { - byte[] data = ImageUtils.getImage(imagePath); - getDrawingPatriarch(cell.getSheet()).createPicture(anchor, - cell.getSheet().getWorkbook().addPicture(data, getImageType(data))); + List imagePaths = StringUtils.str2List(propertyValue, SEPARATOR); + for (String imagePath : imagePaths) + { + byte[] data = ImageUtils.getImage(imagePath); + getDrawingPatriarch(cell.getSheet()).createPicture(anchor, cell.getSheet().getWorkbook().addPicture(data, getImageType(data))); + } } } } @@ -1243,7 +1247,7 @@ public class ExcelUtil public static String convertByExp(String propertyValue, String converterExp, String separator) { StringBuilder propertyString = new StringBuilder(); - String[] convertSource = converterExp.split(","); + String[] convertSource = converterExp.split(SEPARATOR); for (String item : convertSource) { String[] itemArray = item.split("="); @@ -1280,7 +1284,7 @@ public class ExcelUtil public static String reverseByExp(String propertyValue, String converterExp, String separator) { StringBuilder propertyString = new StringBuilder(); - String[] convertSource = converterExp.split(","); + String[] convertSource = converterExp.split(SEPARATOR); for (String item : convertSource) { String[] itemArray = item.split("="); @@ -1706,30 +1710,24 @@ public class ExcelUtil * @param workbook 工作簿对象 * @return Map key:图片单元格索引(1_1)String,value:图片流PictureData */ - public static Map getSheetPictures03(HSSFSheet sheet, HSSFWorkbook workbook) + public static Map> getSheetPictures03(HSSFSheet sheet, HSSFWorkbook workbook) { - Map sheetIndexPicMap = new HashMap(); + Map> sheetIndexPicMap = new HashMap<>(); List pictures = workbook.getAllPictures(); - if (!pictures.isEmpty()) + if (!pictures.isEmpty() && sheet.getDrawingPatriarch() != null) { for (HSSFShape shape : sheet.getDrawingPatriarch().getChildren()) { - HSSFClientAnchor anchor = (HSSFClientAnchor) shape.getAnchor(); if (shape instanceof HSSFPicture) { HSSFPicture pic = (HSSFPicture) shape; - int pictureIndex = pic.getPictureIndex() - 1; - HSSFPictureData picData = pictures.get(pictureIndex); + HSSFClientAnchor anchor = (HSSFClientAnchor) pic.getAnchor(); String picIndex = anchor.getRow1() + "_" + anchor.getCol1(); - sheetIndexPicMap.put(picIndex, picData); + sheetIndexPicMap.computeIfAbsent(picIndex, k -> new ArrayList<>()).add(pic.getPictureData()); } } - return sheetIndexPicMap; - } - else - { - return sheetIndexPicMap; } + return sheetIndexPicMap; } /** @@ -1739,16 +1737,15 @@ public class ExcelUtil * @param workbook 工作簿对象 * @return Map key:图片单元格索引(1_1)String,value:图片流PictureData */ - public static Map getSheetPictures07(XSSFSheet sheet, XSSFWorkbook workbook) + public static Map> getSheetPictures07(XSSFSheet sheet, XSSFWorkbook workbook) { - Map sheetIndexPicMap = new HashMap(); + Map> sheetIndexPicMap = new HashMap<>(); for (POIXMLDocumentPart dr : sheet.getRelations()) { if (dr instanceof XSSFDrawing) { XSSFDrawing drawing = (XSSFDrawing) dr; - List shapes = drawing.getShapes(); - for (XSSFShape shape : shapes) + for (XSSFShape shape : drawing.getShapes()) { if (shape instanceof XSSFPicture) { @@ -1756,7 +1753,7 @@ public class ExcelUtil XSSFClientAnchor anchor = pic.getPreferredSize(); CTMarker ctMarker = anchor.getFrom(); String picIndex = ctMarker.getRow() + "_" + ctMarker.getCol(); - sheetIndexPicMap.put(picIndex, pic.getPictureData()); + sheetIndexPicMap.computeIfAbsent(picIndex, k -> new ArrayList<>()).add(pic.getPictureData()); } } } diff --git a/springboot/fastbee-common/src/main/java/com/fastbee/common/utils/spring/SpringUtils.java b/springboot/fastbee-common/src/main/java/com/fastbee/common/utils/spring/SpringUtils.java index 61138aaf..9b3eabda 100644 --- a/springboot/fastbee-common/src/main/java/com/fastbee/common/utils/spring/SpringUtils.java +++ b/springboot/fastbee-common/src/main/java/com/fastbee/common/utils/spring/SpringUtils.java @@ -1,5 +1,6 @@ package com.fastbee.common.utils.spring; +import org.springframework.aop.framework.Advised; import org.springframework.aop.framework.AopContext; import org.springframework.beans.BeansException; import org.springframework.beans.factory.NoSuchBeanDefinitionException; @@ -18,11 +19,11 @@ import java.util.Map; /** * spring工具类 方便在非spring管理环境中获取bean - * + * * @author ruoyi */ @Component -public final class SpringUtils implements BeanFactoryPostProcessor, ApplicationContextAware +public final class SpringUtils implements BeanFactoryPostProcessor, ApplicationContextAware { /** Spring应用上下文环境 */ private static ConfigurableListableBeanFactory beanFactory; @@ -30,13 +31,13 @@ public final class SpringUtils implements BeanFactoryPostProcessor, ApplicationC private static ApplicationContext applicationContext; @Override - public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException + public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { SpringUtils.beanFactory = beanFactory; } @Override - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { SpringUtils.applicationContext = applicationContext; } @@ -119,14 +120,19 @@ public final class SpringUtils implements BeanFactoryPostProcessor, ApplicationC /** * 获取aop代理对象 - * + * * @param invoker * @return */ @SuppressWarnings("unchecked") public static T getAopProxy(T invoker) { - return (T) AopContext.currentProxy(); + Object proxy = AopContext.currentProxy(); + if (((Advised) proxy).getTargetSource().getTargetClass() == invoker.getClass()) + { + return (T) proxy; + } + return invoker; } /** diff --git a/springboot/fastbee-common/src/main/java/com/fastbee/common/utils/uuid/Seq.java b/springboot/fastbee-common/src/main/java/com/fastbee/common/utils/uuid/Seq.java index 7ecd061d..2b4b774b 100644 --- a/springboot/fastbee-common/src/main/java/com/fastbee/common/utils/uuid/Seq.java +++ b/springboot/fastbee-common/src/main/java/com/fastbee/common/utils/uuid/Seq.java @@ -22,21 +22,21 @@ public class Seq private static AtomicInteger uploadSeq = new AtomicInteger(1); // 机器标识 - private static String machineCode = "A"; + private static final String machineCode = "A"; /** * 获取通用序列号 - * + * * @return 序列值 */ public static String getId() { return getId(commSeqType); } - + /** * 默认16位序列号 yyMMddHHmmss + 一位机器标识 + 3长度循环递增字符串 - * + * * @return 序列值 */ public static String getId(String type) @@ -51,7 +51,7 @@ public class Seq /** * 通用接口序列号 yyMMddHHmmss + 一位机器标识 + length长度循环递增字符串 - * + * * @param atomicInt 序列数 * @param length 数值长度 * @return 序列值 @@ -66,7 +66,7 @@ public class Seq /** * 序列循环递增字符串[1, 10 的 (length)幂次方), 用0左补齐length位数 - * + * * @return 序列值 */ private synchronized static String getSeq(AtomicInteger atomicInt, int length) diff --git a/springboot/fastbee-common/src/main/java/com/fastbee/common/xss/XssValidator.java b/springboot/fastbee-common/src/main/java/com/fastbee/common/xss/XssValidator.java index cf6a6dee..8cf72a75 100644 --- a/springboot/fastbee-common/src/main/java/com/fastbee/common/xss/XssValidator.java +++ b/springboot/fastbee-common/src/main/java/com/fastbee/common/xss/XssValidator.java @@ -8,7 +8,7 @@ import java.util.regex.Pattern; /** * 自定义xss校验注解实现 - * + * * @author ruoyi */ public class XssValidator implements ConstraintValidator @@ -27,8 +27,13 @@ public class XssValidator implements ConstraintValidator public static boolean containsHtml(String value) { + StringBuilder sHtml = new StringBuilder(); Pattern pattern = Pattern.compile(HTML_PATTERN); Matcher matcher = pattern.matcher(value); - return matcher.matches(); + while (matcher.find()) + { + sHtml.append(matcher.group()); + } + return pattern.matcher(sHtml).matches(); } -} \ No newline at end of file +} diff --git a/springboot/fastbee-framework/src/main/java/com/fastbee/framework/aspectj/DataScopeAspect.java b/springboot/fastbee-framework/src/main/java/com/fastbee/framework/aspectj/DataScopeAspect.java index 813d9d3f..95523e9a 100644 --- a/springboot/fastbee-framework/src/main/java/com/fastbee/framework/aspectj/DataScopeAspect.java +++ b/springboot/fastbee-framework/src/main/java/com/fastbee/framework/aspectj/DataScopeAspect.java @@ -7,6 +7,7 @@ import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.stereotype.Component; import com.fastbee.common.annotation.DataScope; +import com.fastbee.common.constant.UserConstants; import com.fastbee.common.core.domain.BaseEntity; import com.fastbee.common.core.domain.entity.SysRole; import com.fastbee.common.core.domain.entity.SysUser; @@ -73,8 +74,7 @@ public class DataScopeAspect if (StringUtils.isNotNull(currentUser) && !currentUser.isAdmin()) { String permission = StringUtils.defaultIfEmpty(controllerDataScope.permission(), PermissionContextHolder.getContext()); - dataScopeFilter(joinPoint, currentUser, controllerDataScope.deptAlias(), - controllerDataScope.userAlias(), permission); + dataScopeFilter(joinPoint, currentUser, controllerDataScope.deptAlias(), controllerDataScope.userAlias(), permission); } } } @@ -92,29 +92,42 @@ public class DataScopeAspect { StringBuilder sqlString = new StringBuilder(); List conditions = new ArrayList(); + List scopeCustomIds = new ArrayList(); + user.getRoles().forEach(role -> { + if (DATA_SCOPE_CUSTOM.equals(role.getDataScope()) && StringUtils.equals(role.getStatus(), UserConstants.ROLE_NORMAL) && StringUtils.containsAny(role.getPermissions(), Convert.toStrArray(permission))) + { + scopeCustomIds.add(Convert.toStr(role.getRoleId())); + } + }); for (SysRole role : user.getRoles()) { String dataScope = role.getDataScope(); - if (!DATA_SCOPE_CUSTOM.equals(dataScope) && conditions.contains(dataScope)) + if (conditions.contains(dataScope) || StringUtils.equals(role.getStatus(), UserConstants.ROLE_DISABLE)) { continue; } - if (StringUtils.isNotEmpty(permission) && StringUtils.isNotEmpty(role.getPermissions()) - && !StringUtils.containsAny(role.getPermissions(), Convert.toStrArray(permission))) + if (!StringUtils.containsAny(role.getPermissions(), Convert.toStrArray(permission))) { continue; } if (DATA_SCOPE_ALL.equals(dataScope)) { sqlString = new StringBuilder(); + conditions.add(dataScope); break; } else if (DATA_SCOPE_CUSTOM.equals(dataScope)) { - sqlString.append(StringUtils.format( - " OR {}.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id = {} ) ", deptAlias, - role.getRoleId())); + if (scopeCustomIds.size() > 1) + { + // 多个自定数据权限使用in查询,避免多次拼接。 + sqlString.append(StringUtils.format(" OR {}.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id in ({}) ) ", deptAlias, String.join(",", scopeCustomIds))); + } + else + { + sqlString.append(StringUtils.format(" OR {}.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id = {} ) ", deptAlias, role.getRoleId())); + } } else if (DATA_SCOPE_DEPT.equals(dataScope)) { @@ -122,9 +135,7 @@ public class DataScopeAspect } else if (DATA_SCOPE_DEPT_AND_CHILD.equals(dataScope)) { - sqlString.append(StringUtils.format( - " OR {}.dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = {} or find_in_set( {} , ancestors ) )", - deptAlias, user.getDeptId(), user.getDeptId())); + sqlString.append(StringUtils.format(" OR {}.dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = {} or find_in_set( {} , ancestors ) )", deptAlias, user.getDeptId(), user.getDeptId())); } else if (DATA_SCOPE_SELF.equals(dataScope)) { @@ -141,6 +152,12 @@ public class DataScopeAspect conditions.add(dataScope); } + // 角色都不包含传递过来的权限字符,这个时候sqlString也会为空,所以要限制一下,不查询任何数据 + if (StringUtils.isEmpty(conditions)) + { + sqlString.append(StringUtils.format(" OR {}.dept_id = 0 ", deptAlias)); + } + if (StringUtils.isNotBlank(sqlString.toString())) { Object params = joinPoint.getArgs()[0]; diff --git a/springboot/fastbee-framework/src/main/java/com/fastbee/framework/aspectj/RateLimiterAspect.java b/springboot/fastbee-framework/src/main/java/com/fastbee/framework/aspectj/RateLimiterAspect.java index caed1bd1..861493e9 100644 --- a/springboot/fastbee-framework/src/main/java/com/fastbee/framework/aspectj/RateLimiterAspect.java +++ b/springboot/fastbee-framework/src/main/java/com/fastbee/framework/aspectj/RateLimiterAspect.java @@ -79,7 +79,7 @@ public class RateLimiterAspect StringBuffer stringBuffer = new StringBuffer(rateLimiter.key()); if (rateLimiter.limitType() == LimitType.IP) { - stringBuffer.append(IpUtils.getIpAddr(ServletUtils.getRequest())).append("-"); + stringBuffer.append(IpUtils.getIpAddr()).append("-"); } MethodSignature signature = (MethodSignature) point.getSignature(); Method method = signature.getMethod(); diff --git a/springboot/fastbee-framework/src/main/java/com/fastbee/framework/config/I18nConfig.java b/springboot/fastbee-framework/src/main/java/com/fastbee/framework/config/I18nConfig.java new file mode 100644 index 00000000..0eb53125 --- /dev/null +++ b/springboot/fastbee-framework/src/main/java/com/fastbee/framework/config/I18nConfig.java @@ -0,0 +1,43 @@ +package com.fastbee.framework.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.LocaleResolver; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import org.springframework.web.servlet.i18n.LocaleChangeInterceptor; +import org.springframework.web.servlet.i18n.SessionLocaleResolver; +import com.fastbee.common.constant.Constants; + +/** + * 资源文件配置加载 + * + * @author ruoyi + */ +@Configuration +public class I18nConfig implements WebMvcConfigurer +{ + @Bean + public LocaleResolver localeResolver() + { + SessionLocaleResolver slr = new SessionLocaleResolver(); + // 默认语言 + slr.setDefaultLocale(Constants.DEFAULT_LOCALE); + return slr; + } + + @Bean + public LocaleChangeInterceptor localeChangeInterceptor() + { + LocaleChangeInterceptor lci = new LocaleChangeInterceptor(); + // 参数名 + lci.setParamName("lang"); + return lci; + } + + @Override + public void addInterceptors(InterceptorRegistry registry) + { + registry.addInterceptor(localeChangeInterceptor()); + } +} diff --git a/springboot/fastbee-framework/src/main/java/com/fastbee/framework/config/RedisConfig.java b/springboot/fastbee-framework/src/main/java/com/fastbee/framework/config/RedisConfig.java index 70e9783d..035fcba2 100644 --- a/springboot/fastbee-framework/src/main/java/com/fastbee/framework/config/RedisConfig.java +++ b/springboot/fastbee-framework/src/main/java/com/fastbee/framework/config/RedisConfig.java @@ -1,6 +1,7 @@ package com.fastbee.framework.config; import org.springframework.cache.annotation.CachingConfigurerSupport; +import org.springframework.cache.annotation.EnableCaching; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisConnectionFactory; @@ -14,6 +15,7 @@ import org.springframework.data.redis.serializer.StringRedisSerializer; * @author ruoyi */ @Configuration +@EnableCaching public class RedisConfig extends CachingConfigurerSupport { @Bean diff --git a/springboot/fastbee-framework/src/main/java/com/fastbee/framework/config/ResourcesConfig.java b/springboot/fastbee-framework/src/main/java/com/fastbee/framework/config/ResourcesConfig.java index 76e98745..1a1dfa6b 100644 --- a/springboot/fastbee-framework/src/main/java/com/fastbee/framework/config/ResourcesConfig.java +++ b/springboot/fastbee-framework/src/main/java/com/fastbee/framework/config/ResourcesConfig.java @@ -17,7 +17,7 @@ import com.fastbee.framework.interceptor.RepeatSubmitInterceptor; /** * 通用配置 - * + * * @author ruoyi */ @Configuration @@ -36,7 +36,7 @@ public class ResourcesConfig implements WebMvcConfigurer /** swagger配置 */ registry.addResourceHandler("/swagger-ui/**") .addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/") - .setCacheControl(CacheControl.maxAge(5, TimeUnit.HOURS).cachePublic());; + .setCacheControl(CacheControl.maxAge(5, TimeUnit.HOURS).cachePublic()); } /** @@ -70,4 +70,4 @@ public class ResourcesConfig implements WebMvcConfigurer // 返回新的CorsFilter return new CorsFilter(source); } -} \ No newline at end of file +} diff --git a/springboot/fastbee-framework/src/main/java/com/fastbee/framework/config/properties/PermitAllUrlProperties.java b/springboot/fastbee-framework/src/main/java/com/fastbee/framework/config/properties/PermitAllUrlProperties.java index 71baae88..690fd181 100644 --- a/springboot/fastbee-framework/src/main/java/com/fastbee/framework/config/properties/PermitAllUrlProperties.java +++ b/springboot/fastbee-framework/src/main/java/com/fastbee/framework/config/properties/PermitAllUrlProperties.java @@ -3,6 +3,7 @@ package com.fastbee.framework.config.properties; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.regex.Pattern; import org.apache.commons.lang3.RegExUtils; @@ -19,7 +20,7 @@ import com.fastbee.common.annotation.Anonymous; /** * 设置Anonymous注解允许匿名访问的url - * + * * @author ruoyi */ @Configuration @@ -44,12 +45,12 @@ public class PermitAllUrlProperties implements InitializingBean, ApplicationCont // 获取方法上边的注解 替代path variable 为 * Anonymous method = AnnotationUtils.findAnnotation(handlerMethod.getMethod(), Anonymous.class); - Optional.ofNullable(method).ifPresent(anonymous -> info.getPatternsCondition().getPatterns() + Optional.ofNullable(method).ifPresent(anonymous -> Objects.requireNonNull(info.getPatternsCondition().getPatterns()) .forEach(url -> urls.add(RegExUtils.replaceAll(url, PATTERN, ASTERISK)))); // 获取类上边的注解, 替代path variable 为 * Anonymous controller = AnnotationUtils.findAnnotation(handlerMethod.getBeanType(), Anonymous.class); - Optional.ofNullable(controller).ifPresent(anonymous -> info.getPatternsCondition().getPatterns() + Optional.ofNullable(controller).ifPresent(anonymous -> Objects.requireNonNull(info.getPatternsCondition().getPatterns()) .forEach(url -> urls.add(RegExUtils.replaceAll(url, PATTERN, ASTERISK)))); }); } diff --git a/springboot/fastbee-framework/src/main/java/com/fastbee/framework/datasource/DynamicDataSourceContextHolder.java b/springboot/fastbee-framework/src/main/java/com/fastbee/framework/datasource/DynamicDataSourceContextHolder.java index 04e5877f..ccfbc614 100644 --- a/springboot/fastbee-framework/src/main/java/com/fastbee/framework/datasource/DynamicDataSourceContextHolder.java +++ b/springboot/fastbee-framework/src/main/java/com/fastbee/framework/datasource/DynamicDataSourceContextHolder.java @@ -5,7 +5,7 @@ import org.slf4j.LoggerFactory; /** * 数据源切换处理 - * + * * @author ruoyi */ public class DynamicDataSourceContextHolder @@ -14,7 +14,7 @@ public class DynamicDataSourceContextHolder /** * 使用ThreadLocal维护变量,ThreadLocal为每个使用该变量的线程提供独立的变量副本, - * 所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。 + * 所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。 */ private static final ThreadLocal CONTEXT_HOLDER = new ThreadLocal<>(); diff --git a/springboot/fastbee-framework/src/main/java/com/fastbee/framework/interceptor/RepeatSubmitInterceptor.java b/springboot/fastbee-framework/src/main/java/com/fastbee/framework/interceptor/RepeatSubmitInterceptor.java index 7ce4bc2b..778021a9 100644 --- a/springboot/fastbee-framework/src/main/java/com/fastbee/framework/interceptor/RepeatSubmitInterceptor.java +++ b/springboot/fastbee-framework/src/main/java/com/fastbee/framework/interceptor/RepeatSubmitInterceptor.java @@ -47,8 +47,9 @@ public abstract class RepeatSubmitInterceptor implements HandlerInterceptor /** * 验证是否重复提交由子类实现具体的防重复提交的规则 * - * @param request - * @return + * @param request 请求信息 + * @param annotation 防重复注解参数 + * @return 结果 * @throws Exception */ public abstract boolean isRepeatSubmit(HttpServletRequest request, RepeatSubmit annotation); diff --git a/springboot/fastbee-framework/src/main/java/com/fastbee/framework/manager/factory/AsyncFactory.java b/springboot/fastbee-framework/src/main/java/com/fastbee/framework/manager/factory/AsyncFactory.java index 34bd8098..19ba6587 100644 --- a/springboot/fastbee-framework/src/main/java/com/fastbee/framework/manager/factory/AsyncFactory.java +++ b/springboot/fastbee-framework/src/main/java/com/fastbee/framework/manager/factory/AsyncFactory.java @@ -18,7 +18,7 @@ import eu.bitwalker.useragentutils.UserAgent; /** * 异步工厂(产生任务用) - * + * * @author ruoyi */ public class AsyncFactory @@ -27,7 +27,7 @@ public class AsyncFactory /** * 记录登录信息 - * + * * @param username 用户名 * @param status 状态 * @param message 消息 @@ -38,7 +38,7 @@ public class AsyncFactory final Object... args) { final UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent")); - final String ip = IpUtils.getIpAddr(ServletUtils.getRequest()); + final String ip = IpUtils.getIpAddr(); return new TimerTask() { @Override @@ -82,7 +82,7 @@ public class AsyncFactory /** * 操作日志记录 - * + * * @param operLog 操作日志信息 * @return 任务task */ diff --git a/springboot/fastbee-framework/src/main/java/com/fastbee/framework/security/handle/LogoutSuccessHandlerImpl.java b/springboot/fastbee-framework/src/main/java/com/fastbee/framework/security/handle/LogoutSuccessHandlerImpl.java index 65ad50f5..32530ba6 100644 --- a/springboot/fastbee-framework/src/main/java/com/fastbee/framework/security/handle/LogoutSuccessHandlerImpl.java +++ b/springboot/fastbee-framework/src/main/java/com/fastbee/framework/security/handle/LogoutSuccessHandlerImpl.java @@ -4,6 +4,8 @@ import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; + +import com.fastbee.common.utils.MessageUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.security.core.Authentication; @@ -20,7 +22,7 @@ import com.fastbee.framework.web.service.TokenService; /** * 自定义退出处理类 返回成功 - * + * * @author ruoyi */ @Configuration @@ -31,7 +33,7 @@ public class LogoutSuccessHandlerImpl implements LogoutSuccessHandler /** * 退出处理 - * + * * @return */ @Override @@ -45,8 +47,8 @@ public class LogoutSuccessHandlerImpl implements LogoutSuccessHandler // 删除用户缓存记录 tokenService.delLoginUser(loginUser.getToken()); // 记录用户退出日志 - AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName, Constants.LOGOUT, "退出成功")); + AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName, Constants.LOGOUT, MessageUtils.message("user.logout.success"))); } - ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.success("退出成功"))); + ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.success(MessageUtils.message("user.logout.success")))); } } diff --git a/springboot/fastbee-framework/src/main/java/com/fastbee/framework/web/exception/GlobalExceptionHandler.java b/springboot/fastbee-framework/src/main/java/com/fastbee/framework/web/exception/GlobalExceptionHandler.java index a848827f..bc6bc84c 100644 --- a/springboot/fastbee-framework/src/main/java/com/fastbee/framework/web/exception/GlobalExceptionHandler.java +++ b/springboot/fastbee-framework/src/main/java/com/fastbee/framework/web/exception/GlobalExceptionHandler.java @@ -7,17 +7,21 @@ import org.springframework.security.access.AccessDeniedException; import org.springframework.validation.BindException; import org.springframework.web.HttpRequestMethodNotSupportedException; import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.MissingPathVariableException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; +import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; import com.fastbee.common.constant.HttpStatus; import com.fastbee.common.core.domain.AjaxResult; +import com.fastbee.common.core.text.Convert; import com.fastbee.common.exception.DemoModeException; import com.fastbee.common.exception.ServiceException; import com.fastbee.common.utils.StringUtils; +import com.fastbee.common.utils.html.EscapeUtil; /** * 全局异常处理器 - * + * * @author ruoyi */ @RestControllerAdvice @@ -59,6 +63,33 @@ public class GlobalExceptionHandler return StringUtils.isNotNull(code) ? AjaxResult.error(code, e.getMessage()) : AjaxResult.error(e.getMessage()); } + /** + * 请求路径中缺少必需的路径变量 + */ + @ExceptionHandler(MissingPathVariableException.class) + public AjaxResult handleMissingPathVariableException(MissingPathVariableException e, HttpServletRequest request) + { + String requestURI = request.getRequestURI(); + log.error("请求路径中缺少必需的路径变量'{}',发生系统异常.", requestURI, e); + return AjaxResult.error(String.format("请求路径中缺少必需的路径变量[%s]", e.getVariableName())); + } + + /** + * 请求参数类型不匹配 + */ + @ExceptionHandler(MethodArgumentTypeMismatchException.class) + public AjaxResult handleMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException e, HttpServletRequest request) + { + String requestURI = request.getRequestURI(); + String value = Convert.toStr(e.getValue()); + if (StringUtils.isNotEmpty(value)) + { + value = EscapeUtil.clean(value); + } + log.error("请求参数类型不匹配'{}',发生系统异常.", requestURI, e); + return AjaxResult.error(String.format("请求参数类型不匹配,参数[%s]要求类型为:'%s',但输入值为:'%s'", e.getName(), e.getRequiredType().getName(), value)); + } + /** * 拦截未知的运行时异常 */ diff --git a/springboot/fastbee-framework/src/main/java/com/fastbee/framework/web/service/PermissionService.java b/springboot/fastbee-framework/src/main/java/com/fastbee/framework/web/service/PermissionService.java index 16061890..4e41114f 100644 --- a/springboot/fastbee-framework/src/main/java/com/fastbee/framework/web/service/PermissionService.java +++ b/springboot/fastbee-framework/src/main/java/com/fastbee/framework/web/service/PermissionService.java @@ -3,6 +3,7 @@ package com.fastbee.framework.web.service; import java.util.Set; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; +import com.fastbee.common.constant.Constants; import com.fastbee.common.core.domain.entity.SysRole; import com.fastbee.common.core.domain.model.LoginUser; import com.fastbee.common.utils.SecurityUtils; @@ -11,25 +12,15 @@ import com.fastbee.framework.security.context.PermissionContextHolder; /** * RuoYi首创 自定义权限实现,ss取自SpringSecurity首字母 - * + * * @author ruoyi */ @Service("ss") public class PermissionService { - /** 所有权限标识 */ - private static final String ALL_PERMISSION = "*:*:*"; - - /** 管理员角色权限标识 */ - private static final String SUPER_ADMIN = "admin"; - - private static final String ROLE_DELIMETER = ","; - - private static final String PERMISSION_DELIMETER = ","; - /** * 验证用户是否具备某权限 - * + * * @param permission 权限字符串 * @return 用户是否具备某权限 */ @@ -78,7 +69,7 @@ public class PermissionService } PermissionContextHolder.setContext(permissions); Set authorities = loginUser.getPermissions(); - for (String permission : permissions.split(PERMISSION_DELIMETER)) + for (String permission : permissions.split(Constants.PERMISSION_DELIMETER)) { if (permission != null && hasPermissions(authorities, permission)) { @@ -90,7 +81,7 @@ public class PermissionService /** * 判断用户是否拥有某个角色 - * + * * @param role 角色字符串 * @return 用户是否具备某角色 */ @@ -108,7 +99,7 @@ public class PermissionService for (SysRole sysRole : loginUser.getUser().getRoles()) { String roleKey = sysRole.getRoleKey(); - if (SUPER_ADMIN.equals(roleKey) || roleKey.equals(StringUtils.trim(role))) + if (Constants.SUPER_ADMIN.equals(roleKey) || roleKey.equals(StringUtils.trim(role))) { return true; } @@ -144,7 +135,7 @@ public class PermissionService { return false; } - for (String role : roles.split(ROLE_DELIMETER)) + for (String role : roles.split(Constants.ROLE_DELIMETER)) { if (hasRole(role)) { @@ -156,13 +147,13 @@ public class PermissionService /** * 判断是否包含权限 - * + * * @param permissions 权限列表 * @param permission 权限字符串 * @return 用户是否具备某权限 */ private boolean hasPermissions(Set permissions, String permission) { - return permissions.contains(ALL_PERMISSION) || permissions.contains(StringUtils.trim(permission)); + return permissions.contains(Constants.ALL_PERMISSION) || permissions.contains(StringUtils.trim(permission)); } } diff --git a/springboot/fastbee-framework/src/main/java/com/fastbee/framework/web/service/SysLoginService.java b/springboot/fastbee-framework/src/main/java/com/fastbee/framework/web/service/SysLoginService.java index 7a37687d..4a9a3405 100644 --- a/springboot/fastbee-framework/src/main/java/com/fastbee/framework/web/service/SysLoginService.java +++ b/springboot/fastbee-framework/src/main/java/com/fastbee/framework/web/service/SysLoginService.java @@ -2,17 +2,15 @@ package com.fastbee.framework.web.service; import com.fastbee.common.constant.CacheConstants; import com.fastbee.common.constant.Constants; +import com.fastbee.common.constant.UserConstants; import com.fastbee.common.core.domain.entity.SysUser; import com.fastbee.common.core.domain.model.LoginUser; import com.fastbee.common.core.redis.RedisCache; import com.fastbee.common.enums.UserStatus; import com.fastbee.common.exception.ServiceException; -import com.fastbee.common.exception.user.CaptchaException; -import com.fastbee.common.exception.user.CaptchaExpireException; -import com.fastbee.common.exception.user.UserPasswordNotMatchException; +import com.fastbee.common.exception.user.*; import com.fastbee.common.utils.DateUtils; import com.fastbee.common.utils.MessageUtils; -import com.fastbee.common.utils.ServletUtils; import com.fastbee.common.utils.StringUtils; import com.fastbee.common.utils.ip.IpUtils; import com.fastbee.framework.manager.AsyncManager; @@ -70,12 +68,10 @@ public class SysLoginService */ public String login(String username, String password, String code, String uuid) { - boolean captchaEnabled = configService.selectCaptchaEnabled(); - // 验证码开关 - if (captchaEnabled) - { - validateCaptcha(username, code, uuid); - } + // 验证码校验 + validateCaptcha(username, code, uuid); + // 登录前置校验 + loginPreCheck(username, password); // 用户验证 Authentication authentication = null; try @@ -186,18 +182,58 @@ public class SysLoginService */ public void validateCaptcha(String username, String code, String uuid) { - String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, ""); - String captcha = redisCache.getCacheObject(verifyKey); - redisCache.deleteObject(verifyKey); - if (captcha == null) + boolean captchaEnabled = configService.selectCaptchaEnabled(); + if (captchaEnabled) { - AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"))); - throw new CaptchaExpireException(); + String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, ""); + String captcha = redisCache.getCacheObject(verifyKey); + if (captcha == null) + { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"))); + throw new CaptchaExpireException(); + } + redisCache.deleteObject(verifyKey); + if (!code.equalsIgnoreCase(captcha)) + { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error"))); + throw new CaptchaException(); + } } - if (!code.equalsIgnoreCase(captcha)) + } + + /** + * 登录前置校验 + * @param username 用户名 + * @param password 用户密码 + */ + public void loginPreCheck(String username, String password) + { + // 用户名或密码为空 错误 + if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) { - AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error"))); - throw new CaptchaException(); + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("not.null"))); + throw new UserNotExistsException(); + } + // 密码如果不在指定范围内 错误 + if (password.length() < UserConstants.PASSWORD_MIN_LENGTH + || password.length() > UserConstants.PASSWORD_MAX_LENGTH) + { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match"))); + throw new UserPasswordNotMatchException(); + } + // 用户名不在指定范围内 错误 + if (username.length() < UserConstants.USERNAME_MIN_LENGTH + || username.length() > UserConstants.USERNAME_MAX_LENGTH) + { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match"))); + throw new UserPasswordNotMatchException(); + } + // IP黑名单校验 + String blackStr = configService.selectConfigByKey("sys.login.blackIPList"); + if (IpUtils.isMatchedIp(blackStr, IpUtils.getIpAddr())) + { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("login.blocked"))); + throw new BlackListException(); } } @@ -210,7 +246,7 @@ public class SysLoginService { SysUser sysUser = new SysUser(); sysUser.setUserId(userId); - sysUser.setLoginIp(IpUtils.getIpAddr(ServletUtils.getRequest())); + sysUser.setLoginIp(IpUtils.getIpAddr()); sysUser.setLoginDate(DateUtils.getNowDate()); userService.updateUserProfile(sysUser); } diff --git a/springboot/fastbee-framework/src/main/java/com/fastbee/framework/web/service/SysPermissionService.java b/springboot/fastbee-framework/src/main/java/com/fastbee/framework/web/service/SysPermissionService.java index 1010a7bc..b8b03fa5 100644 --- a/springboot/fastbee-framework/src/main/java/com/fastbee/framework/web/service/SysPermissionService.java +++ b/springboot/fastbee-framework/src/main/java/com/fastbee/framework/web/service/SysPermissionService.java @@ -5,14 +5,17 @@ import java.util.List; import java.util.Set; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; +import com.fastbee.common.constant.UserConstants; import com.fastbee.common.core.domain.entity.SysRole; import com.fastbee.common.core.domain.entity.SysUser; +import com.fastbee.common.utils.StringUtils; import com.fastbee.system.service.ISysMenuService; import com.fastbee.system.service.ISysRoleService; /** * 用户权限处理 - * + * * @author ruoyi */ @Component @@ -26,7 +29,7 @@ public class SysPermissionService /** * 获取角色数据权限 - * + * * @param user 用户信息 * @return 角色权限信息 */ @@ -47,7 +50,7 @@ public class SysPermissionService /** * 获取菜单数据权限 - * + * * @param user 用户信息 * @return 菜单权限信息 */ @@ -62,14 +65,17 @@ public class SysPermissionService else { List roles = user.getRoles(); - if (!roles.isEmpty() && roles.size() > 1) + if (!CollectionUtils.isEmpty(roles)) { // 多角色设置permissions属性,以便数据权限匹配权限 for (SysRole role : roles) { - Set rolePerms = menuService.selectMenuPermsByRoleId(role.getRoleId()); - role.setPermissions(rolePerms); - perms.addAll(rolePerms); + if (StringUtils.equals(role.getStatus(), UserConstants.ROLE_NORMAL) && !role.isAdmin()) + { + Set rolePerms = menuService.selectMenuPermsByRoleId(role.getRoleId()); + role.setPermissions(rolePerms); + perms.addAll(rolePerms); + } } } else diff --git a/springboot/fastbee-framework/src/main/java/com/fastbee/framework/web/service/TokenService.java b/springboot/fastbee-framework/src/main/java/com/fastbee/framework/web/service/TokenService.java index 9ae8d160..121e71bb 100644 --- a/springboot/fastbee-framework/src/main/java/com/fastbee/framework/web/service/TokenService.java +++ b/springboot/fastbee-framework/src/main/java/com/fastbee/framework/web/service/TokenService.java @@ -53,7 +53,7 @@ public class TokenService { protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND; - private static final Long MILLIS_MINUTE_TEN = 20 * 60 * 1000L; + private static final Long MILLIS_MINUTE_TWENTY = 20 * 60 * 1000L; @Autowired private RedisCache redisCache; @@ -160,6 +160,7 @@ public class TokenService { Map claims = new HashMap<>(); claims.put(Constants.LOGIN_USER_KEY, token); + claims.put(Constants.JWT_USERNAME, loginUser.getUsername()); return createToken(claims); } @@ -217,7 +218,7 @@ public class TokenService { public void verifyToken(LoginUser loginUser) { long expireTime = loginUser.getExpireTime(); long currentTime = System.currentTimeMillis(); - if (expireTime - currentTime <= MILLIS_MINUTE_TEN) { + if (expireTime - currentTime <= MILLIS_MINUTE_TWENTY) { refreshToken(loginUser); } } diff --git a/springboot/fastbee-framework/src/main/java/com/fastbee/framework/web/service/UserDetailsServiceImpl.java b/springboot/fastbee-framework/src/main/java/com/fastbee/framework/web/service/UserDetailsServiceImpl.java index 01c56c4b..7a5fe886 100644 --- a/springboot/fastbee-framework/src/main/java/com/fastbee/framework/web/service/UserDetailsServiceImpl.java +++ b/springboot/fastbee-framework/src/main/java/com/fastbee/framework/web/service/UserDetailsServiceImpl.java @@ -11,6 +11,7 @@ import com.fastbee.common.core.domain.entity.SysUser; import com.fastbee.common.core.domain.model.LoginUser; import com.fastbee.common.enums.UserStatus; import com.fastbee.common.exception.ServiceException; +import com.fastbee.common.utils.MessageUtils; import com.fastbee.common.utils.StringUtils; import com.fastbee.system.service.ISysUserService; @@ -26,7 +27,7 @@ public class UserDetailsServiceImpl implements UserDetailsService @Autowired private ISysUserService userService; - + @Autowired private SysPasswordService passwordService; @@ -40,17 +41,17 @@ public class UserDetailsServiceImpl implements UserDetailsService if (StringUtils.isNull(user)) { log.info("登录用户:{} 不存在.", username); - throw new ServiceException("登录用户:" + username + " 不存在"); + throw new ServiceException(MessageUtils.message("user.not.exists")); } else if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) { log.info("登录用户:{} 已被删除.", username); - throw new ServiceException("对不起,您的账号:" + username + " 已被删除"); + throw new ServiceException(MessageUtils.message("user.password.delete")); } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) { log.info("登录用户:{} 已被停用.", username); - throw new ServiceException("对不起,您的账号:" + username + " 已停用"); + throw new ServiceException(MessageUtils.message("user.blocked")); } passwordService.validate(user); diff --git a/springboot/fastbee-plugs/fastbee-mqtt-client/src/main/java/com/fastbee/mqttclient/MqttClientConfig.java b/springboot/fastbee-plugs/fastbee-mqtt-client/src/main/java/com/fastbee/mqttclient/MqttClientConfig.java index 4dc0bcc1..fb9363ed 100644 --- a/springboot/fastbee-plugs/fastbee-mqtt-client/src/main/java/com/fastbee/mqttclient/MqttClientConfig.java +++ b/springboot/fastbee-plugs/fastbee-mqtt-client/src/main/java/com/fastbee/mqttclient/MqttClientConfig.java @@ -16,7 +16,7 @@ public class MqttClientConfig { public MqttClientConfig() { this.username = "fastbee"; this.password = "fastbee"; - this.hostUrl = "tcp://127.0.0.1:1883"; + this.hostUrl = "tcp://127.0.0.1:1884"; this.clientId = UUID.randomUUID().toString(); this.defaultTopic = "test"; this.timeout = 30; diff --git a/springboot/fastbee-service/fastbee-system-service/src/main/java/com/fastbee/system/service/impl/SysMenuServiceImpl.java b/springboot/fastbee-service/fastbee-system-service/src/main/java/com/fastbee/system/service/impl/SysMenuServiceImpl.java index 1227943c..a32c5198 100644 --- a/springboot/fastbee-service/fastbee-system-service/src/main/java/com/fastbee/system/service/impl/SysMenuServiceImpl.java +++ b/springboot/fastbee-service/fastbee-system-service/src/main/java/com/fastbee/system/service/impl/SysMenuServiceImpl.java @@ -175,7 +175,7 @@ public class SysMenuServiceImpl implements ISysMenuService router.setQuery(menu.getQuery()); router.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), StringUtils.equals("1", menu.getIsCache()), menu.getPath())); List cMenus = menu.getChildren(); - if (!cMenus.isEmpty() && cMenus.size() > 0 && UserConstants.TYPE_DIR.equals(menu.getMenuType())) + if (StringUtils.isNotEmpty(cMenus) && UserConstants.TYPE_DIR.equals(menu.getMenuType())) { router.setAlwaysShow(true); router.setRedirect("noRedirect"); @@ -188,7 +188,7 @@ public class SysMenuServiceImpl implements ISysMenuService RouterVo children = new RouterVo(); children.setPath(menu.getPath()); children.setComponent(menu.getComponent()); - children.setName(StringUtils.capitalize(menu.getPath())); + children.setName(getRouteName(menu.getRouteName(), menu.getPath())); children.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), StringUtils.equals("1", menu.getIsCache()), menu.getPath())); children.setQuery(menu.getQuery()); childrenList.add(children); @@ -203,7 +203,7 @@ public class SysMenuServiceImpl implements ISysMenuService String routerPath = innerLinkReplaceEach(menu.getPath()); children.setPath(routerPath); children.setComponent(UserConstants.INNER_LINK); - children.setName(StringUtils.capitalize(routerPath)); + children.setName(getRouteName(menu.getRouteName(), routerPath)); children.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), menu.getPath())); childrenList.add(children); router.setChildren(childrenList); @@ -354,13 +354,25 @@ public class SysMenuServiceImpl implements ISysMenuService */ public String getRouteName(SysMenu menu) { - String routerName = StringUtils.capitalize(menu.getPath()); // 非外链并且是一级目录(类型为目录) if (isMenuFrame(menu)) { - routerName = StringUtils.EMPTY; + return StringUtils.EMPTY; } - return routerName; + return getRouteName(menu.getRouteName(), menu.getPath()); + } + + /** + * 获取路由名称,如没有配置路由名称则取路由地址 + * + * @param name 路由名称 + * @param path 路由地址 + * @return 路由名称(驼峰格式) + */ + public String getRouteName(String name, String path) + { + String routerName = StringUtils.isNotEmpty(name) ? name : path; + return StringUtils.capitalize(routerName); } /** @@ -525,7 +537,7 @@ public class SysMenuServiceImpl implements ISysMenuService */ public String innerLinkReplaceEach(String path) { - return StringUtils.replaceEach(path, new String[] { Constants.HTTP, Constants.HTTPS, Constants.WWW, "." }, - new String[] { "", "", "", "/" }); + return StringUtils.replaceEach(path, new String[] { Constants.HTTP, Constants.HTTPS, Constants.WWW, ".", ":" }, + new String[] { "", "", "", "/", "/" }); } } diff --git a/springboot/sql/fastbee.sql b/springboot/sql/fastbee.sql index aa99e31e..3b32d928 100644 --- a/springboot/sql/fastbee.sql +++ b/springboot/sql/fastbee.sql @@ -2437,7 +2437,11 @@ CREATE TABLE `sys_oper_log` ( `status` int(1) NULL DEFAULT 0 COMMENT '操作状态(0正常 1异常)', `error_msg` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '错误消息', `oper_time` datetime NULL DEFAULT NULL COMMENT '操作时间', - PRIMARY KEY (`oper_id`) USING BTREE + `cost_time` bigint(20) DEFAULT 0 COMMENT '消耗时间', + PRIMARY KEY (`oper_id`) USING BTREE, + KEY idx_sys_oper_log_bt (business_type), + KEY idx_sys_oper_log_s (status), + KEY idx_sys_oper_log_ot (oper_time) ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '操作日志记录' ROW_FORMAT = DYNAMIC; -- ----------------------------