refactor(system): 重构系统模块控制器代码结构

- 解决所有接口分页异常
- 剥离控制器校验逻辑
- 解决循环依赖问题
- 解决角色赋权后,权限回显不正确
This commit is contained in:
2025-12-30 12:51:31 +08:00
parent 79b847f9a4
commit 377b0989f8
77 changed files with 4471 additions and 4235 deletions
@@ -15,38 +15,17 @@
*/ */
package cn.odboy.system.controller; package cn.odboy.system.controller;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.odboy.annotation.AnonymousPostMapping; import cn.odboy.annotation.AnonymousPostMapping;
import cn.odboy.constant.CaptchaCodeEnum;
import cn.odboy.constant.SystemConst;
import cn.odboy.framework.exception.BadRequestException;
import cn.odboy.framework.properties.AppProperties;
import cn.odboy.framework.redis.KitRedisHelper;
import cn.odboy.system.dal.model.SystemUserInfoVo; import cn.odboy.system.dal.model.SystemUserInfoVo;
import cn.odboy.system.dal.model.SystemUserJwtVo;
import cn.odboy.system.dal.model.SystemUserLoginArgs; import cn.odboy.system.dal.model.SystemUserLoginArgs;
import cn.odboy.system.dal.redis.SystemCacheKey; import cn.odboy.system.service.SystemAuthService;
import cn.odboy.system.dal.redis.SystemUserOnlineInfoDAO;
import cn.odboy.system.framework.permission.core.KitSecurityHelper;
import cn.odboy.system.framework.permission.core.handler.TokenProvider;
import cn.odboy.system.framework.permission.core.handler.UserDetailsHandler;
import cn.odboy.util.KitRsaEncryptUtil;
import com.wf.captcha.base.Captcha;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import jakarta.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.TimeUnit; import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
@@ -62,92 +41,35 @@ import org.springframework.web.bind.annotation.RestController;
@Api(tags = "系统:系统授权接口") @Api(tags = "系统:系统授权接口")
public class SystemAuthController { public class SystemAuthController {
@Autowired private KitRedisHelper redisHelper; @Autowired
@Autowired private SystemUserOnlineInfoDAO systemUserOnlineInfoDAO; private SystemAuthService systemAuthService;
@Autowired private TokenProvider tokenProvider;
@Autowired private AppProperties properties;
@Autowired private PasswordEncoder passwordEncoder;
@Autowired private UserDetailsHandler userDetailsService;
@ApiOperation("登录授权") @ApiOperation("登录授权")
@AnonymousPostMapping(value = "/login") @AnonymousPostMapping(value = "/login")
public ResponseEntity<Map<String, Object>> login(@Validated @RequestBody SystemUserLoginArgs loginRequest, public ResponseEntity<Map<String, Object>> login(@Validated @RequestBody SystemUserLoginArgs loginRequest,
HttpServletRequest request) throws Exception { HttpServletRequest request) throws Exception {
// 密码解密 Map<String, Object> loginInfo = systemAuthService.doLogin(loginRequest, request);
String password = return ResponseEntity.ok(loginInfo);
KitRsaEncryptUtil.decryptByPrivateKey(properties.getRsa().getPrivateKey(), loginRequest.getPassword());
// 查询验证码
String code = redisHelper.get(loginRequest.getUuid(), String.class);
// 清除验证码
redisHelper.del(loginRequest.getUuid());
if (StrUtil.isBlank(code)) {
throw new BadRequestException("验证码不存在或已过期");
}
if (StrUtil.isBlank(loginRequest.getCode()) || !loginRequest.getCode().equalsIgnoreCase(code)) {
throw new BadRequestException("验证码错误");
}
// 获取用户信息
SystemUserJwtVo jwtUser = userDetailsService.loadUserByUsername(loginRequest.getUsername());
// 验证用户密码
if (!passwordEncoder.matches(password, jwtUser.getPassword())) {
throw new BadRequestException("登录密码错误");
}
Authentication authentication =
new UsernamePasswordAuthenticationToken(jwtUser, null, jwtUser.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication);
// 生成令牌
String token = tokenProvider.createToken(jwtUser);
// 返回 token 与 用户信息
Map<String, Object> authInfo = new HashMap<>(2) {{
put("token", String.format("%s %s", SystemConst.TOKEN_PREFIX, token));
put("user", BeanUtil.copyProperties(jwtUser, SystemUserInfoVo.class));
}};
if (properties.getLogin().isSingle()) {
// 踢掉之前已经登录的token
systemUserOnlineInfoDAO.kickOutByUsername(loginRequest.getUsername());
}
// 保存在线信息
systemUserOnlineInfoDAO.saveUserJwtModelByToken(jwtUser, token, request);
// 返回登录信息
return ResponseEntity.ok(authInfo);
} }
@ApiOperation("获取用户信息") @ApiOperation("获取用户信息")
@PostMapping(value = "/info") @PostMapping(value = "/info")
public ResponseEntity<SystemUserInfoVo> getUserInfo() { public ResponseEntity<SystemUserInfoVo> getUserInfo() {
SystemUserJwtVo jwtUser = (SystemUserJwtVo)KitSecurityHelper.getCurrentUser(); SystemUserInfoVo userInfoVo = systemAuthService.getCurrentUserInfoVo();
SystemUserInfoVo userInfoVo = BeanUtil.copyProperties(jwtUser, SystemUserInfoVo.class);
return ResponseEntity.ok(userInfoVo); return ResponseEntity.ok(userInfoVo);
} }
@ApiOperation("获取验证码") @ApiOperation("获取验证码")
@AnonymousPostMapping(value = "/captcha/getImage") @AnonymousPostMapping(value = "/captcha/getImage")
public ResponseEntity<Map<String, Object>> getCode() { public ResponseEntity<Map<String, Object>> getCode() {
// 获取运算的结果 Map<String, Object> imgResult = systemAuthService.getCaptchaInfo();
Captcha captcha = properties.getLogin().getCaptchaSetting().getCaptcha();
String uuid = SystemCacheKey.CAPTCHA_LOGIN + IdUtil.simpleUUID();
//当验证码类型为 arithmetic时且长度 >= 2 时, captcha.text()的结果有几率为浮点型
String captchaValue = captcha.text();
if (captcha.getCharType() - 1 == CaptchaCodeEnum.ARITHMETIC.ordinal() &&
captchaValue.contains(SystemConst.SYMBOL_DOT)) {
captchaValue = captchaValue.split("\\.")[0];
}
// 保存
redisHelper.set(uuid, captchaValue, properties.getLogin().getCaptchaSetting().getExpiration(),
TimeUnit.MINUTES);
// 验证码信息
Map<String, Object> imgResult = new HashMap<String, Object>(2) {{
put("img", captcha.toBase64());
put("uuid", uuid);
}};
return ResponseEntity.ok(imgResult); return ResponseEntity.ok(imgResult);
} }
@ApiOperation("退出登录") @ApiOperation("退出登录")
@AnonymousPostMapping(value = "/logout") @AnonymousPostMapping(value = "/logout")
public ResponseEntity<Void> logout(HttpServletRequest request) { public ResponseEntity<Void> logout(HttpServletRequest request) {
String token = tokenProvider.getToken(request); systemAuthService.doLogout(request);
systemUserOnlineInfoDAO.logoutByToken(token);
return ResponseEntity.ok(null); return ResponseEntity.ok(null);
} }
} }
@@ -15,7 +15,6 @@
*/ */
package cn.odboy.system.controller; package cn.odboy.system.controller;
import cn.odboy.framework.exception.BadRequestException;
import cn.odboy.system.constant.SystemCaptchaBizEnum; import cn.odboy.system.constant.SystemCaptchaBizEnum;
import cn.odboy.system.dal.model.SystemCheckEmailCaptchaArgs; import cn.odboy.system.dal.model.SystemCheckEmailCaptchaArgs;
import cn.odboy.system.service.SystemEmailService; import cn.odboy.system.service.SystemEmailService;
@@ -35,7 +34,8 @@ import org.springframework.web.bind.annotation.RestController;
@Api(tags = "系统:验证码管理") @Api(tags = "系统:验证码管理")
public class SystemCaptchaController { public class SystemCaptchaController {
@Autowired private SystemEmailService systemEmailService; @Autowired
private SystemEmailService systemEmailService;
@ApiOperation("重置邮箱, 发送验证码") @ApiOperation("重置邮箱, 发送验证码")
@PostMapping(value = "/sendResetEmailCaptcha") @PostMapping(value = "/sendResetEmailCaptcha")
@@ -54,11 +54,7 @@ public class SystemCaptchaController {
@ApiOperation("验证码验证") @ApiOperation("验证码验证")
@PostMapping(value = "/checkEmailCaptcha") @PostMapping(value = "/checkEmailCaptcha")
public ResponseEntity<Void> checkEmailCaptcha(@Validated @RequestBody SystemCheckEmailCaptchaArgs args) { public ResponseEntity<Void> checkEmailCaptcha(@Validated @RequestBody SystemCheckEmailCaptchaArgs args) {
SystemCaptchaBizEnum biEnum = SystemCaptchaBizEnum.getByBizCode(args.getBizCode()); systemEmailService.checkEmailCaptcha(args);
if (biEnum == null) {
throw new BadRequestException("不支持的业务");
}
systemEmailService.checkEmailCaptcha(biEnum, args.getEmail(), args.getCode());
return ResponseEntity.ok(null); return ResponseEntity.ok(null);
} }
} }
@@ -30,7 +30,8 @@ import org.springframework.web.bind.annotation.RestController;
@RequestMapping("/api/component") @RequestMapping("/api/component")
public class SystemComponentController { public class SystemComponentController {
@Autowired private SystemDeptService systemDeptService; @Autowired
private SystemDeptService systemDeptService;
@ApiOperation("查询部门下拉选择数据源") @ApiOperation("查询部门下拉选择数据源")
@PostMapping(value = "/queryDeptSelectDataSource") @PostMapping(value = "/queryDeptSelectDataSource")
@@ -24,9 +24,9 @@ import cn.odboy.system.service.SystemDeptService;
import cn.odboy.util.KitPageUtil; import cn.odboy.util.KitPageUtil;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import jakarta.servlet.http.HttpServletResponse;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
@@ -43,7 +43,8 @@ import org.springframework.web.bind.annotation.RestController;
@RequestMapping("/api/dept") @RequestMapping("/api/dept")
public class SystemDeptController { public class SystemDeptController {
@Autowired private SystemDeptService systemDeptService; @Autowired
private SystemDeptService systemDeptService;
@ApiOperation("导出部门数据") @ApiOperation("导出部门数据")
@GetMapping(value = "/download") @GetMapping(value = "/download")
@@ -57,8 +58,7 @@ public class SystemDeptController {
@PreAuthorize("@el.check('user:list','dept:list')") @PreAuthorize("@el.check('user:list','dept:list')")
public ResponseEntity<KitPageResult<SystemDeptTb>> queryDept( public ResponseEntity<KitPageResult<SystemDeptTb>> queryDept(
@Validated @RequestBody KitPageArgs<SystemQueryDeptArgs> pageArgs) throws Exception { @Validated @RequestBody KitPageArgs<SystemQueryDeptArgs> pageArgs) throws Exception {
SystemQueryDeptArgs args = pageArgs.getArgs(); List<SystemDeptTb> depts = systemDeptService.queryAllDeptByArgs(pageArgs.getArgs(), true);
List<SystemDeptTb> depts = systemDeptService.queryAllDeptByArgs(args, true);
return ResponseEntity.ok(KitPageUtil.toPage(depts)); return ResponseEntity.ok(KitPageUtil.toPage(depts));
} }
@@ -90,11 +90,7 @@ public class SystemDeptController {
@PostMapping(value = "/removeDeptByIds") @PostMapping(value = "/removeDeptByIds")
@PreAuthorize("@el.check('dept:del')") @PreAuthorize("@el.check('dept:del')")
public ResponseEntity<Void> removeDeptByIds(@RequestBody Set<Long> ids) { public ResponseEntity<Void> removeDeptByIds(@RequestBody Set<Long> ids) {
// 获取部门, 和其所有子部门 systemDeptService.deleteDeptByIds(ids);
Set<SystemDeptTb> depts = systemDeptService.traverseDeptByIdWithPids(ids);
// 验证是否被角色或用户关联
systemDeptService.verifyBindRelationByIds(depts);
systemDeptService.deleteDeptByIds(depts);
return ResponseEntity.ok(null); return ResponseEntity.ok(null);
} }
} }
@@ -24,10 +24,10 @@ import cn.odboy.system.service.SystemDictService;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
@@ -43,7 +43,8 @@ import org.springframework.web.bind.annotation.RestController;
@RequestMapping("/api/dict") @RequestMapping("/api/dict")
public class SystemDictController { public class SystemDictController {
@Autowired private SystemDictService systemDictService; @Autowired
private SystemDictService systemDictService;
@ApiOperation("导出字典数据") @ApiOperation("导出字典数据")
@GetMapping(value = "/download") @GetMapping(value = "/download")
@@ -65,8 +66,7 @@ public class SystemDictController {
public ResponseEntity<KitPageResult<SystemDictTb>> queryDictByArgs( public ResponseEntity<KitPageResult<SystemDictTb>> queryDictByArgs(
@Validated @RequestBody KitPageArgs<SystemQueryDictArgs> pageArgs) { @Validated @RequestBody KitPageArgs<SystemQueryDictArgs> pageArgs) {
Page<SystemDictTb> page = new Page<>(pageArgs.getPage(), pageArgs.getSize()); Page<SystemDictTb> page = new Page<>(pageArgs.getPage(), pageArgs.getSize());
SystemQueryDictArgs args = pageArgs.getArgs(); return ResponseEntity.ok(systemDictService.searchDict(pageArgs.getArgs(), page));
return ResponseEntity.ok(systemDictService.searchDict(args, page));
} }
@ApiOperation("新增字典") @ApiOperation("新增字典")
@@ -25,7 +25,6 @@ import cn.odboy.system.service.SystemDictDetailService;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -44,7 +43,8 @@ import org.springframework.web.bind.annotation.RestController;
@RequestMapping("/api/dictDetail") @RequestMapping("/api/dictDetail")
public class SystemDictDetailController { public class SystemDictDetailController {
@Autowired private SystemDictDetailService systemDictDetailService; @Autowired
private SystemDictDetailService systemDictDetailService;
@ApiOperation("查询字典详情") @ApiOperation("查询字典详情")
@PostMapping @PostMapping
@@ -57,19 +57,14 @@ public class SystemDictDetailController {
@PostMapping(value = "/queryDictDetailByArgs") @PostMapping(value = "/queryDictDetailByArgs")
public ResponseEntity<KitPageResult<SystemDictDetailVo>> queryDictDetailByArgs( public ResponseEntity<KitPageResult<SystemDictDetailVo>> queryDictDetailByArgs(
@Validated @RequestBody KitPageArgs<SystemQueryDictDetailArgs> pageArgs) { @Validated @RequestBody KitPageArgs<SystemQueryDictDetailArgs> pageArgs) {
SystemQueryDictDetailArgs args = pageArgs.getArgs();
Page<SystemDictDetailTb> page = new Page<>(pageArgs.getPage(), pageArgs.getSize()); Page<SystemDictDetailTb> page = new Page<>(pageArgs.getPage(), pageArgs.getSize());
return ResponseEntity.ok(systemDictDetailService.searchDictDetail(args, page)); return ResponseEntity.ok(systemDictDetailService.searchDictDetail(pageArgs.getArgs(), page));
} }
@ApiOperation("查询多个字典详情") @ApiOperation("查询多个字典详情")
@GetMapping(value = "/getDictDetailMaps") @GetMapping(value = "/getDictDetailMaps")
public ResponseEntity<Map<String, List<SystemDictDetailVo>>> getDictDetailMaps(@RequestParam String dictName) { public ResponseEntity<Map<String, List<SystemDictDetailVo>>> getDictDetailMaps(@RequestParam String dictName) {
String[] names = dictName.split("[,, ]"); Map<String, List<SystemDictDetailVo>> dictMap = systemDictDetailService.getDictDetailMap(dictName);
Map<String, List<SystemDictDetailVo>> dictMap = new HashMap<>(16);
for (String name : names) {
dictMap.put(name, systemDictDetailService.listDictDetailByName(name));
}
return ResponseEntity.ok(dictMap); return ResponseEntity.ok(dictMap);
} }
@@ -36,7 +36,8 @@ import org.springframework.web.bind.annotation.RestController;
@Api(tags = "工具:邮件管理") @Api(tags = "工具:邮件管理")
public class SystemEmailController { public class SystemEmailController {
@Autowired private SystemEmailService systemEmailService; @Autowired
private SystemEmailService systemEmailService;
@ApiOperation("查询配置") @ApiOperation("查询配置")
@PostMapping(value = "/getLastEmailConfig") @PostMapping(value = "/getLastEmailConfig")
@@ -24,9 +24,9 @@ import cn.odboy.system.service.SystemJobService;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.util.Set; import java.util.Set;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
@@ -42,7 +42,8 @@ import org.springframework.web.bind.annotation.RestController;
@RequestMapping("/api/job") @RequestMapping("/api/job")
public class SystemJobController { public class SystemJobController {
@Autowired private SystemJobService systemJobService; @Autowired
private SystemJobService systemJobService;
@ApiOperation("导出岗位数据") @ApiOperation("导出岗位数据")
@GetMapping(value = "/download") @GetMapping(value = "/download")
@@ -56,9 +57,8 @@ public class SystemJobController {
@PreAuthorize("@el.check('job:list','user:list')") @PreAuthorize("@el.check('job:list','user:list')")
public ResponseEntity<KitPageResult<SystemJobTb>> queryJobByArgs( public ResponseEntity<KitPageResult<SystemJobTb>> queryJobByArgs(
@Validated @RequestBody KitPageArgs<SystemQueryJobArgs> pageArgs) { @Validated @RequestBody KitPageArgs<SystemQueryJobArgs> pageArgs) {
SystemQueryJobArgs args = pageArgs.getArgs(); Page<SystemJobTb> page = new Page<>(pageArgs.getPage(), pageArgs.getSize());
Page<SystemJobTb> page = new Page<>(args.getPage(), args.getSize()); return ResponseEntity.ok(systemJobService.searchJobByArgs(pageArgs.getArgs(), page));
return ResponseEntity.ok(systemJobService.searchJobByArgs(args, page));
} }
@ApiOperation("查询岗位") @ApiOperation("查询岗位")
@@ -89,8 +89,6 @@ public class SystemJobController {
@PostMapping(value = "/removeJobByIds") @PostMapping(value = "/removeJobByIds")
@PreAuthorize("@el.check('job:del')") @PreAuthorize("@el.check('job:del')")
public ResponseEntity<Void> removeJobByIds(@RequestBody Set<Long> ids) { public ResponseEntity<Void> removeJobByIds(@RequestBody Set<Long> ids) {
// 验证是否被用户关联
systemJobService.verifyBindRelationByIds(ids);
systemJobService.deleteJobByIds(ids); systemJobService.deleteJobByIds(ids);
return ResponseEntity.ok(null); return ResponseEntity.ok(null);
} }
@@ -17,17 +17,14 @@ package cn.odboy.system.controller;
import cn.odboy.base.KitPageArgs; import cn.odboy.base.KitPageArgs;
import cn.odboy.base.KitPageResult; import cn.odboy.base.KitPageResult;
import cn.odboy.constant.FileTypeEnum;
import cn.odboy.framework.exception.BadRequestException;
import cn.odboy.system.dal.dataobject.SystemLocalStorageTb; import cn.odboy.system.dal.dataobject.SystemLocalStorageTb;
import cn.odboy.system.dal.model.SystemQueryStorageArgs; import cn.odboy.system.dal.model.SystemQueryStorageArgs;
import cn.odboy.system.service.SystemLocalStorageService; import cn.odboy.system.service.SystemLocalStorageService;
import cn.odboy.util.KitFileUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
@@ -45,16 +42,16 @@ import org.springframework.web.multipart.MultipartFile;
@RequestMapping("/api/localStorage") @RequestMapping("/api/localStorage")
public class SystemLocalStorageController { public class SystemLocalStorageController {
@Autowired private SystemLocalStorageService localStorageService; @Autowired
private SystemLocalStorageService localStorageService;
@ApiOperation("查询文件") @ApiOperation("查询文件")
@PostMapping @PostMapping
@PreAuthorize("@el.check('storage:list')") @PreAuthorize("@el.check('storage:list')")
public ResponseEntity<KitPageResult<SystemLocalStorageTb>> queryLocalStorage( public ResponseEntity<KitPageResult<SystemLocalStorageTb>> queryLocalStorage(
@Validated @RequestBody KitPageArgs<SystemQueryStorageArgs> pageArgs) { @Validated @RequestBody KitPageArgs<SystemQueryStorageArgs> pageArgs) {
SystemQueryStorageArgs args = pageArgs.getArgs(); Page<SystemLocalStorageTb> page = new Page<>(pageArgs.getPage(), pageArgs.getSize());
Page<SystemLocalStorageTb> page = new Page<>(args.getPage(), args.getSize()); return ResponseEntity.ok(localStorageService.searchLocalStorage(pageArgs.getArgs(), page));
return ResponseEntity.ok(localStorageService.searchLocalStorage(args, page));
} }
@ApiOperation("导出数据") @ApiOperation("导出数据")
@@ -75,12 +72,7 @@ public class SystemLocalStorageController {
@ApiOperation("上传图片") @ApiOperation("上传图片")
@PostMapping("/uploadPicture") @PostMapping("/uploadPicture")
public ResponseEntity<SystemLocalStorageTb> uploadPicture(@RequestParam MultipartFile file) { public ResponseEntity<SystemLocalStorageTb> uploadPicture(@RequestParam MultipartFile file) {
// 判断文件是否为图片 SystemLocalStorageTb localStorage = localStorageService.uploadPictureV1(file);
String suffix = KitFileUtil.getSuffix(file.getOriginalFilename());
if (!FileTypeEnum.IMAGE.getCode().equals(KitFileUtil.getFileType(suffix))) {
throw new BadRequestException("只能上传图片");
}
SystemLocalStorageTb localStorage = localStorageService.uploadFile(null, file);
return ResponseEntity.ok(localStorage); return ResponseEntity.ok(localStorage);
} }
@@ -15,7 +15,6 @@
*/ */
package cn.odboy.system.controller; package cn.odboy.system.controller;
import cn.hutool.core.collection.CollectionUtil;
import cn.odboy.base.KitPageArgs; import cn.odboy.base.KitPageArgs;
import cn.odboy.base.KitPageResult; import cn.odboy.base.KitPageResult;
import cn.odboy.framework.exception.BadRequestException; import cn.odboy.framework.exception.BadRequestException;
@@ -23,18 +22,13 @@ import cn.odboy.system.dal.dataobject.SystemMenuTb;
import cn.odboy.system.dal.model.SystemMenuVo; import cn.odboy.system.dal.model.SystemMenuVo;
import cn.odboy.system.dal.model.SystemQueryMenuArgs; import cn.odboy.system.dal.model.SystemQueryMenuArgs;
import cn.odboy.system.dal.mysql.SystemMenuMapper; import cn.odboy.system.dal.mysql.SystemMenuMapper;
import cn.odboy.system.framework.permission.core.KitSecurityHelper;
import cn.odboy.system.service.SystemMenuService; import cn.odboy.system.service.SystemMenuService;
import cn.odboy.util.KitPageUtil; import cn.odboy.util.KitPageUtil;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
@@ -51,8 +45,10 @@ import org.springframework.web.bind.annotation.RestController;
@RequestMapping("/api/menu") @RequestMapping("/api/menu")
public class SystemMenuController { public class SystemMenuController {
@Autowired private SystemMenuService systemMenuService; @Autowired
@Autowired private SystemMenuMapper systemMenuMapper; private SystemMenuService systemMenuService;
@Autowired
private SystemMenuMapper systemMenuMapper;
@ApiOperation("导出菜单数据") @ApiOperation("导出菜单数据")
@GetMapping(value = "/download") @GetMapping(value = "/download")
@@ -64,27 +60,23 @@ public class SystemMenuController {
@PostMapping(value = "/buildMenus") @PostMapping(value = "/buildMenus")
@ApiOperation("获取前端所需菜单") @ApiOperation("获取前端所需菜单")
public ResponseEntity<List<SystemMenuVo>> buildMenus() { public ResponseEntity<List<SystemMenuVo>> buildMenus() {
List<SystemMenuTb> menuList = systemMenuService.listMenuByUserId(KitSecurityHelper.getCurrentUserId()); List<SystemMenuVo> systemMenuVos = systemMenuService.buildFrontMenus();
List<SystemMenuTb> menus = systemMenuService.buildMenuTree(menuList); return ResponseEntity.ok(systemMenuVos);
return ResponseEntity.ok(systemMenuService.buildMenuVo(menus));
} }
@ApiOperation("返回全部的菜单") @ApiOperation("返回全部的菜单")
@PostMapping(value = "/queryMenuListByPid") @PostMapping(value = "/queryMenuListByPid")
@PreAuthorize("@el.check('menu:list','roles:list')") @PreAuthorize("@el.check('menu:list','roles:list')")
public ResponseEntity<List<SystemMenuTb>> queryMenuListByPid(@RequestParam Long pid) { public ResponseEntity<List<SystemMenuTb>> queryMenuListByPid(@RequestParam Long pid) {
return ResponseEntity.ok(systemMenuService.listMenuByPid(pid)); List<SystemMenuTb> systemMenuTbs = systemMenuService.listMenuByPid(pid);
return ResponseEntity.ok(systemMenuTbs);
} }
@ApiOperation("根据菜单ID返回所有子节点ID, 包含自身ID") @ApiOperation("根据菜单ID返回所有子节点ID, 包含自身ID")
@PostMapping(value = "/queryChildMenuSet") @PostMapping(value = "/queryChildMenuSet")
@PreAuthorize("@el.check('menu:list','roles:list')") @PreAuthorize("@el.check('menu:list','roles:list')")
public ResponseEntity<Set<Long>> queryChildMenuSet(@RequestParam Long id) { public ResponseEntity<Set<Long>> queryChildMenuSet(@RequestParam Long id) {
Set<SystemMenuTb> menuSet = new HashSet<>(); Set<Long> ids = systemMenuService.listChildMenuSetByMenuId(id);
List<SystemMenuTb> menuList = systemMenuService.listMenuByPid(id);
menuSet.add(systemMenuMapper.selectById(id));
menuSet = systemMenuService.queryChildMenuByArgs(menuList, menuSet);
Set<Long> ids = menuSet.stream().map(SystemMenuTb::getId).collect(Collectors.toSet());
return ResponseEntity.ok(ids); return ResponseEntity.ok(ids);
} }
@@ -101,8 +93,7 @@ public class SystemMenuController {
@PreAuthorize("@el.check('menu:list')") @PreAuthorize("@el.check('menu:list')")
public ResponseEntity<KitPageResult<SystemMenuTb>> queryAllMenu( public ResponseEntity<KitPageResult<SystemMenuTb>> queryAllMenu(
@Validated @RequestBody KitPageArgs<SystemQueryMenuArgs> pageArgs) throws Exception { @Validated @RequestBody KitPageArgs<SystemQueryMenuArgs> pageArgs) throws Exception {
SystemQueryMenuArgs args = pageArgs.getArgs(); List<SystemMenuTb> menuList = systemMenuService.queryAllMenu(pageArgs.getArgs(), true);
List<SystemMenuTb> menuList = systemMenuService.queryAllMenu(args, true);
return ResponseEntity.ok(KitPageUtil.toPage(menuList)); return ResponseEntity.ok(KitPageUtil.toPage(menuList));
} }
@@ -110,23 +101,8 @@ public class SystemMenuController {
@PostMapping("/queryMenuSuperior") @PostMapping("/queryMenuSuperior")
@PreAuthorize("@el.check('menu:list')") @PreAuthorize("@el.check('menu:list')")
public ResponseEntity<List<SystemMenuTb>> queryMenuSuperior(@RequestBody List<Long> ids) { public ResponseEntity<List<SystemMenuTb>> queryMenuSuperior(@RequestBody List<Long> ids) {
Set<SystemMenuTb> menus; List<SystemMenuTb> systemMenuTbs = systemMenuService.listMenuSuperior(ids);
if (CollectionUtil.isNotEmpty(ids)) { return ResponseEntity.ok(systemMenuTbs);
menus = new LinkedHashSet<>(systemMenuService.listMenuByIds(ids));
for (SystemMenuTb menu : menus) {
List<SystemMenuTb> menuList = systemMenuService.querySuperiorMenuByArgs(menu, new ArrayList<>());
for (SystemMenuTb data : menuList) {
if (data.getId().equals(menu.getPid())) {
data.setSubCount(data.getSubCount() - 1);
}
}
menus.addAll(menuList);
}
// 编辑菜单时不显示自己以及自己下级的数据, 避免出现PID数据环形问题
menus = menus.stream().filter(i -> !ids.contains(i.getId())).collect(Collectors.toSet());
return ResponseEntity.ok(systemMenuService.buildMenuTree(new ArrayList<>(menus)));
}
return ResponseEntity.ok(systemMenuService.listMenuByPid(null));
} }
@ApiOperation("新增菜单") @ApiOperation("新增菜单")
@@ -31,7 +31,8 @@ import org.springframework.web.bind.annotation.RestController;
@RequestMapping("/api/monitor") @RequestMapping("/api/monitor")
public class SystemMonitorController { public class SystemMonitorController {
@Autowired private SystemMonitorService systemMonitorService; @Autowired
private SystemMonitorService systemMonitorService;
@PostMapping(value = "/queryServerMonitorInfo") @PostMapping(value = "/queryServerMonitorInfo")
@ApiOperation("查询服务监控") @ApiOperation("查询服务监控")
@@ -19,14 +19,14 @@ import cn.odboy.base.KitPageArgs;
import cn.odboy.base.KitPageResult; import cn.odboy.base.KitPageResult;
import cn.odboy.system.dal.model.SystemUserOnlineVo; import cn.odboy.system.dal.model.SystemUserOnlineVo;
import cn.odboy.system.dal.redis.SystemUserOnlineInfoDAO; import cn.odboy.system.dal.redis.SystemUserOnlineInfoDAO;
import cn.odboy.util.KitDesEncryptUtil;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.util.List;
import java.util.Set; import java.util.Set;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
@@ -42,34 +42,31 @@ import org.springframework.web.bind.annotation.RestController;
@Api(tags = "系统:在线用户管理") @Api(tags = "系统:在线用户管理")
public class SystemOnlineController { public class SystemOnlineController {
@Autowired private SystemUserOnlineInfoDAO systemUserOnlineInfoDAO; @Autowired
private SystemUserOnlineInfoDAO systemUserOnlineInfoDAO;
@ApiOperation("查询在线用户") @ApiOperation("查询在线用户")
@PostMapping @PostMapping
@PreAuthorize("@el.check()") @PreAuthorize("@el.check()")
public ResponseEntity<KitPageResult<SystemUserOnlineVo>> queryOnlineUser( public ResponseEntity<KitPageResult<SystemUserOnlineVo>> queryOnlineUser(
@Validated @RequestBody KitPageArgs<SystemUserOnlineVo> args) { @Validated @RequestBody KitPageArgs<SystemUserOnlineVo> pageArgs) {
IPage<SystemUserOnlineVo> page = new Page<>(args.getPage(), args.getSize()); IPage<SystemUserOnlineVo> page = new Page<>(pageArgs.getPage(), pageArgs.getSize());
return ResponseEntity.ok(systemUserOnlineInfoDAO.queryUserOnlineModelPage(args.getArgs(), page)); return ResponseEntity.ok(systemUserOnlineInfoDAO.queryUserOnlineModelPage(pageArgs.getArgs(), page));
} }
@ApiOperation("导出数据") @ApiOperation("导出数据")
@GetMapping(value = "/download") @GetMapping(value = "/download")
@PreAuthorize("@el.check()") @PreAuthorize("@el.check()")
public void exportOnlineUser(HttpServletResponse response, String username) throws IOException { public void exportOnlineUser(HttpServletResponse response, String username) throws IOException {
systemUserOnlineInfoDAO.downloadUserOnlineModelExcel( List<SystemUserOnlineVo> userOnlineVos = systemUserOnlineInfoDAO.queryUserOnlineModelListByUsername(username);
systemUserOnlineInfoDAO.queryUserOnlineModelListByUsername(username), response); systemUserOnlineInfoDAO.downloadUserOnlineModelExcel(userOnlineVos, response);
} }
@ApiOperation("踢出用户") @ApiOperation("踢出用户")
@PostMapping(value = "/kickOutUser") @PostMapping(value = "/kickOutUser")
@PreAuthorize("@el.check()") @PreAuthorize("@el.check()")
public ResponseEntity<Void> kickOutUser(@RequestBody Set<String> keys) throws Exception { public ResponseEntity<Void> kickOutUser(@RequestBody Set<String> keys) throws Exception {
for (String token : keys) { systemUserOnlineInfoDAO.kickOutUser(keys);
// 解密Key
token = KitDesEncryptUtil.desDecrypt(token);
systemUserOnlineInfoDAO.logoutByToken(token);
}
return ResponseEntity.ok(null); return ResponseEntity.ok(null);
} }
} }
@@ -24,8 +24,8 @@ import cn.odboy.system.service.SystemOssStorageService;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
@@ -45,16 +45,16 @@ import org.springframework.web.multipart.MultipartFile;
@RequestMapping("/api/ossStorage") @RequestMapping("/api/ossStorage")
public class SystemOssStorageController { public class SystemOssStorageController {
@Autowired private SystemOssStorageService systemOssStorageService; @Autowired
private SystemOssStorageService systemOssStorageService;
@ApiOperation("查询文件") @ApiOperation("查询文件")
@PostMapping @PostMapping
@PreAuthorize("@el.check('storage:list')") @PreAuthorize("@el.check('storage:list')")
public ResponseEntity<KitPageResult<SystemOssStorageVo>> queryOssStorage( public ResponseEntity<KitPageResult<SystemOssStorageVo>> queryOssStorage(
@Validated @RequestBody KitPageArgs<SystemQueryStorageArgs> pageArgs) { @Validated @RequestBody KitPageArgs<SystemQueryStorageArgs> pageArgs) {
SystemQueryStorageArgs args = pageArgs.getArgs(); Page<SystemOssStorageTb> page = new Page<>(pageArgs.getPage(), pageArgs.getSize());
Page<SystemOssStorageTb> page = new Page<>(args.getPage(), args.getSize()); return ResponseEntity.ok(systemOssStorageService.searchOssStorage(pageArgs.getArgs(), page));
return ResponseEntity.ok(systemOssStorageService.searchOssStorage(args, page));
} }
@ApiOperation("导出数据") @ApiOperation("导出数据")
@@ -17,8 +17,6 @@ package cn.odboy.system.controller;
import cn.odboy.base.KitPageArgs; import cn.odboy.base.KitPageArgs;
import cn.odboy.base.KitPageResult; import cn.odboy.base.KitPageResult;
import cn.odboy.framework.context.KitSpringBeanHolder;
import cn.odboy.framework.exception.BadRequestException;
import cn.odboy.system.dal.dataobject.SystemQuartzJobTb; import cn.odboy.system.dal.dataobject.SystemQuartzJobTb;
import cn.odboy.system.dal.dataobject.SystemQuartzLogTb; import cn.odboy.system.dal.dataobject.SystemQuartzLogTb;
import cn.odboy.system.dal.model.SystemQueryQuartzJobArgs; import cn.odboy.system.dal.model.SystemQueryQuartzJobArgs;
@@ -27,9 +25,9 @@ import cn.odboy.system.service.SystemQuartzJobService;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.util.Set; import java.util.Set;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
@@ -49,16 +47,16 @@ import org.springframework.web.bind.annotation.RestController;
@Api(tags = "系统:定时任务管理") @Api(tags = "系统:定时任务管理")
public class SystemQuartzJobController { public class SystemQuartzJobController {
@Autowired private SystemQuartzJobService systemQuartzJobService; @Autowired
private SystemQuartzJobService systemQuartzJobService;
@ApiOperation("查询定时任务") @ApiOperation("查询定时任务")
@PostMapping @PostMapping
@PreAuthorize("@el.check('quartzJob:list')") @PreAuthorize("@el.check('quartzJob:list')")
public ResponseEntity<KitPageResult<SystemQuartzJobTb>> queryQuartzJobByCrud( public ResponseEntity<KitPageResult<SystemQuartzJobTb>> queryQuartzJobByCrud(
@Validated @RequestBody KitPageArgs<SystemQueryQuartzJobArgs> pageArgs) { @Validated @RequestBody KitPageArgs<SystemQueryQuartzJobArgs> pageArgs) {
SystemQueryQuartzJobArgs args = pageArgs.getArgs(); Page<SystemQuartzJobTb> page = new Page<>(pageArgs.getPage(), pageArgs.getSize());
Page<SystemQuartzJobTb> page = new Page<>(args.getPage(), args.getSize()); return ResponseEntity.ok(systemQuartzJobService.searchQuartzJobByArgs(pageArgs.getArgs(), page));
return ResponseEntity.ok(systemQuartzJobService.searchQuartzJobByArgs(args, page));
} }
@ApiOperation("导出任务数据") @ApiOperation("导出任务数据")
@@ -87,11 +85,6 @@ public class SystemQuartzJobController {
@PostMapping(value = "/createQuartzJob") @PostMapping(value = "/createQuartzJob")
@PreAuthorize("@el.check('quartzJob:add')") @PreAuthorize("@el.check('quartzJob:add')")
public ResponseEntity<Void> createQuartzJob(@Validated @RequestBody SystemQuartzJobTb args) { public ResponseEntity<Void> createQuartzJob(@Validated @RequestBody SystemQuartzJobTb args) {
if (args.getId() != null) {
throw new BadRequestException("无效参数id");
}
// 验证Bean是不是合法的, 合法的定时任务 Bean 需要用 @Service 定义
checkBean(args.getBeanName());
systemQuartzJobService.createJob(args); systemQuartzJobService.createJob(args);
return ResponseEntity.ok(null); return ResponseEntity.ok(null);
} }
@@ -101,8 +94,6 @@ public class SystemQuartzJobController {
@PreAuthorize("@el.check('quartzJob:edit')") @PreAuthorize("@el.check('quartzJob:edit')")
public ResponseEntity<Void> updateQuartzJob( public ResponseEntity<Void> updateQuartzJob(
@Validated(SystemQuartzJobTb.Update.class) @RequestBody SystemUpdateQuartzJobArgs args) { @Validated(SystemQuartzJobTb.Update.class) @RequestBody SystemUpdateQuartzJobArgs args) {
// 验证Bean是不是合法的, 合法的定时任务 Bean 需要用 @Service 定义
checkBean(args.getBeanName());
systemQuartzJobService.updateQuartzJobResumeCron(args); systemQuartzJobService.updateQuartzJobResumeCron(args);
return ResponseEntity.ok(null); return ResponseEntity.ok(null);
} }
@@ -130,17 +121,4 @@ public class SystemQuartzJobController {
systemQuartzJobService.deleteJobByIds(ids); systemQuartzJobService.deleteJobByIds(ids);
return ResponseEntity.ok(null); return ResponseEntity.ok(null);
} }
/**
* 验证Bean是不是合法的, 合法的定时任务 Bean 需要用 @Service 定义
*
* @param beanName Bean名称
*/
private void checkBean(String beanName) {
// 避免调用攻击者可以从SpringContextHolder获得控制jdbcTemplate类
// 并使用getDeclaredMethod调用jdbcTemplate的queryForMap函数,执行任意sql命令。
if (!KitSpringBeanHolder.getAllServiceBeanName().contains(beanName)) {
throw new BadRequestException("非法的 Bean,请重新输入!");
}
}
} }
@@ -18,22 +18,18 @@ package cn.odboy.system.controller;
import cn.hutool.core.lang.Dict; import cn.hutool.core.lang.Dict;
import cn.odboy.base.KitPageArgs; import cn.odboy.base.KitPageArgs;
import cn.odboy.base.KitPageResult; import cn.odboy.base.KitPageResult;
import cn.odboy.framework.exception.BadRequestException;
import cn.odboy.system.dal.dataobject.SystemRoleTb; import cn.odboy.system.dal.dataobject.SystemRoleTb;
import cn.odboy.system.dal.model.SystemCreateRoleArgs; import cn.odboy.system.dal.model.SystemCreateRoleArgs;
import cn.odboy.system.dal.model.SystemQueryRoleArgs; import cn.odboy.system.dal.model.SystemQueryRoleArgs;
import cn.odboy.system.dal.model.SystemRoleVo; import cn.odboy.system.dal.model.SystemRoleVo;
import cn.odboy.system.framework.permission.core.KitSecurityHelper;
import cn.odboy.system.service.SystemRoleService; import cn.odboy.system.service.SystemRoleService;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
@@ -49,12 +45,13 @@ import org.springframework.web.bind.annotation.RestController;
@RequestMapping("/api/role") @RequestMapping("/api/role")
public class SystemRoleController { public class SystemRoleController {
@Autowired private SystemRoleService systemRoleService; @Autowired
private SystemRoleService systemRoleService;
@ApiOperation("获取单个role") @ApiOperation("获取单个role")
@PostMapping(value = "/queryRoleById") @PostMapping(value = "/queryRoleById")
@PreAuthorize("@el.check('roles:list')") @PreAuthorize("@el.check('roles:list')")
public ResponseEntity<SystemRoleTb> queryRoleById(@RequestBody SystemRoleTb args) { public ResponseEntity<SystemRoleVo> queryRoleById(@RequestBody SystemRoleTb args) {
return ResponseEntity.ok(systemRoleService.getRoleById(args.getId())); return ResponseEntity.ok(systemRoleService.getRoleById(args.getId()));
} }
@@ -77,22 +74,20 @@ public class SystemRoleController {
@PreAuthorize("@el.check('roles:list')") @PreAuthorize("@el.check('roles:list')")
public ResponseEntity<KitPageResult<SystemRoleVo>> queryRoleByArgs( public ResponseEntity<KitPageResult<SystemRoleVo>> queryRoleByArgs(
@Validated @RequestBody KitPageArgs<SystemQueryRoleArgs> pageArgs) { @Validated @RequestBody KitPageArgs<SystemQueryRoleArgs> pageArgs) {
SystemQueryRoleArgs args = pageArgs.getArgs(); Page<Object> page = new Page<>(pageArgs.getPage(), pageArgs.getSize());
Page<Object> page = new Page<>(args.getPage(), args.getSize()); return ResponseEntity.ok(systemRoleService.searchRoleByArgs(pageArgs.getArgs(), page));
return ResponseEntity.ok(systemRoleService.searchRoleByArgs(args, page));
} }
@ApiOperation("获取用户级别") @ApiOperation("获取用户级别")
@PostMapping(value = "/queryRoleLevel") @PostMapping(value = "/queryRoleLevel")
public ResponseEntity<Dict> queryRoleLevel() { public ResponseEntity<Dict> queryRoleLevel() {
return ResponseEntity.ok(Dict.create().set("level", checkRoleLevels(null))); return ResponseEntity.ok(systemRoleService.getRoleLevel());
} }
@ApiOperation("新增角色") @ApiOperation("新增角色")
@PostMapping(value = "/saveRole") @PostMapping(value = "/saveRole")
@PreAuthorize("@el.check('roles:add')") @PreAuthorize("@el.check('roles:add')")
public ResponseEntity<Void> saveRole(@Validated @RequestBody SystemCreateRoleArgs args) { public ResponseEntity<Void> saveRole(@Validated @RequestBody SystemCreateRoleArgs args) {
checkRoleLevels(args.getLevel());
systemRoleService.saveRole(args); systemRoleService.saveRole(args);
return ResponseEntity.ok(null); return ResponseEntity.ok(null);
} }
@@ -101,7 +96,6 @@ public class SystemRoleController {
@PostMapping(value = "/modifyRoleById") @PostMapping(value = "/modifyRoleById")
@PreAuthorize("@el.check('roles:edit')") @PreAuthorize("@el.check('roles:edit')")
public ResponseEntity<Void> modifyRoleById(@Validated(SystemRoleTb.Update.class) @RequestBody SystemRoleVo args) { public ResponseEntity<Void> modifyRoleById(@Validated(SystemRoleTb.Update.class) @RequestBody SystemRoleVo args) {
checkRoleLevels(args.getLevel());
systemRoleService.updateRoleById(args); systemRoleService.updateRoleById(args);
return ResponseEntity.ok(null); return ResponseEntity.ok(null);
} }
@@ -110,8 +104,6 @@ public class SystemRoleController {
@PostMapping(value = "/modifyBindMenuById") @PostMapping(value = "/modifyBindMenuById")
@PreAuthorize("@el.check('roles:edit')") @PreAuthorize("@el.check('roles:edit')")
public ResponseEntity<Void> modifyBindMenuById(@RequestBody SystemRoleVo args) { public ResponseEntity<Void> modifyBindMenuById(@RequestBody SystemRoleVo args) {
SystemRoleTb role = systemRoleService.getRoleById(args.getId());
checkRoleLevels(role.getLevel());
systemRoleService.updateBindMenuById(args); systemRoleService.updateBindMenuById(args);
return ResponseEntity.ok(null); return ResponseEntity.ok(null);
} }
@@ -120,30 +112,7 @@ public class SystemRoleController {
@PostMapping(value = "/removeRoleByIds") @PostMapping(value = "/removeRoleByIds")
@PreAuthorize("@el.check('roles:del')") @PreAuthorize("@el.check('roles:del')")
public ResponseEntity<Void> removeRoleByIds(@RequestBody Set<Long> ids) { public ResponseEntity<Void> removeRoleByIds(@RequestBody Set<Long> ids) {
for (Long id : ids) {
SystemRoleTb role = systemRoleService.getRoleById(id);
checkRoleLevels(role.getLevel());
}
// 验证是否被用户关联
systemRoleService.verifyBindRelationByIds(ids);
systemRoleService.deleteRoleByIds(ids); systemRoleService.deleteRoleByIds(ids);
return ResponseEntity.ok(null); return ResponseEntity.ok(null);
} }
/**
* 检查用户的角色级别
*
* @return /
*/
private int checkRoleLevels(Integer level) {
List<Integer> levels = systemRoleService.queryRoleByUsersId(KitSecurityHelper.getCurrentUserId()).stream()
.map(SystemRoleTb::getLevel).collect(Collectors.toList());
int min = Collections.min(levels);
if (level != null) {
if (level < min) {
throw new BadRequestException("权限不足, 你的角色级别:" + min + ", 低于操作的角色级别:" + level);
}
}
return min;
}
} }
@@ -15,15 +15,9 @@
*/ */
package cn.odboy.system.controller; package cn.odboy.system.controller;
import cn.hutool.core.collection.CollectionUtil;
import cn.odboy.base.KitPageArgs; import cn.odboy.base.KitPageArgs;
import cn.odboy.base.KitPageResult; import cn.odboy.base.KitPageResult;
import cn.odboy.base.KitSelectOptionVo; import cn.odboy.base.KitSelectOptionVo;
import cn.odboy.framework.exception.BadRequestException;
import cn.odboy.framework.properties.AppProperties;
import cn.odboy.system.constant.SystemCaptchaBizEnum;
import cn.odboy.system.dal.dataobject.SystemDeptTb;
import cn.odboy.system.dal.dataobject.SystemRoleTb;
import cn.odboy.system.dal.dataobject.SystemUserTb; import cn.odboy.system.dal.dataobject.SystemUserTb;
import cn.odboy.system.dal.model.SystemQueryUserArgs; import cn.odboy.system.dal.model.SystemQueryUserArgs;
import cn.odboy.system.dal.model.SystemUpdateUserPasswordArgs; import cn.odboy.system.dal.model.SystemUpdateUserPasswordArgs;
@@ -31,26 +25,17 @@ import cn.odboy.system.dal.model.SystemUserVo;
import cn.odboy.system.framework.permission.core.KitSecurityHelper; import cn.odboy.system.framework.permission.core.KitSecurityHelper;
import cn.odboy.system.service.SystemDataService; import cn.odboy.system.service.SystemDataService;
import cn.odboy.system.service.SystemDeptService; import cn.odboy.system.service.SystemDeptService;
import cn.odboy.system.service.SystemEmailService;
import cn.odboy.system.service.SystemRoleService;
import cn.odboy.system.service.SystemUserService; import cn.odboy.system.service.SystemUserService;
import cn.odboy.util.KitPageUtil;
import cn.odboy.util.KitRsaEncryptUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
@@ -66,13 +51,13 @@ import org.springframework.web.multipart.MultipartFile;
@RequestMapping("/api/user") @RequestMapping("/api/user")
public class SystemUserController { public class SystemUserController {
@Autowired private PasswordEncoder passwordEncoder; @Autowired
@Autowired private SystemUserService systemUserService; private SystemUserService systemUserService;
@Autowired private SystemDataService systemDataService; @Autowired
@Autowired private SystemDeptService systemDeptService; private SystemDataService systemDataService;
@Autowired private SystemRoleService systemRoleService; @Autowired
@Autowired private SystemEmailService systemEmailService; private SystemDeptService systemDeptService;
@Autowired private AppProperties properties;
@ApiOperation("导出用户数据") @ApiOperation("导出用户数据")
@GetMapping(value = "/download") @GetMapping(value = "/download")
@@ -84,42 +69,16 @@ public class SystemUserController {
@ApiOperation("查询用户") @ApiOperation("查询用户")
@PostMapping @PostMapping
@PreAuthorize("@el.check('user:list')") @PreAuthorize("@el.check('user:list')")
public ResponseEntity<KitPageResult<SystemUserVo>> queryUserByArgs( public ResponseEntity<KitPageResult<SystemUserVo>> queryUserByArgs(@Validated @RequestBody KitPageArgs<SystemQueryUserArgs> pageArgs) {
@Validated @RequestBody KitPageArgs<SystemQueryUserArgs> pageArgs) { String currentUsername = KitSecurityHelper.getCurrentUsername();
Page<SystemUserTb> page = new Page<>(pageArgs.getPage(), pageArgs.getSize()); Page<SystemUserTb> page = new Page<>(pageArgs.getPage(), pageArgs.getSize());
SystemQueryUserArgs args = pageArgs.getArgs(); return ResponseEntity.ok(systemUserService.aggregationSearchUserByArgs(page, pageArgs.getArgs(), currentUsername));
if (!ObjectUtils.isEmpty(args.getDeptId())) {
args.getDeptIds().add(args.getDeptId());
// 先查找是否存在子节点
List<SystemDeptTb> data = systemDeptService.listDeptByPid(args.getDeptId());
// 然后把子节点的ID都加入到集合中
args.getDeptIds().addAll(systemDeptService.queryChildDeptIdByDeptIds(data));
}
// 数据权限
List<Long> dataScopes = systemDataService.queryDeptIdByArgs(
systemUserService.getUserByUsername(KitSecurityHelper.getCurrentUsername()));
// args.getDeptIds() 不为空并且数据权限不为空则取交集
if (!CollectionUtils.isEmpty(args.getDeptIds()) && !CollectionUtils.isEmpty(dataScopes)) {
// 取交集
args.getDeptIds().retainAll(dataScopes);
if (!CollectionUtil.isEmpty(args.getDeptIds())) {
return ResponseEntity.ok(systemUserService.searchUserByArgs(args, page));
}
} else {
// 否则取并集
args.getDeptIds().addAll(dataScopes);
return ResponseEntity.ok(systemUserService.searchUserByArgs(args, page));
}
return ResponseEntity.ok(KitPageUtil.emptyData());
} }
@ApiOperation("新增用户") @ApiOperation("新增用户")
@PostMapping(value = "/saveUser") @PostMapping(value = "/saveUser")
@PreAuthorize("@el.check('user:add')") @PreAuthorize("@el.check('user:add')")
public ResponseEntity<Object> saveUser(@Validated @RequestBody SystemUserVo args) { public ResponseEntity<Object> saveUser(@Validated @RequestBody SystemUserVo args) {
checkLevel(args);
// 默认密码 123456
args.setPassword(passwordEncoder.encode("123456"));
systemUserService.saveUser(args); systemUserService.saveUser(args);
return ResponseEntity.ok(null); return ResponseEntity.ok(null);
} }
@@ -128,18 +87,13 @@ public class SystemUserController {
@PostMapping(value = "/modifyUserById") @PostMapping(value = "/modifyUserById")
@PreAuthorize("@el.check('user:edit')") @PreAuthorize("@el.check('user:edit')")
public ResponseEntity<Object> modifyUserById(@Validated(SystemUserTb.Update.class) @RequestBody SystemUserVo args) { public ResponseEntity<Object> modifyUserById(@Validated(SystemUserTb.Update.class) @RequestBody SystemUserVo args) {
checkLevel(args);
systemUserService.updateUserById(args); systemUserService.updateUserById(args);
return ResponseEntity.ok(null); return ResponseEntity.ok(null);
} }
@ApiOperation("修改用户:个人中心") @ApiOperation("修改用户:个人中心")
@PostMapping(value = "modifyUserCenterInfoById") @PostMapping(value = "modifyUserCenterInfoById")
public ResponseEntity<Object> modifyUserCenterInfoById( public ResponseEntity<Object> modifyUserCenterInfoById(@Validated(SystemUserTb.Update.class) @RequestBody SystemUserTb args) {
@Validated(SystemUserTb.Update.class) @RequestBody SystemUserTb args) {
if (!args.getId().equals(KitSecurityHelper.getCurrentUserId())) {
throw new BadRequestException("不能修改他人资料");
}
systemUserService.updateUserCenterInfoById(args); systemUserService.updateUserCenterInfoById(args);
return ResponseEntity.ok(null); return ResponseEntity.ok(null);
} }
@@ -148,46 +102,22 @@ public class SystemUserController {
@PostMapping(value = "/removeUserByIds") @PostMapping(value = "/removeUserByIds")
@PreAuthorize("@el.check('user:del')") @PreAuthorize("@el.check('user:del')")
public ResponseEntity<Object> removeUserByIds(@RequestBody Set<Long> ids) { public ResponseEntity<Object> removeUserByIds(@RequestBody Set<Long> ids) {
for (Long id : ids) {
Integer currentLevel = Collections.min(
systemRoleService.queryRoleByUsersId(KitSecurityHelper.getCurrentUserId()).stream()
.map(SystemRoleTb::getLevel).collect(Collectors.toList()));
Integer optLevel = Collections.min(
systemRoleService.queryRoleByUsersId(id).stream().map(SystemRoleTb::getLevel)
.collect(Collectors.toList()));
if (currentLevel > optLevel) {
throw new BadRequestException(
"角色权限不足, 不能删除:" + systemUserService.getUserById(id).getUsername());
}
}
systemUserService.removeUserByIds(ids); systemUserService.removeUserByIds(ids);
return ResponseEntity.ok(null); return ResponseEntity.ok(null);
} }
@ApiOperation("修改密码") @ApiOperation("修改密码")
@PostMapping(value = "/modifyUserPasswordByUsername") @PostMapping(value = "/modifyUserPasswordByUsername")
public ResponseEntity<Object> modifyUserPasswordByUsername(@RequestBody SystemUpdateUserPasswordArgs passVo) public ResponseEntity<Object> modifyUserPasswordByUsername(@RequestBody SystemUpdateUserPasswordArgs passVo) throws Exception {
throws Exception { String currentUsername = KitSecurityHelper.getCurrentUsername();
String oldPass = systemUserService.updateUserPasswordByUsername(currentUsername, passVo);
KitRsaEncryptUtil.decryptByPrivateKey(properties.getRsa().getPrivateKey(), passVo.getOldPass());
String newPass =
KitRsaEncryptUtil.decryptByPrivateKey(properties.getRsa().getPrivateKey(), passVo.getNewPass());
SystemUserTb user = systemUserService.getUserByUsername(KitSecurityHelper.getCurrentUsername());
if (!passwordEncoder.matches(oldPass, user.getPassword())) {
throw new BadRequestException("修改失败,旧密码错误");
}
if (passwordEncoder.matches(newPass, user.getPassword())) {
throw new BadRequestException("新密码不能与旧密码相同");
}
systemUserService.updateUserPasswordByUsername(user.getUsername(), passwordEncoder.encode(newPass));
return ResponseEntity.ok(null); return ResponseEntity.ok(null);
} }
@ApiOperation("重置密码") @ApiOperation("重置密码")
@PostMapping(value = "/resetUserPasswordByIds") @PostMapping(value = "/resetUserPasswordByIds")
public ResponseEntity<Object> resetUserPasswordByIds(@RequestBody Set<Long> ids) { public ResponseEntity<Object> resetUserPasswordByIds(@RequestBody Set<Long> ids) {
String defaultPwd = passwordEncoder.encode("123456"); systemUserService.resetUserPasswordByIds(ids);
systemUserService.resetUserPasswordByIds(ids, defaultPwd);
return ResponseEntity.ok(null); return ResponseEntity.ok(null);
} }
@@ -199,39 +129,16 @@ public class SystemUserController {
@ApiOperation("修改邮箱") @ApiOperation("修改邮箱")
@PostMapping(value = "/modifyUserEmailByUsername/{code}") @PostMapping(value = "/modifyUserEmailByUsername/{code}")
public ResponseEntity<Object> modifyUserEmailByUsername(@PathVariable String code, @RequestBody SystemUserTb args) public ResponseEntity<Object> modifyUserEmailByUsername(@PathVariable String code, @RequestBody SystemUserTb args) throws Exception {
throws Exception { String currentUsername = KitSecurityHelper.getCurrentUsername();
String password = systemUserService.updateUserEmailByUsername(currentUsername, args, code);
KitRsaEncryptUtil.decryptByPrivateKey(properties.getRsa().getPrivateKey(), args.getPassword());
SystemUserTb user = systemUserService.getUserByUsername(KitSecurityHelper.getCurrentUsername());
if (!passwordEncoder.matches(password, user.getPassword())) {
throw new BadRequestException("密码错误");
}
systemEmailService.checkEmailCaptcha(SystemCaptchaBizEnum.EMAIL_RESET_EMAIL_CODE, args.getEmail(), code);
systemUserService.updateUserEmailByUsername(user.getUsername(), args.getEmail());
return ResponseEntity.ok(null); return ResponseEntity.ok(null);
} }
/**
* 如果当前用户的角色级别低于创建用户的角色级别,则抛出权限不足的错误
*
* @param args /
*/
private void checkLevel(SystemUserVo args) {
Integer currentLevel = Collections.min(
systemRoleService.queryRoleByUsersId(KitSecurityHelper.getCurrentUserId()).stream()
.map(SystemRoleTb::getLevel).collect(Collectors.toList()));
Integer optLevel = systemRoleService.getDeptLevelByRoles(args.getRoles());
if (currentLevel > optLevel) {
throw new BadRequestException("角色权限不足");
}
}
@ApiOperation("查询用户基础数据") @ApiOperation("查询用户基础数据")
@PostMapping(value = "/queryUserMetadataOptions") @PostMapping(value = "/queryUserMetadataOptions")
@PreAuthorize("@el.check('user:list')") @PreAuthorize("@el.check('user:list')")
public ResponseEntity<List<KitSelectOptionVo>> queryUserMetadataOptions( public ResponseEntity<List<KitSelectOptionVo>> queryUserMetadataOptions(@Validated @RequestBody KitPageArgs<SystemQueryUserArgs> args) {
@Validated @RequestBody KitPageArgs<SystemQueryUserArgs> args) {
List<KitSelectOptionVo> collect = systemUserService.queryUserMetadataOptions(args); List<KitSelectOptionVo> collect = systemUserService.queryUserMetadataOptions(args);
return ResponseEntity.ok(collect); return ResponseEntity.ok(collect);
} }
@@ -30,5 +30,6 @@ import org.apache.ibatis.annotations.Param;
*/ */
@Mapper @Mapper
public interface SystemDictDetailMapper extends BaseMapper<SystemDictDetailTb> { public interface SystemDictDetailMapper extends BaseMapper<SystemDictDetailTb> {
IPage<SystemDictDetailTb> selectPageByArgs(Page<SystemDictDetailTb> page, @Param("args") SystemQueryDictDetailArgs args); IPage<SystemDictDetailTb> selectPageByArgs(Page<SystemDictDetailTb> page, @Param("args") SystemQueryDictDetailArgs args);
} }
@@ -14,7 +14,8 @@ import org.springframework.stereotype.Component;
@Component @Component
public class SystemUserInfoDAO { public class SystemUserInfoDAO {
@Autowired private KitRedisHelper redisHelper; @Autowired
private KitRedisHelper redisHelper;
/** /**
* 添加缓存到Redis * 添加缓存到Redis
@@ -13,8 +13,6 @@ import cn.odboy.util.KitFileUtil;
import cn.odboy.util.KitIPUtil; import cn.odboy.util.KitIPUtil;
import cn.odboy.util.KitPageUtil; import cn.odboy.util.KitPageUtil;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@@ -22,7 +20,10 @@ import java.util.Date;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -157,4 +158,12 @@ public class SystemUserOnlineInfoDAO {
public SystemUserOnlineVo queryUserOnlineModelByKey(String key) { public SystemUserOnlineVo queryUserOnlineModelByKey(String key) {
return redisHelper.get(key, SystemUserOnlineVo.class); return redisHelper.get(key, SystemUserOnlineVo.class);
} }
public void kickOutUser(Set<String> keys) throws Exception {
for (String token : keys) {
// 解密Key
token = KitDesEncryptUtil.desDecrypt(token);
this.logoutByToken(token);
}
}
} }
@@ -0,0 +1,117 @@
package cn.odboy.system.service;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.odboy.constant.CaptchaCodeEnum;
import cn.odboy.constant.SystemConst;
import cn.odboy.framework.exception.BadRequestException;
import cn.odboy.framework.properties.AppProperties;
import cn.odboy.framework.redis.KitRedisHelper;
import cn.odboy.system.dal.model.SystemUserInfoVo;
import cn.odboy.system.dal.model.SystemUserJwtVo;
import cn.odboy.system.dal.model.SystemUserLoginArgs;
import cn.odboy.system.dal.redis.SystemCacheKey;
import cn.odboy.system.dal.redis.SystemUserOnlineInfoDAO;
import cn.odboy.system.framework.permission.core.KitSecurityHelper;
import cn.odboy.system.framework.permission.core.handler.TokenProvider;
import cn.odboy.system.framework.permission.core.handler.UserDetailsHandler;
import cn.odboy.util.KitRsaEncryptUtil;
import com.wf.captcha.base.Captcha;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
@Service
public class SystemAuthService {
@Autowired
private KitRedisHelper redisHelper;
@Autowired
private SystemUserOnlineInfoDAO systemUserOnlineInfoDAO;
@Autowired
private TokenProvider tokenProvider;
@Autowired
private AppProperties properties;
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private UserDetailsHandler userDetailsService;
public Map<String, Object> doLogin(SystemUserLoginArgs loginRequest, HttpServletRequest request) throws Exception {
// 密码解密
String password =
KitRsaEncryptUtil.decryptByPrivateKey(properties.getRsa().getPrivateKey(), loginRequest.getPassword());
// 查询验证码
String code = redisHelper.get(loginRequest.getUuid(), String.class);
// 清除验证码
redisHelper.del(loginRequest.getUuid());
if (StrUtil.isBlank(code)) {
throw new BadRequestException("验证码不存在或已过期");
}
if (StrUtil.isBlank(loginRequest.getCode()) || !loginRequest.getCode().equalsIgnoreCase(code)) {
throw new BadRequestException("验证码错误");
}
// 获取用户信息
SystemUserJwtVo jwtUser = userDetailsService.loadUserByUsername(loginRequest.getUsername());
// 验证用户密码
if (!passwordEncoder.matches(password, jwtUser.getPassword())) {
throw new BadRequestException("登录密码错误");
}
Authentication authentication =
new UsernamePasswordAuthenticationToken(jwtUser, null, jwtUser.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication);
// 生成令牌
String token = tokenProvider.createToken(jwtUser);
// 返回 token 与 用户信息
Map<String, Object> authInfo = new HashMap<>(2) {{
put("token", String.format("%s %s", SystemConst.TOKEN_PREFIX, token));
put("user", BeanUtil.copyProperties(jwtUser, SystemUserInfoVo.class));
}};
if (properties.getLogin().isSingle()) {
// 踢掉之前已经登录的token
systemUserOnlineInfoDAO.kickOutByUsername(loginRequest.getUsername());
}
// 保存在线信息
systemUserOnlineInfoDAO.saveUserJwtModelByToken(jwtUser, token, request);
// 返回登录信息
return authInfo;
}
public SystemUserInfoVo getCurrentUserInfoVo() {
SystemUserJwtVo jwtUser = (SystemUserJwtVo) KitSecurityHelper.getCurrentUser();
return BeanUtil.copyProperties(jwtUser, SystemUserInfoVo.class);
}
public Map<String, Object> getCaptchaInfo() {
// 获取运算的结果
Captcha captcha = properties.getLogin().getCaptchaSetting().getCaptcha();
String uuid = SystemCacheKey.CAPTCHA_LOGIN + IdUtil.simpleUUID();
//当验证码类型为 arithmetic时且长度 >= 2 时, captcha.text()的结果有几率为浮点型
String captchaValue = captcha.text();
if (captcha.getCharType() - 1 == CaptchaCodeEnum.ARITHMETIC.ordinal() &&
captchaValue.contains(SystemConst.SYMBOL_DOT)) {
captchaValue = captchaValue.split("\\.")[0];
}
// 保存
redisHelper.set(uuid, captchaValue, properties.getLogin().getCaptchaSetting().getExpiration(),
TimeUnit.MINUTES);
// 验证码信息
return new HashMap<>(2) {{
put("img", captcha.toBase64());
put("uuid", uuid);
}};
}
public void doLogout(HttpServletRequest request) {
String token = tokenProvider.getToken(request);
systemUserOnlineInfoDAO.logoutByToken(token);
}
}
@@ -36,9 +36,12 @@ import org.springframework.stereotype.Service;
@Service @Service
public class SystemDataService { public class SystemDataService {
@Autowired private SystemRoleService systemRoleService; @Autowired
@Autowired private SystemDeptService systemDeptService; private SystemUserRoleService systemUserRoleService;
@Autowired private SystemRoleDeptService systemRoleDeptService; @Autowired
private SystemDeptService systemDeptService;
@Autowired
private SystemRoleDeptService systemRoleDeptService;
/** /**
* 获取数据权限 * 获取数据权限
@@ -49,7 +52,7 @@ public class SystemDataService {
public List<Long> queryDeptIdByArgs(SystemUserTb user) { public List<Long> queryDeptIdByArgs(SystemUserTb user) {
List<Long> deptIds = new ArrayList<>(); List<Long> deptIds = new ArrayList<>();
// 查询用户角色 // 查询用户角色
List<SystemRoleVo> roleList = systemRoleService.queryRoleByUsersId(user.getId()); List<SystemRoleVo> roleList = systemUserRoleService.queryRoleByUsersId(user.getId());
// 获取对应的部门ID // 获取对应的部门ID
for (SystemRoleTb role : roleList) { for (SystemRoleTb role : roleList) {
SystemDataScopeEnum dataScopeEnum = SystemDataScopeEnum.find(role.getDataScope()); SystemDataScopeEnum dataScopeEnum = SystemDataScopeEnum.find(role.getDataScope());
@@ -33,7 +33,6 @@ import cn.odboy.system.framework.permission.core.KitSecurityHelper;
import cn.odboy.util.KitClassUtil; import cn.odboy.util.KitClassUtil;
import cn.odboy.util.KitFileUtil; import cn.odboy.util.KitFileUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.ArrayList; import java.util.ArrayList;
@@ -47,6 +46,7 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@@ -54,9 +54,12 @@ import org.springframework.transaction.annotation.Transactional;
@Service @Service
public class SystemDeptService { public class SystemDeptService {
@Autowired private SystemDeptMapper systemDeptMapper; @Autowired
@Autowired private SystemUserService systemUserService; private SystemDeptMapper systemDeptMapper;
@Autowired private SystemRoleService systemRoleService; @Autowired
private SystemUserDeptService systemUserDeptService;
@Autowired
private SystemRoleDeptService systemRoleDeptService;
/** /**
* 创建 * 创建
@@ -92,11 +95,15 @@ public class SystemDeptService {
/** /**
* 删除 * 删除
* *
* @param deptSet / * @param ids /
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void deleteDeptByIds(Set<SystemDeptTb> deptSet) { public void deleteDeptByIds(Set<Long> ids) {
for (SystemDeptTb dept : deptSet) { // 获取部门, 和其所有子部门
Set<SystemDeptTb> depts = this.traverseDeptByIdWithPids(ids);
// 验证是否被角色或用户关联
this.verifyBindRelationByIds(depts);
for (SystemDeptTb dept : depts) {
systemDeptMapper.deleteById(dept.getId()); systemDeptMapper.deleteById(dept.getId());
this.updateDeptSubCnt(dept.getPid()); this.updateDeptSubCnt(dept.getPid());
} }
@@ -165,7 +172,8 @@ public class SystemDeptService {
wrapper.eq(args.getPid() != null, SystemDeptTb::getPid, args.getPid()); wrapper.eq(args.getPid() != null, SystemDeptTb::getPid, args.getPid());
wrapper.isNull(args.getPidIsNull() != null, SystemDeptTb::getPid); wrapper.isNull(args.getPidIsNull() != null, SystemDeptTb::getPid);
if (CollUtil.isNotEmpty(args.getCreateTime()) && args.getCreateTime().size() >= 2) { if (CollUtil.isNotEmpty(args.getCreateTime()) && args.getCreateTime().size() >= 2) {
wrapper.between(SystemDeptTb::getCreateTime, args.getCreateTime().get(0), args.getCreateTime().get(1)); wrapper.between(SystemDeptTb::getCreateTime, args.getCreateTime().get(0),
args.getCreateTime().get(1));
} }
} }
wrapper.orderByAsc(SystemDeptTb::getDeptSort); wrapper.orderByAsc(SystemDeptTb::getDeptSort);
@@ -343,10 +351,10 @@ public class SystemDeptService {
*/ */
public void verifyBindRelationByIds(Set<SystemDeptTb> deptSet) { public void verifyBindRelationByIds(Set<SystemDeptTb> deptSet) {
Set<Long> deptIds = deptSet.stream().map(SystemDeptTb::getId).collect(Collectors.toSet()); Set<Long> deptIds = deptSet.stream().map(SystemDeptTb::getId).collect(Collectors.toSet());
if (systemUserService.countUserByDeptIds(deptIds) > 0) { if (systemUserDeptService.countUserByDeptIds(deptIds) > 0) {
throw new BadRequestException("所选部门存在用户关联,请解除后再试!"); throw new BadRequestException("所选部门存在用户关联,请解除后再试!");
} }
if (systemRoleService.countRoleByDeptIds(deptIds) > 0) { if (systemRoleDeptService.countRoleByDeptIds(deptIds) > 0) {
throw new BadRequestException("所选部门存在角色关联,请解除后再试!"); throw new BadRequestException("所选部门存在角色关联,请解除后再试!");
} }
} }
@@ -31,6 +31,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@@ -134,4 +135,13 @@ public class SystemDictDetailService {
return detailVo; return detailVo;
}).collect(Collectors.toList()); }).collect(Collectors.toList());
} }
public Map<String, List<SystemDictDetailVo>> getDictDetailMap(String dictName) {
String[] names = dictName.split("[,, ]");
Map<String, List<SystemDictDetailVo>> dictMap = new HashMap<>(16);
for (String name : names) {
dictMap.put(name, this.listDictDetailByName(name));
}
return dictMap;
}
} }
@@ -29,13 +29,13 @@ import cn.odboy.util.KitFileUtil;
import cn.odboy.util.KitPageUtil; import cn.odboy.util.KitPageUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@@ -43,8 +43,10 @@ import org.springframework.transaction.annotation.Transactional;
@Service @Service
public class SystemDictService { public class SystemDictService {
@Autowired private SystemDictMapper systemDictMapper; @Autowired
@Autowired private SystemDictDetailService systemDictDetailService; private SystemDictMapper systemDictMapper;
@Autowired
private SystemDictDetailService systemDictDetailService;
/** /**
* 创建 * 创建
@@ -24,6 +24,7 @@ import cn.odboy.framework.properties.AppProperties;
import cn.odboy.framework.redis.KitRedisHelper; import cn.odboy.framework.redis.KitRedisHelper;
import cn.odboy.system.constant.SystemCaptchaBizEnum; import cn.odboy.system.constant.SystemCaptchaBizEnum;
import cn.odboy.system.dal.dataobject.SystemEmailConfigTb; import cn.odboy.system.dal.dataobject.SystemEmailConfigTb;
import cn.odboy.system.dal.model.SystemCheckEmailCaptchaArgs;
import cn.odboy.system.dal.model.SystemSendEmailArgs; import cn.odboy.system.dal.model.SystemSendEmailArgs;
import cn.odboy.system.dal.mysql.SystemEmailConfigMapper; import cn.odboy.system.dal.mysql.SystemEmailConfigMapper;
import cn.odboy.util.KitDesEncryptUtil; import cn.odboy.util.KitDesEncryptUtil;
@@ -39,10 +40,14 @@ import org.springframework.transaction.annotation.Transactional;
@Service @Service
public class SystemEmailService { public class SystemEmailService {
@Autowired private SystemEmailConfigMapper systemEmailConfigMapper; @Autowired
@Autowired private KitRedisHelper redisHelper; private SystemEmailConfigMapper systemEmailConfigMapper;
@Autowired private AppProperties properties; @Autowired
@Value("${spring.application.title}") private String applicationTitle; private KitRedisHelper redisHelper;
@Autowired
private AppProperties properties;
@Value("${spring.application.title}")
private String applicationTitle;
/** /**
* 更新邮件配置 * 更新邮件配置
@@ -108,7 +113,7 @@ public class SystemEmailService {
/** /**
* 校验邮箱验证码 * 校验邮箱验证码
*/ */
public void checkEmailCaptcha(SystemCaptchaBizEnum biEnum, String email, String code) { public void checkEmailCaptchaV1(SystemCaptchaBizEnum biEnum, String email, String code) {
String redisKey = biEnum.getRedisKey() + email; String redisKey = biEnum.getRedisKey() + email;
String value = redisHelper.get(redisKey, String.class); String value = redisHelper.get(redisKey, String.class);
if (value == null || !value.equals(code)) { if (value == null || !value.equals(code)) {
@@ -149,4 +154,12 @@ public class SystemEmailService {
SystemEmailConfigTb systemEmailConfigTb = systemEmailConfigMapper.selectById(1L); SystemEmailConfigTb systemEmailConfigTb = systemEmailConfigMapper.selectById(1L);
return systemEmailConfigTb == null ? new SystemEmailConfigTb() : systemEmailConfigTb; return systemEmailConfigTb == null ? new SystemEmailConfigTb() : systemEmailConfigTb;
} }
public void checkEmailCaptcha(SystemCheckEmailCaptchaArgs args) {
SystemCaptchaBizEnum biEnum = SystemCaptchaBizEnum.getByBizCode(args.getBizCode());
if (biEnum == null) {
throw new BadRequestException("不支持的业务");
}
this.checkEmailCaptchaV1(biEnum, args.getEmail(), args.getCode());
}
} }
@@ -28,13 +28,13 @@ import cn.odboy.util.KitFileUtil;
import cn.odboy.util.KitPageUtil; import cn.odboy.util.KitPageUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@@ -42,8 +42,10 @@ import org.springframework.transaction.annotation.Transactional;
@Service @Service
public class SystemJobService { public class SystemJobService {
@Autowired private SystemJobMapper systemJobMapper; @Autowired
@Autowired private SystemUserService systemUserService; private SystemJobMapper systemJobMapper;
@Autowired
private SystemUserService systemUserService;
/** /**
* 创建 * 创建
@@ -82,6 +84,8 @@ public class SystemJobService {
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void deleteJobByIds(Set<Long> ids) { public void deleteJobByIds(Set<Long> ids) {
// 验证是否被用户关联
this.verifyBindRelationByIds(ids);
systemJobMapper.deleteByIds(ids); systemJobMapper.deleteByIds(ids);
} }
@@ -147,7 +151,8 @@ public class SystemJobService {
wrapper.like(StrUtil.isNotBlank(args.getName()), SystemJobTb::getName, args.getName()); wrapper.like(StrUtil.isNotBlank(args.getName()), SystemJobTb::getName, args.getName());
wrapper.eq(args.getEnabled() != null, SystemJobTb::getEnabled, args.getEnabled()); wrapper.eq(args.getEnabled() != null, SystemJobTb::getEnabled, args.getEnabled());
if (CollUtil.isNotEmpty(args.getCreateTime()) && args.getCreateTime().size() >= 2) { if (CollUtil.isNotEmpty(args.getCreateTime()) && args.getCreateTime().size() >= 2) {
wrapper.between(SystemJobTb::getCreateTime, args.getCreateTime().get(0), args.getCreateTime().get(1)); wrapper.between(SystemJobTb::getCreateTime, args.getCreateTime().get(0),
args.getCreateTime().get(1));
} }
} }
wrapper.orderByDesc(SystemJobTb::getJobSort, SystemJobTb::getId); wrapper.orderByDesc(SystemJobTb::getJobSort, SystemJobTb::getId);
@@ -21,6 +21,8 @@ import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.IORuntimeException; import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.odboy.base.KitPageResult; import cn.odboy.base.KitPageResult;
import cn.odboy.constant.FileTypeEnum;
import cn.odboy.framework.context.KitSpringBeanHolder;
import cn.odboy.framework.exception.BadRequestException; import cn.odboy.framework.exception.BadRequestException;
import cn.odboy.framework.properties.AppProperties; import cn.odboy.framework.properties.AppProperties;
import cn.odboy.framework.server.core.KitFileLocalUploadHelper; import cn.odboy.framework.server.core.KitFileLocalUploadHelper;
@@ -31,7 +33,6 @@ import cn.odboy.util.KitFileUtil;
import cn.odboy.util.KitPageUtil; import cn.odboy.util.KitPageUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.servlet.http.HttpServletResponse;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
@@ -39,6 +40,7 @@ import java.util.Date;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@@ -47,9 +49,12 @@ import org.springframework.web.multipart.MultipartFile;
@Service @Service
public class SystemLocalStorageService { public class SystemLocalStorageService {
@Autowired private SystemLocalStorageMapper systemLocalStorageMapper; @Autowired
@Autowired private KitFileLocalUploadHelper fileUploadPathHelper; private SystemLocalStorageMapper systemLocalStorageMapper;
@Autowired private AppProperties properties; @Autowired
private KitFileLocalUploadHelper fileUploadPathHelper;
@Autowired
private AppProperties properties;
/** /**
* 上传 * 上传
@@ -177,4 +182,14 @@ public class SystemLocalStorageService {
this.injectQueryParams(args, wrapper); this.injectQueryParams(args, wrapper);
return systemLocalStorageMapper.selectList(wrapper); return systemLocalStorageMapper.selectList(wrapper);
} }
public SystemLocalStorageTb uploadPictureV1(MultipartFile file) {
// 判断文件是否为图片
String suffix = KitFileUtil.getSuffix(file.getOriginalFilename());
if (!FileTypeEnum.IMAGE.getCode().equals(KitFileUtil.getFileType(suffix))) {
throw new BadRequestException("只能上传图片");
}
return KitSpringBeanHolder.getBean(SystemLocalStorageService.class).uploadFile(null, file);
}
} }
@@ -31,22 +31,24 @@ import cn.odboy.system.dal.model.SystemQueryMenuArgs;
import cn.odboy.system.dal.model.SystemRoleVo; import cn.odboy.system.dal.model.SystemRoleVo;
import cn.odboy.system.dal.mysql.SystemMenuMapper; import cn.odboy.system.dal.mysql.SystemMenuMapper;
import cn.odboy.system.dal.mysql.SystemRoleMenuMapper; import cn.odboy.system.dal.mysql.SystemRoleMenuMapper;
import cn.odboy.system.framework.permission.core.KitSecurityHelper;
import cn.odboy.util.KitClassUtil; import cn.odboy.util.KitClassUtil;
import cn.odboy.util.KitFileUtil; import cn.odboy.util.KitFileUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@@ -56,10 +58,16 @@ public class SystemMenuService {
private static final String YES_STR = "是"; private static final String YES_STR = "是";
private static final String NO_STR = "否"; private static final String NO_STR = "否";
@Autowired private SystemMenuMapper systemMenuMapper; @Autowired
@Autowired private SystemRoleMenuMapper systemRoleMenuMapper; private SystemMenuMapper systemMenuMapper;
@Autowired private SystemRoleService systemRoleService; @Autowired
@Autowired private SystemRoleMenuService systemRoleMenuService; private SystemRoleMenuMapper systemRoleMenuMapper;
@Autowired
private SystemRoleService systemRoleService;
@Autowired
private SystemRoleMenuService systemRoleMenuService;
@Autowired
private SystemUserRoleService systemUserRoleService;
/** /**
* 创建 * 创建
@@ -247,7 +255,7 @@ public class SystemMenuService {
* @return / * @return /
*/ */
public List<SystemMenuTb> listMenuByUserId(Long currentUserId) { public List<SystemMenuTb> listMenuByUserId(Long currentUserId) {
List<SystemRoleVo> roles = systemRoleService.queryRoleByUsersId(currentUserId); List<SystemRoleVo> roles = systemUserRoleService.queryRoleByUsersId(currentUserId);
Set<Long> roleIds = roles.stream().map(SystemRoleTb::getId).collect(Collectors.toSet()); Set<Long> roleIds = roles.stream().map(SystemRoleTb::getId).collect(Collectors.toSet());
return new ArrayList<>(systemRoleMenuService.queryMenuByRoleIds(roleIds)); return new ArrayList<>(systemRoleMenuService.queryMenuByRoleIds(roleIds));
} }
@@ -431,11 +439,13 @@ public class SystemMenuService {
if (args != null) { if (args != null) {
wrapper.isNull(args.getPidIsNull() != null, SystemMenuTb::getPid); wrapper.isNull(args.getPidIsNull() != null, SystemMenuTb::getPid);
wrapper.eq(args.getPid() != null, SystemMenuTb::getPid, args.getPid()); wrapper.eq(args.getPid() != null, SystemMenuTb::getPid, args.getPid());
wrapper.and(StrUtil.isNotBlank(args.getBlurry()), c -> c.like(SystemMenuTb::getTitle, args.getBlurry()).or() wrapper.and(StrUtil.isNotBlank(args.getBlurry()),
c -> c.like(SystemMenuTb::getTitle, args.getBlurry()).or()
.like(SystemMenuTb::getComponentName, args.getBlurry()).or() .like(SystemMenuTb::getComponentName, args.getBlurry()).or()
.like(SystemMenuTb::getPermission, args.getBlurry())); .like(SystemMenuTb::getPermission, args.getBlurry()));
if (CollUtil.isNotEmpty(args.getCreateTime()) && args.getCreateTime().size() >= 2) { if (CollUtil.isNotEmpty(args.getCreateTime()) && args.getCreateTime().size() >= 2) {
wrapper.between(SystemMenuTb::getCreateTime, args.getCreateTime().get(0), args.getCreateTime().get(1)); wrapper.between(SystemMenuTb::getCreateTime, args.getCreateTime().get(0),
args.getCreateTime().get(1));
} }
} }
wrapper.orderByAsc(SystemMenuTb::getMenuSort); wrapper.orderByAsc(SystemMenuTb::getMenuSort);
@@ -448,4 +458,41 @@ public class SystemMenuService {
wrapper.orderByAsc(SystemMenuTb::getMenuSort); wrapper.orderByAsc(SystemMenuTb::getMenuSort);
return systemMenuMapper.selectList(wrapper); return systemMenuMapper.selectList(wrapper);
} }
public List<SystemMenuVo> buildFrontMenus() {
List<SystemMenuTb> menuList = this.listMenuByUserId(KitSecurityHelper.getCurrentUserId());
List<SystemMenuTb> menus = this.buildMenuTree(menuList);
return this.buildMenuVo(menus);
}
public Set<Long> listChildMenuSetByMenuId(Long id) {
Set<SystemMenuTb> menuSet = new HashSet<>();
List<SystemMenuTb> menuList = this.listMenuByPid(id);
menuSet.add(systemMenuMapper.selectById(id));
menuSet = this.queryChildMenuByArgs(menuList, menuSet);
return menuSet.stream().map(SystemMenuTb::getId).collect(Collectors.toSet());
}
public List<SystemMenuTb> listMenuSuperior(List<Long> ids) {
Set<SystemMenuTb> menus;
List<SystemMenuTb> systemMenuTbs;
if (CollectionUtil.isNotEmpty(ids)) {
menus = new LinkedHashSet<>(this.listMenuByIds(ids));
for (SystemMenuTb menu : menus) {
List<SystemMenuTb> menuList = this.querySuperiorMenuByArgs(menu, new ArrayList<>());
for (SystemMenuTb data : menuList) {
if (data.getId().equals(menu.getPid())) {
data.setSubCount(data.getSubCount() - 1);
}
}
menus.addAll(menuList);
}
// 编辑菜单时不显示自己以及自己下级的数据, 避免出现PID数据环形问题
menus = menus.stream().filter(i -> !ids.contains(i.getId())).collect(Collectors.toSet());
systemMenuTbs = this.buildMenuTree(new ArrayList<>(menus));
} else {
systemMenuTbs = this.listMenuByPid(null);
}
return systemMenuTbs;
}
} }
@@ -101,7 +101,7 @@ public class SystemMonitorService {
diskInfo.put("available", KitFileUtil.getSize(available)); diskInfo.put("available", KitFileUtil.getSize(available));
diskInfo.put("used", KitFileUtil.getSize(used)); diskInfo.put("used", KitFileUtil.getSize(used));
if (total != 0) { if (total != 0) {
diskInfo.put("usageRate", df.format(used / (double)total * 100)); diskInfo.put("usageRate", df.format(used / (double) total * 100));
} else { } else {
diskInfo.put("usageRate", 0); diskInfo.put("usageRate", 0);
} }
@@ -125,7 +125,7 @@ public class SystemMonitorService {
if (used == 0) { if (used == 0) {
swapInfo.put("usageRate", 0); swapInfo.put("usageRate", 0);
} else { } else {
swapInfo.put("usageRate", df.format(used / (double)total * 100)); swapInfo.put("usageRate", df.format(used / (double) total * 100));
} }
return swapInfo; return swapInfo;
} }
@@ -142,7 +142,7 @@ public class SystemMonitorService {
memoryInfo.put("available", FormatUtil.formatBytes(memory.getAvailable())); memoryInfo.put("available", FormatUtil.formatBytes(memory.getAvailable()));
memoryInfo.put("used", FormatUtil.formatBytes(memory.getTotal() - memory.getAvailable())); memoryInfo.put("used", FormatUtil.formatBytes(memory.getTotal() - memory.getAvailable()));
memoryInfo.put("usageRate", memoryInfo.put("usageRate",
df.format((memory.getTotal() - memory.getAvailable()) / (double)memory.getTotal() * 100)); df.format((memory.getTotal() - memory.getAvailable()) / (double) memory.getTotal() * 100));
return memoryInfo; return memoryInfo;
} }
@@ -21,9 +21,9 @@ import cn.odboy.system.dal.model.SystemOssStorageVo;
import cn.odboy.system.dal.model.SystemQueryStorageArgs; import cn.odboy.system.dal.model.SystemQueryStorageArgs;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
/** /**
@@ -20,6 +20,7 @@ import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.odboy.base.KitPageResult; import cn.odboy.base.KitPageResult;
import cn.odboy.framework.context.KitSpringBeanHolder;
import cn.odboy.framework.exception.BadRequestException; import cn.odboy.framework.exception.BadRequestException;
import cn.odboy.framework.redis.KitRedisHelper; import cn.odboy.framework.redis.KitRedisHelper;
import cn.odboy.system.dal.dataobject.SystemQuartzJobTb; import cn.odboy.system.dal.dataobject.SystemQuartzJobTb;
@@ -33,7 +34,6 @@ import cn.odboy.util.KitFileUtil;
import cn.odboy.util.KitPageUtil; import cn.odboy.util.KitPageUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@@ -41,6 +41,7 @@ import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import jakarta.servlet.http.HttpServletResponse;
import org.quartz.CronExpression; import org.quartz.CronExpression;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@@ -49,10 +50,27 @@ import org.springframework.transaction.annotation.Transactional;
@Service @Service
public class SystemQuartzJobService { public class SystemQuartzJobService {
@Autowired private SystemQuartzJobMapper systemQuartzJobMapper; @Autowired
@Autowired private SystemQuartzLogMapper systemQuartzLogMapper; private SystemQuartzJobMapper systemQuartzJobMapper;
@Autowired private QuartzManage quartzManage; @Autowired
@Autowired private KitRedisHelper redisHelper; private SystemQuartzLogMapper systemQuartzLogMapper;
@Autowired
private QuartzManage quartzManage;
@Autowired
private KitRedisHelper redisHelper;
/**
* 验证Bean是不是合法的, 合法的定时任务 Bean 需要用 @Service 定义
*
* @param beanName Bean名称
*/
private void checkBean(String beanName) {
// 避免调用攻击者可以从SpringContextHolder获得控制jdbcTemplate类
// 并使用getDeclaredMethod调用jdbcTemplate的queryForMap函数,执行任意sql命令。
if (!KitSpringBeanHolder.getAllServiceBeanName().contains(beanName)) {
throw new BadRequestException("非法的 Bean,请重新输入!");
}
}
/** /**
* 创建 * 创建
@@ -61,6 +79,11 @@ public class SystemQuartzJobService {
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void createJob(SystemQuartzJobTb args) { public void createJob(SystemQuartzJobTb args) {
if (args.getId() != null) {
throw new BadRequestException("无效参数id");
}
// 验证Bean是不是合法的, 合法的定时任务 Bean 需要用 @Service 定义
checkBean(args.getBeanName());
if (!CronExpression.isValidExpression(args.getCronExpression())) { if (!CronExpression.isValidExpression(args.getCronExpression())) {
throw new BadRequestException("cron表达式格式错误"); throw new BadRequestException("cron表达式格式错误");
} }
@@ -75,6 +98,8 @@ public class SystemQuartzJobService {
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void updateQuartzJobResumeCron(SystemUpdateQuartzJobArgs args) { public void updateQuartzJobResumeCron(SystemUpdateQuartzJobArgs args) {
// 验证Bean是不是合法的, 合法的定时任务 Bean 需要用 @Service 定义
checkBean(args.getBeanName());
if (!CronExpression.isValidExpression(args.getCronExpression())) { if (!CronExpression.isValidExpression(args.getCronExpression())) {
throw new BadRequestException("cron表达式格式错误"); throw new BadRequestException("cron表达式格式错误");
} }
@@ -235,7 +260,8 @@ public class SystemQuartzJobService {
private void injectQuartzJobQueryParams(SystemQueryQuartzJobArgs args, private void injectQuartzJobQueryParams(SystemQueryQuartzJobArgs args,
LambdaQueryWrapper<SystemQuartzJobTb> wrapper) { LambdaQueryWrapper<SystemQuartzJobTb> wrapper) {
if (args != null) { if (args != null) {
wrapper.like(StrUtil.isNotBlank(args.getJobName()), SystemQuartzJobTb::getJobName, args.getJobName()); wrapper.like(StrUtil.isNotBlank(args.getJobName()), SystemQuartzJobTb::getJobName,
args.getJobName());
if (CollUtil.isNotEmpty(args.getCreateTime()) && args.getCreateTime().size() >= 2) { if (CollUtil.isNotEmpty(args.getCreateTime()) && args.getCreateTime().size() >= 2) {
wrapper.between(SystemQuartzJobTb::getUpdateTime, args.getCreateTime().get(0), wrapper.between(SystemQuartzJobTb::getUpdateTime, args.getCreateTime().get(0),
args.getCreateTime().get(1)); args.getCreateTime().get(1));
@@ -247,7 +273,8 @@ public class SystemQuartzJobService {
private void injectQuartzLogQueryParams(SystemQueryQuartzJobArgs args, private void injectQuartzLogQueryParams(SystemQueryQuartzJobArgs args,
LambdaQueryWrapper<SystemQuartzLogTb> wrapper) { LambdaQueryWrapper<SystemQuartzLogTb> wrapper) {
if (args != null) { if (args != null) {
wrapper.like(StrUtil.isNotBlank(args.getJobName()), SystemQuartzLogTb::getJobName, args.getJobName()); wrapper.like(StrUtil.isNotBlank(args.getJobName()), SystemQuartzLogTb::getJobName,
args.getJobName());
wrapper.eq(args.getIsSuccess() != null, SystemQuartzLogTb::getIsSuccess, args.getIsSuccess()); wrapper.eq(args.getIsSuccess() != null, SystemQuartzLogTb::getIsSuccess, args.getIsSuccess());
if (CollUtil.isNotEmpty(args.getCreateTime()) && args.getCreateTime().size() >= 2) { if (CollUtil.isNotEmpty(args.getCreateTime()) && args.getCreateTime().size() >= 2) {
wrapper.between(SystemQuartzLogTb::getCreateTime, args.getCreateTime().get(0), wrapper.between(SystemQuartzLogTb::getCreateTime, args.getCreateTime().get(0),
@@ -32,8 +32,10 @@ import org.springframework.transaction.annotation.Transactional;
@Service @Service
public class SystemRoleDeptService { public class SystemRoleDeptService {
@Autowired private SystemRoleDeptMapper systemRoleDeptMapper; @Autowired
@Autowired private SystemDeptMapper systemDeptMapper; private SystemRoleDeptMapper systemRoleDeptMapper;
@Autowired
private SystemDeptMapper systemDeptMapper;
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void batchDeleteRoleDept(Set<Long> roleIds) { public void batchDeleteRoleDept(Set<Long> roleIds) {
@@ -74,4 +76,20 @@ public class SystemRoleDeptService {
List<Long> deptIds = systemRoleDeptTbs.stream().map(SystemRoleDeptTb::getDeptId).collect(Collectors.toList()); List<Long> deptIds = systemRoleDeptTbs.stream().map(SystemRoleDeptTb::getDeptId).collect(Collectors.toList());
return systemDeptMapper.selectByIds(deptIds); return systemDeptMapper.selectByIds(deptIds);
} }
/**
* 根据部门ID统计角色数量
*
* @param deptIds 部门ID集合
* @return /
*/
public Long countRoleByDeptIds(Set<Long> deptIds) {
if (CollUtil.isEmpty(deptIds)) {
return 0L;
}
LambdaQueryWrapper<SystemRoleDeptTb> wrapper = new LambdaQueryWrapper<>();
wrapper.in(SystemRoleDeptTb::getDeptId, deptIds);
return systemRoleDeptMapper.selectCount(wrapper);
}
} }
@@ -33,8 +33,10 @@ import org.springframework.transaction.annotation.Transactional;
@Service @Service
public class SystemRoleMenuService { public class SystemRoleMenuService {
@Autowired private SystemRoleMenuMapper systemRoleMenuMapper; @Autowired
@Autowired private SystemMenuMapper systemMenuMapper; private SystemRoleMenuMapper systemRoleMenuMapper;
@Autowired
private SystemMenuMapper systemMenuMapper;
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void deleteRoleMenuByRoleId(Long roleId) { public void deleteRoleMenuByRoleId(Long roleId) {
@@ -18,49 +18,50 @@ package cn.odboy.system.service;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.odboy.base.KitPageResult; import cn.odboy.base.KitPageResult;
import cn.odboy.framework.exception.BadRequestException; import cn.odboy.framework.exception.BadRequestException;
import cn.odboy.system.dal.dataobject.SystemDeptTb;
import cn.odboy.system.dal.dataobject.SystemMenuTb; import cn.odboy.system.dal.dataobject.SystemMenuTb;
import cn.odboy.system.dal.dataobject.SystemRoleDeptTb;
import cn.odboy.system.dal.dataobject.SystemRoleTb; import cn.odboy.system.dal.dataobject.SystemRoleTb;
import cn.odboy.system.dal.dataobject.SystemUserRoleTb;
import cn.odboy.system.dal.dataobject.SystemUserTb; import cn.odboy.system.dal.dataobject.SystemUserTb;
import cn.odboy.system.dal.model.SystemCreateRoleArgs; import cn.odboy.system.dal.model.SystemCreateRoleArgs;
import cn.odboy.system.dal.model.SystemQueryRoleArgs; import cn.odboy.system.dal.model.SystemQueryRoleArgs;
import cn.odboy.system.dal.model.SystemRoleCodeVo; import cn.odboy.system.dal.model.SystemRoleCodeVo;
import cn.odboy.system.dal.model.SystemRoleVo; import cn.odboy.system.dal.model.SystemRoleVo;
import cn.odboy.system.dal.mysql.SystemRoleDeptMapper;
import cn.odboy.system.dal.mysql.SystemRoleMapper; import cn.odboy.system.dal.mysql.SystemRoleMapper;
import cn.odboy.system.dal.mysql.SystemUserRoleMapper; import cn.odboy.system.framework.permission.core.KitSecurityHelper;
import cn.odboy.util.KitFileUtil; import cn.odboy.util.KitFileUtil;
import cn.odboy.util.KitPageUtil; import cn.odboy.util.KitPageUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@Service @Service
public class SystemRoleService { public class SystemRoleService {
@Autowired private SystemRoleMapper systemRoleMapper;
@Autowired private SystemRoleMenuService systemRoleMenuService; @Autowired
@Autowired private SystemRoleDeptService systemRoleDeptService; private SystemRoleMapper systemRoleMapper;
@Autowired private SystemRoleDeptMapper systemRoleDeptMapper; @Autowired
@Autowired private SystemUserRoleMapper systemUserRoleMapper; private SystemRoleMenuService systemRoleMenuService;
@Autowired private SystemUserService systemUserService; @Autowired
private SystemRoleDeptService systemRoleDeptService;
@Autowired
private SystemUserService systemUserService;
@Autowired
private SystemUserRoleService systemUserRoleService;
/** /**
* 创建 * 创建
@@ -69,6 +70,7 @@ public class SystemRoleService {
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void saveRole(SystemCreateRoleArgs args) { public void saveRole(SystemCreateRoleArgs args) {
checkRoleLevels(args.getLevel());
if (this.getRoleByName(args.getName()) != null) { if (this.getRoleByName(args.getName()) != null) {
throw new BadRequestException("角色名称已存在"); throw new BadRequestException("角色名称已存在");
} }
@@ -92,6 +94,7 @@ public class SystemRoleService {
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void updateRoleById(SystemRoleVo args) { public void updateRoleById(SystemRoleVo args) {
checkRoleLevels(args.getLevel());
SystemRoleVo role = BeanUtil.copyProperties(systemRoleMapper.selectById(args.getId()), SystemRoleVo.class); SystemRoleVo role = BeanUtil.copyProperties(systemRoleMapper.selectById(args.getId()), SystemRoleVo.class);
SystemRoleTb role1 = this.getRoleByName(args.getName()); SystemRoleTb role1 = this.getRoleByName(args.getName());
if (role1 != null && !role1.getId().equals(role.getId())) { if (role1 != null && !role1.getId().equals(role.getId())) {
@@ -115,14 +118,16 @@ public class SystemRoleService {
/** /**
* 修改绑定的菜单 * 修改绑定的菜单
* *
* @param role / * @param args /
*/ */
public void updateBindMenuById(SystemRoleVo role) { public void updateBindMenuById(SystemRoleVo args) {
SystemRoleTb role = systemRoleMapper.selectById(args.getId());
checkRoleLevels(role.getLevel());
// 更新菜单 // 更新菜单
systemRoleMenuService.deleteRoleMenuByRoleId(role.getId()); systemRoleMenuService.deleteRoleMenuByRoleId(role.getId());
// 判断是否为空 // 判断是否为空
if (CollUtil.isNotEmpty(role.getMenus())) { if (CollUtil.isNotEmpty(args.getMenus())) {
systemRoleMenuService.batchInsertRoleMenu(role.getMenus(), role.getId()); systemRoleMenuService.batchInsertRoleMenu(args.getMenus(), role.getId());
} }
} }
@@ -133,6 +138,13 @@ public class SystemRoleService {
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void deleteRoleByIds(Set<Long> ids) { public void deleteRoleByIds(Set<Long> ids) {
List<Integer> roleLevels = systemRoleMapper.selectByIds(ids).stream().map(SystemRoleTb::getLevel).distinct().collect(Collectors.toList());
for (Integer roleLevel : roleLevels) {
checkRoleLevels(roleLevel);
}
// 验证是否被用户关联
this.verifyBindRelationByIds(ids);
// 删除角色
systemRoleMapper.deleteByIds(ids); systemRoleMapper.deleteByIds(ids);
// 删除角色部门关联数据、角色菜单关联数据 // 删除角色部门关联数据、角色菜单关联数据
systemRoleDeptService.batchDeleteRoleDept(ids); systemRoleDeptService.batchDeleteRoleDept(ids);
@@ -144,7 +156,6 @@ public class SystemRoleService {
* *
* @param roles 待导出的数据 * @param roles 待导出的数据
* @param response / * @param response /
* @throws IOException
*/ */
public void exportRoleExcel(List<SystemRoleVo> roles, HttpServletResponse response) throws IOException { public void exportRoleExcel(List<SystemRoleVo> roles, HttpServletResponse response) throws IOException {
List<Map<String, Object>> list = new ArrayList<>(); List<Map<String, Object>> list = new ArrayList<>();
@@ -172,16 +183,18 @@ public class SystemRoleService {
* 根据条件查询全部角色 * 根据条件查询全部角色
* *
* @param args 条件 * @param args 条件
* @return * @return /
*/ */
public List<SystemRoleVo> queryRoleByArgs(SystemQueryRoleArgs args) { public List<SystemRoleVo> queryRoleByArgs(SystemQueryRoleArgs args) {
// 查询角色基本信息 // 查询角色基本信息
LambdaQueryWrapper<SystemRoleTb> wrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SystemRoleTb> wrapper = new LambdaQueryWrapper<>();
if (args != null) { if (args != null) {
wrapper.and(StrUtil.isNotBlank(args.getBlurry()), c -> c.like(SystemRoleTb::getName, args.getBlurry()).or() wrapper.and(StrUtil.isNotBlank(args.getBlurry()),
c -> c.like(SystemRoleTb::getName, args.getBlurry()).or()
.like(SystemRoleTb::getDescription, args.getBlurry())); .like(SystemRoleTb::getDescription, args.getBlurry()));
if (CollUtil.isNotEmpty(args.getCreateTime()) && args.getCreateTime().size() >= 2) { if (CollUtil.isNotEmpty(args.getCreateTime()) && args.getCreateTime().size() >= 2) {
wrapper.between(SystemRoleTb::getCreateTime, args.getCreateTime().get(0), args.getCreateTime().get(1)); wrapper.between(SystemRoleTb::getCreateTime, args.getCreateTime().get(0),
args.getCreateTime().get(1));
} }
} }
wrapper.orderByAsc(SystemRoleTb::getLevel); wrapper.orderByAsc(SystemRoleTb::getLevel);
@@ -189,10 +202,10 @@ public class SystemRoleService {
Page<SystemRoleTb> rolePage = new Page<>(args.getPage(), args.getSize()); Page<SystemRoleTb> rolePage = new Page<>(args.getPage(), args.getSize());
Page<SystemRoleTb> page = systemRoleMapper.selectPage(rolePage, wrapper); Page<SystemRoleTb> page = systemRoleMapper.selectPage(rolePage, wrapper);
List<SystemRoleTb> roles = page.getRecords(); List<SystemRoleTb> roles = page.getRecords();
return roles.stream().map(this::convertToRoleVo).collect(Collectors.toList()); return roles.stream().map(systemUserRoleService::convertToRoleVo).collect(Collectors.toList());
} else { } else {
List<SystemRoleTb> roles = systemRoleMapper.selectList(wrapper); List<SystemRoleTb> roles = systemRoleMapper.selectList(wrapper);
return roles.stream().map(this::convertToRoleVo).collect(Collectors.toList()); return roles.stream().map(systemUserRoleService::convertToRoleVo).collect(Collectors.toList());
} }
} }
@@ -201,7 +214,7 @@ public class SystemRoleService {
* *
* @param args 条件 * @param args 条件
* @param page 分页参数 * @param page 分页参数
* @return * @return /
*/ */
public KitPageResult<SystemRoleVo> searchRoleByArgs(SystemQueryRoleArgs args, Page<Object> page) { public KitPageResult<SystemRoleVo> searchRoleByArgs(SystemQueryRoleArgs args, Page<Object> page) {
args.setOffset(page.offset()); args.setOffset(page.offset());
@@ -210,41 +223,6 @@ public class SystemRoleService {
return KitPageUtil.toPage(roles, total); return KitPageUtil.toPage(roles, total);
} }
/**
* 根据用户ID查询
*
* @param userId 用户ID
* @return /
*/
public List<SystemRoleVo> queryRoleByUsersId(Long userId) {
// 查询用户角色关联
LambdaQueryWrapper<SystemUserRoleTb> userRoleWrapper = new LambdaQueryWrapper<>();
userRoleWrapper.eq(SystemUserRoleTb::getUserId, userId);
List<SystemUserRoleTb> userRoles = systemUserRoleMapper.selectList(userRoleWrapper);
if (CollUtil.isEmpty(userRoles)) {
return new ArrayList<>();
}
Set<Long> roleIds = userRoles.stream().map(SystemUserRoleTb::getRoleId).collect(Collectors.toSet());
List<SystemRoleTb> roles = systemRoleMapper.selectByIds(roleIds);
return roles.stream().map(this::convertToRoleVo).collect(Collectors.toList());
}
/**
* 根据角色查询角色级别
*
* @param roles /
* @return /
*/
public Integer getDeptLevelByRoles(Set<SystemRoleTb> roles) {
if (CollUtil.isEmpty(roles)) {
return Integer.MAX_VALUE;
}
Set<SystemRoleTb> roleSet = new HashSet<>();
for (SystemRoleTb role : roles) {
roleSet.add(getRoleById(role.getId()));
}
return Collections.min(roleSet.stream().map(SystemRoleTb::getLevel).collect(Collectors.toList()));
}
/** /**
* 获取用户权限信息 * 获取用户权限信息
@@ -259,7 +237,7 @@ public class SystemRoleService {
permissions.add("admin"); permissions.add("admin");
return permissions.stream().map(SystemRoleCodeVo::new).collect(Collectors.toList()); return permissions.stream().map(SystemRoleCodeVo::new).collect(Collectors.toList());
} }
List<SystemRoleVo> roles = this.queryRoleByUsersId(user.getId()); List<SystemRoleVo> roles = systemUserRoleService.queryRoleByUsersId(user.getId());
permissions = roles.stream().flatMap(role -> role.getMenus().stream()).map(SystemMenuTb::getPermission) permissions = roles.stream().flatMap(role -> role.getMenus().stream()).map(SystemMenuTb::getPermission)
.filter(StrUtil::isNotBlank).collect(Collectors.toSet()); .filter(StrUtil::isNotBlank).collect(Collectors.toSet());
return permissions.stream().map(SystemRoleCodeVo::new).collect(Collectors.toList()); return permissions.stream().map(SystemRoleCodeVo::new).collect(Collectors.toList());
@@ -276,64 +254,46 @@ public class SystemRoleService {
} }
} }
/**
* 根据ID查询
*
* @param id /
* @return /
*/
public SystemRoleTb getRoleById(Long id) {
return systemRoleMapper.selectById(id);
}
/**
* 根据部门ID统计角色数量
*
* @param deptIds 部门ID集合
* @return /
*/
public Long countRoleByDeptIds(Set<Long> deptIds) {
if (CollUtil.isEmpty(deptIds)) {
return 0L;
}
LambdaQueryWrapper<SystemRoleDeptTb> wrapper = new LambdaQueryWrapper<>();
wrapper.in(SystemRoleDeptTb::getDeptId, deptIds);
return systemRoleDeptMapper.selectCount(wrapper);
}
/**
* 转换为SystemRoleVo并关联查询菜单和部门信息
*
* @param role 角色基本信息
* @return 包含关联信息的SystemRoleVo
*/
private SystemRoleVo convertToRoleVo(SystemRoleTb role) {
if (role == null) {
return null;
}
SystemRoleVo roleVo = BeanUtil.copyProperties(role, SystemRoleVo.class);
// 查询关联的菜单信息
Set<SystemMenuTb> menus = systemRoleMenuService.queryMenuByRoleIds(Collections.singleton(role.getId()));
roleVo.setMenus(menus);
// 查询关联的部门信息
List<SystemDeptTb> depts = systemRoleDeptService.listDeptByRoleId(role.getId());
roleVo.setDepts(new LinkedHashSet<>(depts));
return roleVo;
}
public Long countRoleByArgs(SystemQueryRoleArgs args) { public Long countRoleByArgs(SystemQueryRoleArgs args) {
LambdaQueryWrapper<SystemRoleTb> wrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SystemRoleTb> wrapper = new LambdaQueryWrapper<>();
if (args != null) { if (args != null) {
wrapper.and(StrUtil.isNotBlank(args.getBlurry()), c -> c.like(SystemRoleTb::getName, args.getBlurry()).or() wrapper.and(StrUtil.isNotBlank(args.getBlurry()),
c -> c.like(SystemRoleTb::getName, args.getBlurry()).or()
.like(SystemRoleTb::getDescription, args.getBlurry())); .like(SystemRoleTb::getDescription, args.getBlurry()));
if (CollUtil.isNotEmpty(args.getCreateTime()) && args.getCreateTime().size() >= 2) { if (CollUtil.isNotEmpty(args.getCreateTime()) && args.getCreateTime().size() >= 2) {
wrapper.between(SystemRoleTb::getCreateTime, args.getCreateTime().get(0), args.getCreateTime().get(1)); wrapper.between(SystemRoleTb::getCreateTime, args.getCreateTime().get(0),
args.getCreateTime().get(1));
} }
} }
return systemRoleMapper.selectCount(wrapper); return systemRoleMapper.selectCount(wrapper);
} }
public SystemRoleVo getRoleById(Long id) {
SystemRoleTb roleTb = systemRoleMapper.selectById(id);
if (roleTb == null) {
return null;
}
return systemUserRoleService.convertToRoleVo(roleTb);
}
public Dict getRoleLevel() {
return Dict.create().set("level", checkRoleLevels(null));
}
/**
* 检查用户的角色级别
*
* @return /
*/
private int checkRoleLevels(Integer level) {
List<Integer> levels = systemUserRoleService.queryRoleByUsersId(KitSecurityHelper.getCurrentUserId()).stream()
.map(SystemRoleTb::getLevel).collect(Collectors.toList());
int min = Collections.min(levels);
if (level != null) {
if (level < min) {
throw new BadRequestException("权限不足, 你的角色级别:" + min + ", 低于操作的角色级别:" + level);
}
}
return min;
}
} }
@@ -0,0 +1,21 @@
package cn.odboy.system.service;
import cn.odboy.system.dal.dataobject.SystemUserTb;
import cn.odboy.system.dal.mysql.SystemUserMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class SystemUserDeptService {
@Autowired
private SystemUserMapper systemUserMapper;
public long countUserByDeptIds(Set<Long> deptIds) {
LambdaQueryWrapper<SystemUserTb> wrapper = new LambdaQueryWrapper<>();
wrapper.in(SystemUserTb::getDeptId, deptIds);
return systemUserMapper.selectCount(wrapper);
}
}
@@ -30,7 +30,8 @@ import org.springframework.transaction.annotation.Transactional;
@Service @Service
public class SystemUserJobService { public class SystemUserJobService {
@Autowired private SystemUserJobMapper systemUserJobMapper; @Autowired
private SystemUserJobMapper systemUserJobMapper;
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void batchInsertUserJob(Set<SystemJobTb> jobs, Long userId) { public void batchInsertUserJob(Set<SystemJobTb> jobs, Long userId) {
@@ -15,14 +15,26 @@
*/ */
package cn.odboy.system.service; package cn.odboy.system.service;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.odboy.framework.exception.BadRequestException;
import cn.odboy.system.dal.dataobject.SystemDeptTb;
import cn.odboy.system.dal.dataobject.SystemMenuTb;
import cn.odboy.system.dal.dataobject.SystemRoleTb; import cn.odboy.system.dal.dataobject.SystemRoleTb;
import cn.odboy.system.dal.dataobject.SystemUserRoleTb; import cn.odboy.system.dal.dataobject.SystemUserRoleTb;
import cn.odboy.system.dal.model.SystemRoleVo;
import cn.odboy.system.dal.model.SystemUserVo;
import cn.odboy.system.dal.mysql.SystemRoleMapper;
import cn.odboy.system.dal.mysql.SystemUserRoleMapper; import cn.odboy.system.dal.mysql.SystemUserRoleMapper;
import cn.odboy.system.framework.permission.core.KitSecurityHelper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@@ -30,7 +42,14 @@ import org.springframework.transaction.annotation.Transactional;
@Service @Service
public class SystemUserRoleService { public class SystemUserRoleService {
@Autowired private SystemUserRoleMapper systemUserRoleMapper; @Autowired
private SystemRoleMapper systemRoleMapper;
@Autowired
private SystemUserRoleMapper systemUserRoleMapper;
@Autowired
private SystemRoleMenuService systemRoleMenuService;
@Autowired
private SystemRoleDeptService systemRoleDeptService;
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void batchInsertUserRole(Set<SystemRoleTb> roles, Long userId) { public void batchInsertUserRole(Set<SystemRoleTb> roles, Long userId) {
@@ -54,4 +73,78 @@ public class SystemUserRoleService {
systemUserRoleMapper.delete(wrapper); systemUserRoleMapper.delete(wrapper);
} }
} }
/**
* 转换为SystemRoleVo并关联查询菜单和部门信息
*
* @param role 角色基本信息
* @return 包含关联信息的SystemRoleVo
*/
public SystemRoleVo convertToRoleVo(SystemRoleTb role) {
if (role == null) {
return null;
}
SystemRoleVo roleVo = BeanUtil.copyProperties(role, SystemRoleVo.class);
// 查询关联的菜单信息
Set<SystemMenuTb> menus = systemRoleMenuService.queryMenuByRoleIds(
Collections.singleton(role.getId()));
roleVo.setMenus(menus);
// 查询关联的部门信息
List<SystemDeptTb> depts = systemRoleDeptService.listDeptByRoleId(role.getId());
roleVo.setDepts(new LinkedHashSet<>(depts));
return roleVo;
}
/**
* 根据用户ID查询
*
* @param userId 用户ID
* @return /
*/
public List<SystemRoleVo> queryRoleByUsersId(Long userId) {
// 查询用户角色关联
LambdaQueryWrapper<SystemUserRoleTb> userRoleWrapper = new LambdaQueryWrapper<>();
userRoleWrapper.eq(SystemUserRoleTb::getUserId, userId);
List<SystemUserRoleTb> userRoles = systemUserRoleMapper.selectList(userRoleWrapper);
if (CollUtil.isEmpty(userRoles)) {
return new ArrayList<>();
}
Set<Long> roleIds = userRoles.stream().map(SystemUserRoleTb::getRoleId).collect(Collectors.toSet());
List<SystemRoleTb> roles = systemRoleMapper.selectByIds(roleIds);
return roles.stream().map(this::convertToRoleVo).collect(Collectors.toList());
}
/**
* 根据角色查询角色级别
*
* @param roles /
* @return /
*/
public Integer getDeptLevelByRoles(Set<SystemRoleTb> roles) {
if (CollUtil.isEmpty(roles)) {
return Integer.MAX_VALUE;
}
Set<SystemRoleTb> roleSet = new HashSet<>();
for (SystemRoleTb role : roles) {
roleSet.add(systemRoleMapper.selectById(role.getId()));
}
return Collections.min(roleSet.stream().map(SystemRoleTb::getLevel).collect(Collectors.toList()));
}
/**
* 如果当前用户的角色级别低于创建用户的角色级别,则抛出权限不足的错误
*
* @param args /
*/
public void checkLevel(SystemUserVo args) {
Integer currentLevel = Collections.min(
this.queryRoleByUsersId(KitSecurityHelper.getCurrentUserId()).stream()
.map(SystemRoleTb::getLevel).collect(Collectors.toList()));
Integer optLevel = this.getDeptLevelByRoles(args.getRoles());
if (currentLevel > optLevel) {
throw new BadRequestException("角色权限不足");
}
}
} }
@@ -17,12 +17,15 @@ package cn.odboy.system.service;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.odboy.base.KitPageArgs; import cn.odboy.base.KitPageArgs;
import cn.odboy.base.KitPageResult; import cn.odboy.base.KitPageResult;
import cn.odboy.base.KitSelectOptionVo; import cn.odboy.base.KitSelectOptionVo;
import cn.odboy.framework.exception.BadRequestException; import cn.odboy.framework.exception.BadRequestException;
import cn.odboy.framework.properties.AppProperties;
import cn.odboy.framework.server.core.KitFileLocalUploadHelper; import cn.odboy.framework.server.core.KitFileLocalUploadHelper;
import cn.odboy.system.constant.SystemCaptchaBizEnum;
import cn.odboy.system.dal.dataobject.SystemDeptTb; import cn.odboy.system.dal.dataobject.SystemDeptTb;
import cn.odboy.system.dal.dataobject.SystemJobTb; import cn.odboy.system.dal.dataobject.SystemJobTb;
import cn.odboy.system.dal.dataobject.SystemRoleTb; import cn.odboy.system.dal.dataobject.SystemRoleTb;
@@ -30,6 +33,7 @@ import cn.odboy.system.dal.dataobject.SystemUserJobTb;
import cn.odboy.system.dal.dataobject.SystemUserRoleTb; import cn.odboy.system.dal.dataobject.SystemUserRoleTb;
import cn.odboy.system.dal.dataobject.SystemUserTb; import cn.odboy.system.dal.dataobject.SystemUserTb;
import cn.odboy.system.dal.model.SystemQueryUserArgs; import cn.odboy.system.dal.model.SystemQueryUserArgs;
import cn.odboy.system.dal.model.SystemUpdateUserPasswordArgs;
import cn.odboy.system.dal.model.SystemUserVo; import cn.odboy.system.dal.model.SystemUserVo;
import cn.odboy.system.dal.mysql.SystemDeptMapper; import cn.odboy.system.dal.mysql.SystemDeptMapper;
import cn.odboy.system.dal.mysql.SystemJobMapper; import cn.odboy.system.dal.mysql.SystemJobMapper;
@@ -42,10 +46,10 @@ import cn.odboy.system.dal.redis.SystemUserOnlineInfoDAO;
import cn.odboy.system.framework.permission.core.KitSecurityHelper; import cn.odboy.system.framework.permission.core.KitSecurityHelper;
import cn.odboy.util.KitFileUtil; import cn.odboy.util.KitFileUtil;
import cn.odboy.util.KitPageUtil; import cn.odboy.util.KitPageUtil;
import cn.odboy.util.KitRsaEncryptUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.servlet.http.HttpServletResponse;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
@@ -58,9 +62,13 @@ import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
@Service @Service
@@ -69,10 +77,22 @@ public class SystemUserService {
@Autowired @Autowired
private SystemUserMapper systemUserMapper; private SystemUserMapper systemUserMapper;
@Autowired @Autowired
private SystemJobMapper systemJobMapper;
@Autowired
private SystemRoleMapper systemRoleMapper;
@Autowired
private SystemDeptMapper systemDeptMapper;
@Autowired
private SystemUserJobService systemUserJobService; private SystemUserJobService systemUserJobService;
@Autowired @Autowired
private SystemUserRoleService systemUserRoleService; private SystemUserRoleService systemUserRoleService;
@Autowired @Autowired
private SystemEmailService systemEmailService;
@Autowired
private SystemDeptService systemDeptService;
@Autowired
private SystemDataService systemDataService;
@Autowired
private SystemUserInfoDAO systemUserInfoDAO; private SystemUserInfoDAO systemUserInfoDAO;
@Autowired @Autowired
private SystemUserOnlineInfoDAO systemUserOnlineInfoDAO; private SystemUserOnlineInfoDAO systemUserOnlineInfoDAO;
@@ -83,11 +103,10 @@ public class SystemUserService {
@Autowired @Autowired
private SystemUserRoleMapper systemUserRoleMapper; private SystemUserRoleMapper systemUserRoleMapper;
@Autowired @Autowired
private SystemJobMapper systemJobMapper; private AppProperties properties;
@Autowired @Autowired
private SystemRoleMapper systemRoleMapper; private PasswordEncoder passwordEncoder;
@Autowired
private SystemDeptMapper systemDeptMapper;
/** /**
* 新增用户 * 新增用户
@@ -96,6 +115,9 @@ public class SystemUserService {
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void saveUser(SystemUserVo args) { public void saveUser(SystemUserVo args) {
systemUserRoleService.checkLevel(args);
// 默认密码 123456
args.setPassword(passwordEncoder.encode("123456"));
args.setDeptId(args.getDept().getId()); args.setDeptId(args.getDept().getId());
if (this.getUserByUsername(args.getUsername()) != null) { if (this.getUserByUsername(args.getUsername()) != null) {
throw new BadRequestException("用户名已存在"); throw new BadRequestException("用户名已存在");
@@ -106,6 +128,7 @@ public class SystemUserService {
if (this.getUserByPhone(args.getPhone()) != null) { if (this.getUserByPhone(args.getPhone()) != null) {
throw new BadRequestException("手机号已存在"); throw new BadRequestException("手机号已存在");
} }
// 保存用户
systemUserMapper.insert(args); systemUserMapper.insert(args);
// 保存用户岗位 // 保存用户岗位
systemUserJobService.batchInsertUserJob(args.getJobs(), args.getId()); systemUserJobService.batchInsertUserJob(args.getJobs(), args.getId());
@@ -120,6 +143,7 @@ public class SystemUserService {
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void updateUserById(SystemUserVo args) { public void updateUserById(SystemUserVo args) {
systemUserRoleService.checkLevel(args);
SystemUserTb user = systemUserMapper.selectById(args.getId()); SystemUserTb user = systemUserMapper.selectById(args.getId());
SystemUserTb user1 = this.getUserByUsername(args.getUsername()); SystemUserTb user1 = this.getUserByUsername(args.getUsername());
SystemUserTb user2 = this.getUserByEmail(args.getEmail()); SystemUserTb user2 = this.getUserByEmail(args.getEmail());
@@ -163,6 +187,9 @@ public class SystemUserService {
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void updateUserCenterInfoById(SystemUserTb args) { public void updateUserCenterInfoById(SystemUserTb args) {
if (!args.getId().equals(KitSecurityHelper.getCurrentUserId())) {
throw new BadRequestException("不能修改他人资料");
}
SystemUserTb user = systemUserMapper.selectById(args.getId()); SystemUserTb user = systemUserMapper.selectById(args.getId());
SystemUserTb user1 = this.getUserByPhone(args.getPhone()); SystemUserTb user1 = this.getUserByPhone(args.getPhone());
if (user1 != null && !user.getId().equals(user1.getId())) { if (user1 != null && !user.getId().equals(user1.getId())) {
@@ -182,11 +209,26 @@ public class SystemUserService {
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void removeUserByIds(Set<Long> ids) { public void removeUserByIds(Set<Long> ids) {
Long currentUserId = KitSecurityHelper.getCurrentUserId();
// 校验权限
for (Long id : ids) { for (Long id : ids) {
// 清理缓存 Integer currentLevel = Collections.min(
SystemUserTb user = systemUserMapper.selectById(id); systemUserRoleService.queryRoleByUsersId(currentUserId).stream()
systemUserInfoDAO.deleteUserLoginInfoByUserName(user.getUsername()); .map(SystemRoleTb::getLevel).collect(Collectors.toList()));
Integer optLevel = Collections.min(
systemUserRoleService.queryRoleByUsersId(id).stream().map(SystemRoleTb::getLevel)
.collect(Collectors.toList()));
if (currentLevel > optLevel) {
throw new BadRequestException(
"角色权限不足, 不能删除:" + this.getUserById(id).getUsername());
} }
}
// 清理缓存
List<String> usernameList = systemUserMapper.selectByIds(ids).stream().map(SystemUserTb::getUsername).distinct().collect(Collectors.toList());
for (String username : usernameList) {
systemUserInfoDAO.deleteUserLoginInfoByUserName(username);
}
// 删除用户
systemUserMapper.deleteByIds(ids); systemUserMapper.deleteByIds(ids);
// 删除用户岗位 // 删除用户岗位
systemUserJobService.batchDeleteUserJob(ids); systemUserJobService.batchDeleteUserJob(ids);
@@ -198,10 +240,22 @@ public class SystemUserService {
* 修改密码 * 修改密码
* *
* @param username 用户名 * @param username 用户名
* @param encryptPassword 密码 * @param args 参数
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void updateUserPasswordByUsername(String username, String encryptPassword) { public void updateUserPasswordByUsername(String username, SystemUpdateUserPasswordArgs args) throws Exception {
String oldPass =
KitRsaEncryptUtil.decryptByPrivateKey(properties.getRsa().getPrivateKey(), args.getOldPass());
String newPass =
KitRsaEncryptUtil.decryptByPrivateKey(properties.getRsa().getPrivateKey(), args.getNewPass());
SystemUserTb user = this.getUserByUsername(username);
if (!passwordEncoder.matches(oldPass, user.getPassword())) {
throw new BadRequestException("修改失败,旧密码错误");
}
if (passwordEncoder.matches(newPass, user.getPassword())) {
throw new BadRequestException("新密码不能与旧密码相同");
}
String encryptPassword = passwordEncoder.encode(newPass);
systemUserMapper.updateUserPasswordByUsername(username, encryptPassword); systemUserMapper.updateUserPasswordByUsername(username, encryptPassword);
systemUserInfoDAO.deleteUserLoginInfoByUserName(username); systemUserInfoDAO.deleteUserLoginInfoByUserName(username);
} }
@@ -210,20 +264,20 @@ public class SystemUserService {
* 重置密码 * 重置密码
* *
* @param ids 用户id * @param ids 用户id
* @param password 密码
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void resetUserPasswordByIds(Set<Long> ids, String password) { public void resetUserPasswordByIds(Set<Long> ids) {
String defaultPwd = passwordEncoder.encode("123456");
List<SystemUserTb> users = systemUserMapper.selectByIds(ids); List<SystemUserTb> users = systemUserMapper.selectByIds(ids);
// 清除缓存 // 清除缓存
users.forEach(user -> { for (SystemUserTb user : users) {
// 清除缓存 // 清除缓存
systemUserInfoDAO.deleteUserLoginInfoByUserName(user.getUsername()); systemUserInfoDAO.deleteUserLoginInfoByUserName(user.getUsername());
// 强制退出 // 强制退出
systemUserOnlineInfoDAO.kickOutByUsername(user.getUsername()); systemUserOnlineInfoDAO.kickOutByUsername(user.getUsername());
}); }
// 重置密码 // 重置密码
systemUserMapper.updateUserPasswordByUserIds(password, ids); systemUserMapper.updateUserPasswordByUserIds(defaultPwd, ids);
} }
/** /**
@@ -265,11 +319,19 @@ public class SystemUserService {
* 修改邮箱 * 修改邮箱
* *
* @param username 用户名 * @param username 用户名
* @param email 邮箱 * @param args 参数
* @param code 验证码
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void updateUserEmailByUsername(String username, String email) { public void updateUserEmailByUsername(String username, SystemUserTb args, String code) throws Exception {
systemUserMapper.updateUserEmailByUsername(username, email); String password =
KitRsaEncryptUtil.decryptByPrivateKey(properties.getRsa().getPrivateKey(), args.getPassword());
SystemUserTb user = this.getUserByUsername(username);
if (!passwordEncoder.matches(password, user.getPassword())) {
throw new BadRequestException("密码错误");
}
systemEmailService.checkEmailCaptchaV1(SystemCaptchaBizEnum.EMAIL_RESET_EMAIL_CODE, args.getEmail(), code);
systemUserMapper.updateUserEmailByUsername(username, args.getEmail());
systemUserInfoDAO.deleteUserLoginInfoByUserName(username); systemUserInfoDAO.deleteUserLoginInfoByUserName(username);
} }
@@ -436,13 +498,11 @@ public class SystemUserService {
return null; return null;
} }
SystemUserVo userVo = BeanUtil.copyProperties(user, SystemUserVo.class); SystemUserVo userVo = BeanUtil.copyProperties(user, SystemUserVo.class);
// 查询关联的部门信息 // 查询关联的部门信息
if (user.getDeptId() != null) { if (user.getDeptId() != null) {
SystemDeptTb dept = systemDeptMapper.selectById(user.getDeptId()); SystemDeptTb dept = systemDeptMapper.selectById(user.getDeptId());
userVo.setDept(dept); userVo.setDept(dept);
} }
// 查询关联的岗位信息 // 查询关联的岗位信息
LambdaQueryWrapper<SystemUserJobTb> jobWrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SystemUserJobTb> jobWrapper = new LambdaQueryWrapper<>();
jobWrapper.eq(SystemUserJobTb::getUserId, user.getId()); jobWrapper.eq(SystemUserJobTb::getUserId, user.getId());
@@ -452,7 +512,6 @@ public class SystemUserService {
List<SystemJobTb> jobs = systemJobMapper.selectByIds(jobIds); List<SystemJobTb> jobs = systemJobMapper.selectByIds(jobIds);
userVo.setJobs(new LinkedHashSet<>(jobs)); userVo.setJobs(new LinkedHashSet<>(jobs));
} }
// 查询关联的角色信息 // 查询关联的角色信息
LambdaQueryWrapper<SystemUserRoleTb> roleWrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SystemUserRoleTb> roleWrapper = new LambdaQueryWrapper<>();
roleWrapper.eq(SystemUserRoleTb::getUserId, user.getId()); roleWrapper.eq(SystemUserRoleTb::getUserId, user.getId());
@@ -462,7 +521,6 @@ public class SystemUserService {
List<SystemRoleTb> roles = systemRoleMapper.selectByIds(roleIds); List<SystemRoleTb> roles = systemRoleMapper.selectByIds(roleIds);
userVo.setRoles(new LinkedHashSet<>(roles)); userVo.setRoles(new LinkedHashSet<>(roles));
} }
return userVo; return userVo;
} }
@@ -477,12 +535,6 @@ public class SystemUserService {
return this.convertToUserVo(this.getUserByUsername(username)); return this.convertToUserVo(this.getUserByUsername(username));
} }
public long countUserByDeptIds(Set<Long> deptIds) {
LambdaQueryWrapper<SystemUserTb> wrapper = new LambdaQueryWrapper<>();
wrapper.in(SystemUserTb::getDeptId, deptIds);
return systemUserMapper.selectCount(wrapper);
}
public SystemUserTb getUserByEmail(String email) { public SystemUserTb getUserByEmail(String email) {
LambdaQueryWrapper<SystemUserTb> wrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SystemUserTb> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SystemUserTb::getEmail, email); wrapper.eq(SystemUserTb::getEmail, email);
@@ -496,4 +548,30 @@ public class SystemUserService {
wrapper.eq(SystemUserTb::getEnabled, 1); wrapper.eq(SystemUserTb::getEnabled, 1);
return systemUserMapper.selectOne(wrapper); return systemUserMapper.selectOne(wrapper);
} }
public KitPageResult<SystemUserVo> aggregationSearchUserByArgs(Page<SystemUserTb> page, SystemQueryUserArgs args, String currentUsername) {
if (!ObjectUtils.isEmpty(args.getDeptId())) {
args.getDeptIds().add(args.getDeptId());
// 先查找是否存在子节点
List<SystemDeptTb> data = systemDeptService.listDeptByPid(args.getDeptId());
// 然后把子节点的ID都加入到集合中
args.getDeptIds().addAll(systemDeptService.queryChildDeptIdByDeptIds(data));
}
// 数据权限
List<Long> dataScopes = systemDataService.queryDeptIdByArgs(
this.getUserByUsername(currentUsername));
// args.getDeptIds() 不为空并且数据权限不为空则取交集
if (!CollectionUtils.isEmpty(args.getDeptIds()) && !CollectionUtils.isEmpty(dataScopes)) {
// 取交集
args.getDeptIds().retainAll(dataScopes);
if (!CollectionUtil.isEmpty(args.getDeptIds())) {
return this.searchUserByArgs(args, page);
}
} else {
// 否则取并集
args.getDeptIds().addAll(dataScopes);
return this.searchUserByArgs(args, page);
}
return KitPageUtil.emptyData();
}
} }
@@ -36,13 +36,13 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.servlet.http.HttpServletResponse;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@@ -60,10 +60,14 @@ import org.springframework.web.multipart.MultipartFile;
public class SystemOssStorageServiceImpl extends ServiceImpl<SystemOssStorageMapper, SystemOssStorageTb> public class SystemOssStorageServiceImpl extends ServiceImpl<SystemOssStorageMapper, SystemOssStorageTb>
implements SystemOssStorageService { implements SystemOssStorageService {
@Autowired private MinioRepository minioRepository; @Autowired
@Autowired private AppProperties properties; private MinioRepository minioRepository;
@Autowired private KitFileLocalUploadHelper fileLocalUploadHelper; @Autowired
@Autowired private SystemOssStorageMapper systemOssStorageMapper; private AppProperties properties;
@Autowired
private KitFileLocalUploadHelper fileLocalUploadHelper;
@Autowired
private SystemOssStorageMapper systemOssStorageMapper;
@Override @Override
public KitPageResult<SystemOssStorageVo> searchOssStorage(SystemQueryStorageArgs args, public KitPageResult<SystemOssStorageVo> searchOssStorage(SystemQueryStorageArgs args,
@@ -15,38 +15,17 @@
*/ */
package cn.odboy.system.controller; package cn.odboy.system.controller;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.odboy.annotation.AnonymousPostMapping; import cn.odboy.annotation.AnonymousPostMapping;
import cn.odboy.constant.CaptchaCodeEnum;
import cn.odboy.constant.SystemConst;
import cn.odboy.framework.exception.BadRequestException;
import cn.odboy.framework.properties.AppProperties;
import cn.odboy.framework.redis.KitRedisHelper;
import cn.odboy.system.dal.model.SystemUserInfoVo; import cn.odboy.system.dal.model.SystemUserInfoVo;
import cn.odboy.system.dal.model.SystemUserJwtVo;
import cn.odboy.system.dal.model.SystemUserLoginArgs; import cn.odboy.system.dal.model.SystemUserLoginArgs;
import cn.odboy.system.dal.redis.SystemCacheKey; import cn.odboy.system.service.SystemAuthService;
import cn.odboy.system.dal.redis.SystemUserOnlineInfoDAO;
import cn.odboy.system.framework.permission.core.KitSecurityHelper;
import cn.odboy.system.framework.permission.core.handler.TokenProvider;
import cn.odboy.system.framework.permission.core.handler.UserDetailsHandler;
import cn.odboy.util.KitRsaEncryptUtil;
import com.wf.captcha.base.Captcha;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
@@ -63,97 +42,34 @@ import org.springframework.web.bind.annotation.RestController;
public class SystemAuthController { public class SystemAuthController {
@Autowired @Autowired
private KitRedisHelper redisHelper; private SystemAuthService systemAuthService;
@Autowired
private SystemUserOnlineInfoDAO systemUserOnlineInfoDAO;
@Autowired
private TokenProvider tokenProvider;
@Autowired
private AppProperties properties;
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private UserDetailsHandler userDetailsService;
@ApiOperation("登录授权") @ApiOperation("登录授权")
@AnonymousPostMapping(value = "/login") @AnonymousPostMapping(value = "/login")
public ResponseEntity<Map<String, Object>> login(@Validated @RequestBody SystemUserLoginArgs loginRequest, public ResponseEntity<Map<String, Object>> login(@Validated @RequestBody SystemUserLoginArgs loginRequest,
HttpServletRequest request) throws Exception { HttpServletRequest request) throws Exception {
// 密码解密 Map<String, Object> loginInfo = systemAuthService.doLogin(loginRequest, request);
String password = return ResponseEntity.ok(loginInfo);
KitRsaEncryptUtil.decryptByPrivateKey(properties.getRsa().getPrivateKey(), loginRequest.getPassword());
// 查询验证码
String code = redisHelper.get(loginRequest.getUuid(), String.class);
// 清除验证码
redisHelper.del(loginRequest.getUuid());
if (StrUtil.isBlank(code)) {
throw new BadRequestException("验证码不存在或已过期");
}
if (StrUtil.isBlank(loginRequest.getCode()) || !loginRequest.getCode().equalsIgnoreCase(code)) {
throw new BadRequestException("验证码错误");
}
// 获取用户信息
SystemUserJwtVo jwtUser = userDetailsService.loadUserByUsername(loginRequest.getUsername());
// 验证用户密码
if (!passwordEncoder.matches(password, jwtUser.getPassword())) {
throw new BadRequestException("登录密码错误");
}
Authentication authentication =
new UsernamePasswordAuthenticationToken(jwtUser, null, jwtUser.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication);
// 生成令牌
String token = tokenProvider.createToken(jwtUser);
// 返回 token 与 用户信息
Map<String, Object> authInfo = new HashMap<>(2) {{
put("token", String.format("%s %s", SystemConst.TOKEN_PREFIX, token));
put("user", BeanUtil.copyProperties(jwtUser, SystemUserInfoVo.class));
}};
if (properties.getLogin().isSingle()) {
// 踢掉之前已经登录的token
systemUserOnlineInfoDAO.kickOutByUsername(loginRequest.getUsername());
}
// 保存在线信息
systemUserOnlineInfoDAO.saveUserJwtModelByToken(jwtUser, token, request);
// 返回登录信息
return ResponseEntity.ok(authInfo);
} }
@ApiOperation("获取用户信息") @ApiOperation("获取用户信息")
@PostMapping(value = "/info") @PostMapping(value = "/info")
public ResponseEntity<SystemUserInfoVo> getUserInfo() { public ResponseEntity<SystemUserInfoVo> getUserInfo() {
SystemUserJwtVo jwtUser = (SystemUserJwtVo) KitSecurityHelper.getCurrentUser(); SystemUserInfoVo userInfoVo = systemAuthService.getCurrentUserInfoVo();
SystemUserInfoVo userInfoVo = BeanUtil.copyProperties(jwtUser, SystemUserInfoVo.class);
return ResponseEntity.ok(userInfoVo); return ResponseEntity.ok(userInfoVo);
} }
@ApiOperation("获取验证码") @ApiOperation("获取验证码")
@AnonymousPostMapping(value = "/captcha/getImage") @AnonymousPostMapping(value = "/captcha/getImage")
public ResponseEntity<Map<String, Object>> getCode() { public ResponseEntity<Map<String, Object>> getCode() {
// 获取运算的结果 Map<String, Object> imgResult = systemAuthService.getCaptchaInfo();
Captcha captcha = properties.getLogin().getCaptchaSetting().getCaptcha();
String uuid = SystemCacheKey.CAPTCHA_LOGIN + IdUtil.simpleUUID();
//当验证码类型为 arithmetic时且长度 >= 2 时, captcha.text()的结果有几率为浮点型
String captchaValue = captcha.text();
if (captcha.getCharType() - 1 == CaptchaCodeEnum.ARITHMETIC.ordinal() &&
captchaValue.contains(SystemConst.SYMBOL_DOT)) {
captchaValue = captchaValue.split("\\.")[0];
}
// 保存
redisHelper.set(uuid, captchaValue, properties.getLogin().getCaptchaSetting().getExpiration(),
TimeUnit.MINUTES);
// 验证码信息
Map<String, Object> imgResult = new HashMap<String, Object>(2) {{
put("img", captcha.toBase64());
put("uuid", uuid);
}};
return ResponseEntity.ok(imgResult); return ResponseEntity.ok(imgResult);
} }
@ApiOperation("退出登录") @ApiOperation("退出登录")
@AnonymousPostMapping(value = "/logout") @AnonymousPostMapping(value = "/logout")
public ResponseEntity<Void> logout(HttpServletRequest request) { public ResponseEntity<Void> logout(HttpServletRequest request) {
String token = tokenProvider.getToken(request); systemAuthService.doLogout(request);
systemUserOnlineInfoDAO.logoutByToken(token);
return ResponseEntity.ok(null); return ResponseEntity.ok(null);
} }
} }
@@ -15,7 +15,6 @@
*/ */
package cn.odboy.system.controller; package cn.odboy.system.controller;
import cn.odboy.framework.exception.BadRequestException;
import cn.odboy.system.constant.SystemCaptchaBizEnum; import cn.odboy.system.constant.SystemCaptchaBizEnum;
import cn.odboy.system.dal.model.SystemCheckEmailCaptchaArgs; import cn.odboy.system.dal.model.SystemCheckEmailCaptchaArgs;
import cn.odboy.system.service.SystemEmailService; import cn.odboy.system.service.SystemEmailService;
@@ -55,11 +54,7 @@ public class SystemCaptchaController {
@ApiOperation("验证码验证") @ApiOperation("验证码验证")
@PostMapping(value = "/checkEmailCaptcha") @PostMapping(value = "/checkEmailCaptcha")
public ResponseEntity<Void> checkEmailCaptcha(@Validated @RequestBody SystemCheckEmailCaptchaArgs args) { public ResponseEntity<Void> checkEmailCaptcha(@Validated @RequestBody SystemCheckEmailCaptchaArgs args) {
SystemCaptchaBizEnum biEnum = SystemCaptchaBizEnum.getByBizCode(args.getBizCode()); systemEmailService.checkEmailCaptcha(args);
if (biEnum == null) {
throw new BadRequestException("不支持的业务");
}
systemEmailService.checkEmailCaptcha(biEnum, args.getEmail(), args.getCode());
return ResponseEntity.ok(null); return ResponseEntity.ok(null);
} }
} }
@@ -58,8 +58,7 @@ public class SystemDeptController {
@PreAuthorize("@el.check('user:list','dept:list')") @PreAuthorize("@el.check('user:list','dept:list')")
public ResponseEntity<KitPageResult<SystemDeptTb>> queryDept( public ResponseEntity<KitPageResult<SystemDeptTb>> queryDept(
@Validated @RequestBody KitPageArgs<SystemQueryDeptArgs> pageArgs) throws Exception { @Validated @RequestBody KitPageArgs<SystemQueryDeptArgs> pageArgs) throws Exception {
SystemQueryDeptArgs args = pageArgs.getArgs(); List<SystemDeptTb> depts = systemDeptService.queryAllDeptByArgs(pageArgs.getArgs(), true);
List<SystemDeptTb> depts = systemDeptService.queryAllDeptByArgs(args, true);
return ResponseEntity.ok(KitPageUtil.toPage(depts)); return ResponseEntity.ok(KitPageUtil.toPage(depts));
} }
@@ -91,11 +90,7 @@ public class SystemDeptController {
@PostMapping(value = "/removeDeptByIds") @PostMapping(value = "/removeDeptByIds")
@PreAuthorize("@el.check('dept:del')") @PreAuthorize("@el.check('dept:del')")
public ResponseEntity<Void> removeDeptByIds(@RequestBody Set<Long> ids) { public ResponseEntity<Void> removeDeptByIds(@RequestBody Set<Long> ids) {
// 获取部门, 和其所有子部门 systemDeptService.deleteDeptByIds(ids);
Set<SystemDeptTb> depts = systemDeptService.traverseDeptByIdWithPids(ids);
// 验证是否被角色或用户关联
systemDeptService.verifyBindRelationByIds(depts);
systemDeptService.deleteDeptByIds(depts);
return ResponseEntity.ok(null); return ResponseEntity.ok(null);
} }
} }
@@ -66,8 +66,7 @@ public class SystemDictController {
public ResponseEntity<KitPageResult<SystemDictTb>> queryDictByArgs( public ResponseEntity<KitPageResult<SystemDictTb>> queryDictByArgs(
@Validated @RequestBody KitPageArgs<SystemQueryDictArgs> pageArgs) { @Validated @RequestBody KitPageArgs<SystemQueryDictArgs> pageArgs) {
Page<SystemDictTb> page = new Page<>(pageArgs.getPage(), pageArgs.getSize()); Page<SystemDictTb> page = new Page<>(pageArgs.getPage(), pageArgs.getSize());
SystemQueryDictArgs args = pageArgs.getArgs(); return ResponseEntity.ok(systemDictService.searchDict(pageArgs.getArgs(), page));
return ResponseEntity.ok(systemDictService.searchDict(args, page));
} }
@ApiOperation("新增字典") @ApiOperation("新增字典")
@@ -25,7 +25,6 @@ import cn.odboy.system.service.SystemDictDetailService;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -58,19 +57,14 @@ public class SystemDictDetailController {
@PostMapping(value = "/queryDictDetailByArgs") @PostMapping(value = "/queryDictDetailByArgs")
public ResponseEntity<KitPageResult<SystemDictDetailVo>> queryDictDetailByArgs( public ResponseEntity<KitPageResult<SystemDictDetailVo>> queryDictDetailByArgs(
@Validated @RequestBody KitPageArgs<SystemQueryDictDetailArgs> pageArgs) { @Validated @RequestBody KitPageArgs<SystemQueryDictDetailArgs> pageArgs) {
SystemQueryDictDetailArgs args = pageArgs.getArgs();
Page<SystemDictDetailTb> page = new Page<>(pageArgs.getPage(), pageArgs.getSize()); Page<SystemDictDetailTb> page = new Page<>(pageArgs.getPage(), pageArgs.getSize());
return ResponseEntity.ok(systemDictDetailService.searchDictDetail(args, page)); return ResponseEntity.ok(systemDictDetailService.searchDictDetail(pageArgs.getArgs(), page));
} }
@ApiOperation("查询多个字典详情") @ApiOperation("查询多个字典详情")
@GetMapping(value = "/getDictDetailMaps") @GetMapping(value = "/getDictDetailMaps")
public ResponseEntity<Map<String, List<SystemDictDetailVo>>> getDictDetailMaps(@RequestParam String dictName) { public ResponseEntity<Map<String, List<SystemDictDetailVo>>> getDictDetailMaps(@RequestParam String dictName) {
String[] names = dictName.split("[,, ]"); Map<String, List<SystemDictDetailVo>> dictMap = systemDictDetailService.getDictDetailMap(dictName);
Map<String, List<SystemDictDetailVo>> dictMap = new HashMap<>(16);
for (String name : names) {
dictMap.put(name, systemDictDetailService.listDictDetailByName(name));
}
return ResponseEntity.ok(dictMap); return ResponseEntity.ok(dictMap);
} }
@@ -57,9 +57,8 @@ public class SystemJobController {
@PreAuthorize("@el.check('job:list','user:list')") @PreAuthorize("@el.check('job:list','user:list')")
public ResponseEntity<KitPageResult<SystemJobTb>> queryJobByArgs( public ResponseEntity<KitPageResult<SystemJobTb>> queryJobByArgs(
@Validated @RequestBody KitPageArgs<SystemQueryJobArgs> pageArgs) { @Validated @RequestBody KitPageArgs<SystemQueryJobArgs> pageArgs) {
SystemQueryJobArgs args = pageArgs.getArgs(); Page<SystemJobTb> page = new Page<>(pageArgs.getPage(), pageArgs.getSize());
Page<SystemJobTb> page = new Page<>(args.getPage(), args.getSize()); return ResponseEntity.ok(systemJobService.searchJobByArgs(pageArgs.getArgs(), page));
return ResponseEntity.ok(systemJobService.searchJobByArgs(args, page));
} }
@ApiOperation("查询岗位") @ApiOperation("查询岗位")
@@ -90,8 +89,6 @@ public class SystemJobController {
@PostMapping(value = "/removeJobByIds") @PostMapping(value = "/removeJobByIds")
@PreAuthorize("@el.check('job:del')") @PreAuthorize("@el.check('job:del')")
public ResponseEntity<Void> removeJobByIds(@RequestBody Set<Long> ids) { public ResponseEntity<Void> removeJobByIds(@RequestBody Set<Long> ids) {
// 验证是否被用户关联
systemJobService.verifyBindRelationByIds(ids);
systemJobService.deleteJobByIds(ids); systemJobService.deleteJobByIds(ids);
return ResponseEntity.ok(null); return ResponseEntity.ok(null);
} }
@@ -17,12 +17,9 @@ package cn.odboy.system.controller;
import cn.odboy.base.KitPageArgs; import cn.odboy.base.KitPageArgs;
import cn.odboy.base.KitPageResult; import cn.odboy.base.KitPageResult;
import cn.odboy.constant.FileTypeEnum;
import cn.odboy.framework.exception.BadRequestException;
import cn.odboy.system.dal.dataobject.SystemLocalStorageTb; import cn.odboy.system.dal.dataobject.SystemLocalStorageTb;
import cn.odboy.system.dal.model.SystemQueryStorageArgs; import cn.odboy.system.dal.model.SystemQueryStorageArgs;
import cn.odboy.system.service.SystemLocalStorageService; import cn.odboy.system.service.SystemLocalStorageService;
import cn.odboy.util.KitFileUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
@@ -53,9 +50,8 @@ public class SystemLocalStorageController {
@PreAuthorize("@el.check('storage:list')") @PreAuthorize("@el.check('storage:list')")
public ResponseEntity<KitPageResult<SystemLocalStorageTb>> queryLocalStorage( public ResponseEntity<KitPageResult<SystemLocalStorageTb>> queryLocalStorage(
@Validated @RequestBody KitPageArgs<SystemQueryStorageArgs> pageArgs) { @Validated @RequestBody KitPageArgs<SystemQueryStorageArgs> pageArgs) {
SystemQueryStorageArgs args = pageArgs.getArgs(); Page<SystemLocalStorageTb> page = new Page<>(pageArgs.getPage(), pageArgs.getSize());
Page<SystemLocalStorageTb> page = new Page<>(args.getPage(), args.getSize()); return ResponseEntity.ok(localStorageService.searchLocalStorage(pageArgs.getArgs(), page));
return ResponseEntity.ok(localStorageService.searchLocalStorage(args, page));
} }
@ApiOperation("导出数据") @ApiOperation("导出数据")
@@ -76,12 +72,7 @@ public class SystemLocalStorageController {
@ApiOperation("上传图片") @ApiOperation("上传图片")
@PostMapping("/uploadPicture") @PostMapping("/uploadPicture")
public ResponseEntity<SystemLocalStorageTb> uploadPicture(@RequestParam MultipartFile file) { public ResponseEntity<SystemLocalStorageTb> uploadPicture(@RequestParam MultipartFile file) {
// 判断文件是否为图片 SystemLocalStorageTb localStorage = localStorageService.uploadPictureV1(file);
String suffix = KitFileUtil.getSuffix(file.getOriginalFilename());
if (!FileTypeEnum.IMAGE.getCode().equals(KitFileUtil.getFileType(suffix))) {
throw new BadRequestException("只能上传图片");
}
SystemLocalStorageTb localStorage = localStorageService.uploadFile(null, file);
return ResponseEntity.ok(localStorage); return ResponseEntity.ok(localStorage);
} }
@@ -15,7 +15,6 @@
*/ */
package cn.odboy.system.controller; package cn.odboy.system.controller;
import cn.hutool.core.collection.CollectionUtil;
import cn.odboy.base.KitPageArgs; import cn.odboy.base.KitPageArgs;
import cn.odboy.base.KitPageResult; import cn.odboy.base.KitPageResult;
import cn.odboy.framework.exception.BadRequestException; import cn.odboy.framework.exception.BadRequestException;
@@ -23,17 +22,12 @@ import cn.odboy.system.dal.dataobject.SystemMenuTb;
import cn.odboy.system.dal.model.SystemMenuVo; import cn.odboy.system.dal.model.SystemMenuVo;
import cn.odboy.system.dal.model.SystemQueryMenuArgs; import cn.odboy.system.dal.model.SystemQueryMenuArgs;
import cn.odboy.system.dal.mysql.SystemMenuMapper; import cn.odboy.system.dal.mysql.SystemMenuMapper;
import cn.odboy.system.framework.permission.core.KitSecurityHelper;
import cn.odboy.system.service.SystemMenuService; import cn.odboy.system.service.SystemMenuService;
import cn.odboy.util.KitPageUtil; import cn.odboy.util.KitPageUtil;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
@@ -66,27 +60,23 @@ public class SystemMenuController {
@PostMapping(value = "/buildMenus") @PostMapping(value = "/buildMenus")
@ApiOperation("获取前端所需菜单") @ApiOperation("获取前端所需菜单")
public ResponseEntity<List<SystemMenuVo>> buildMenus() { public ResponseEntity<List<SystemMenuVo>> buildMenus() {
List<SystemMenuTb> menuList = systemMenuService.listMenuByUserId(KitSecurityHelper.getCurrentUserId()); List<SystemMenuVo> systemMenuVos = systemMenuService.buildFrontMenus();
List<SystemMenuTb> menus = systemMenuService.buildMenuTree(menuList); return ResponseEntity.ok(systemMenuVos);
return ResponseEntity.ok(systemMenuService.buildMenuVo(menus));
} }
@ApiOperation("返回全部的菜单") @ApiOperation("返回全部的菜单")
@PostMapping(value = "/queryMenuListByPid") @PostMapping(value = "/queryMenuListByPid")
@PreAuthorize("@el.check('menu:list','roles:list')") @PreAuthorize("@el.check('menu:list','roles:list')")
public ResponseEntity<List<SystemMenuTb>> queryMenuListByPid(@RequestParam Long pid) { public ResponseEntity<List<SystemMenuTb>> queryMenuListByPid(@RequestParam Long pid) {
return ResponseEntity.ok(systemMenuService.listMenuByPid(pid)); List<SystemMenuTb> systemMenuTbs = systemMenuService.listMenuByPid(pid);
return ResponseEntity.ok(systemMenuTbs);
} }
@ApiOperation("根据菜单ID返回所有子节点ID, 包含自身ID") @ApiOperation("根据菜单ID返回所有子节点ID, 包含自身ID")
@PostMapping(value = "/queryChildMenuSet") @PostMapping(value = "/queryChildMenuSet")
@PreAuthorize("@el.check('menu:list','roles:list')") @PreAuthorize("@el.check('menu:list','roles:list')")
public ResponseEntity<Set<Long>> queryChildMenuSet(@RequestParam Long id) { public ResponseEntity<Set<Long>> queryChildMenuSet(@RequestParam Long id) {
Set<SystemMenuTb> menuSet = new HashSet<>(); Set<Long> ids = systemMenuService.listChildMenuSetByMenuId(id);
List<SystemMenuTb> menuList = systemMenuService.listMenuByPid(id);
menuSet.add(systemMenuMapper.selectById(id));
menuSet = systemMenuService.queryChildMenuByArgs(menuList, menuSet);
Set<Long> ids = menuSet.stream().map(SystemMenuTb::getId).collect(Collectors.toSet());
return ResponseEntity.ok(ids); return ResponseEntity.ok(ids);
} }
@@ -103,8 +93,7 @@ public class SystemMenuController {
@PreAuthorize("@el.check('menu:list')") @PreAuthorize("@el.check('menu:list')")
public ResponseEntity<KitPageResult<SystemMenuTb>> queryAllMenu( public ResponseEntity<KitPageResult<SystemMenuTb>> queryAllMenu(
@Validated @RequestBody KitPageArgs<SystemQueryMenuArgs> pageArgs) throws Exception { @Validated @RequestBody KitPageArgs<SystemQueryMenuArgs> pageArgs) throws Exception {
SystemQueryMenuArgs args = pageArgs.getArgs(); List<SystemMenuTb> menuList = systemMenuService.queryAllMenu(pageArgs.getArgs(), true);
List<SystemMenuTb> menuList = systemMenuService.queryAllMenu(args, true);
return ResponseEntity.ok(KitPageUtil.toPage(menuList)); return ResponseEntity.ok(KitPageUtil.toPage(menuList));
} }
@@ -112,23 +101,8 @@ public class SystemMenuController {
@PostMapping("/queryMenuSuperior") @PostMapping("/queryMenuSuperior")
@PreAuthorize("@el.check('menu:list')") @PreAuthorize("@el.check('menu:list')")
public ResponseEntity<List<SystemMenuTb>> queryMenuSuperior(@RequestBody List<Long> ids) { public ResponseEntity<List<SystemMenuTb>> queryMenuSuperior(@RequestBody List<Long> ids) {
Set<SystemMenuTb> menus; List<SystemMenuTb> systemMenuTbs = systemMenuService.listMenuSuperior(ids);
if (CollectionUtil.isNotEmpty(ids)) { return ResponseEntity.ok(systemMenuTbs);
menus = new LinkedHashSet<>(systemMenuService.listMenuByIds(ids));
for (SystemMenuTb menu : menus) {
List<SystemMenuTb> menuList = systemMenuService.querySuperiorMenuByArgs(menu, new ArrayList<>());
for (SystemMenuTb data : menuList) {
if (data.getId().equals(menu.getPid())) {
data.setSubCount(data.getSubCount() - 1);
}
}
menus.addAll(menuList);
}
// 编辑菜单时不显示自己以及自己下级的数据, 避免出现PID数据环形问题
menus = menus.stream().filter(i -> !ids.contains(i.getId())).collect(Collectors.toSet());
return ResponseEntity.ok(systemMenuService.buildMenuTree(new ArrayList<>(menus)));
}
return ResponseEntity.ok(systemMenuService.listMenuByPid(null));
} }
@ApiOperation("新增菜单") @ApiOperation("新增菜单")
@@ -19,12 +19,12 @@ import cn.odboy.base.KitPageArgs;
import cn.odboy.base.KitPageResult; import cn.odboy.base.KitPageResult;
import cn.odboy.system.dal.model.SystemUserOnlineVo; import cn.odboy.system.dal.model.SystemUserOnlineVo;
import cn.odboy.system.dal.redis.SystemUserOnlineInfoDAO; import cn.odboy.system.dal.redis.SystemUserOnlineInfoDAO;
import cn.odboy.util.KitDesEncryptUtil;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import java.io.IOException; import java.io.IOException;
import java.util.List;
import java.util.Set; import java.util.Set;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -49,28 +49,24 @@ public class SystemOnlineController {
@PostMapping @PostMapping
@PreAuthorize("@el.check()") @PreAuthorize("@el.check()")
public ResponseEntity<KitPageResult<SystemUserOnlineVo>> queryOnlineUser( public ResponseEntity<KitPageResult<SystemUserOnlineVo>> queryOnlineUser(
@Validated @RequestBody KitPageArgs<SystemUserOnlineVo> args) { @Validated @RequestBody KitPageArgs<SystemUserOnlineVo> pageArgs) {
IPage<SystemUserOnlineVo> page = new Page<>(args.getPage(), args.getSize()); IPage<SystemUserOnlineVo> page = new Page<>(pageArgs.getPage(), pageArgs.getSize());
return ResponseEntity.ok(systemUserOnlineInfoDAO.queryUserOnlineModelPage(args.getArgs(), page)); return ResponseEntity.ok(systemUserOnlineInfoDAO.queryUserOnlineModelPage(pageArgs.getArgs(), page));
} }
@ApiOperation("导出数据") @ApiOperation("导出数据")
@GetMapping(value = "/download") @GetMapping(value = "/download")
@PreAuthorize("@el.check()") @PreAuthorize("@el.check()")
public void exportOnlineUser(HttpServletResponse response, String username) throws IOException { public void exportOnlineUser(HttpServletResponse response, String username) throws IOException {
systemUserOnlineInfoDAO.downloadUserOnlineModelExcel( List<SystemUserOnlineVo> userOnlineVos = systemUserOnlineInfoDAO.queryUserOnlineModelListByUsername(username);
systemUserOnlineInfoDAO.queryUserOnlineModelListByUsername(username), response); systemUserOnlineInfoDAO.downloadUserOnlineModelExcel(userOnlineVos, response);
} }
@ApiOperation("踢出用户") @ApiOperation("踢出用户")
@PostMapping(value = "/kickOutUser") @PostMapping(value = "/kickOutUser")
@PreAuthorize("@el.check()") @PreAuthorize("@el.check()")
public ResponseEntity<Void> kickOutUser(@RequestBody Set<String> keys) throws Exception { public ResponseEntity<Void> kickOutUser(@RequestBody Set<String> keys) throws Exception {
for (String token : keys) { systemUserOnlineInfoDAO.kickOutUser(keys);
// 解密Key
token = KitDesEncryptUtil.desDecrypt(token);
systemUserOnlineInfoDAO.logoutByToken(token);
}
return ResponseEntity.ok(null); return ResponseEntity.ok(null);
} }
} }
@@ -53,9 +53,8 @@ public class SystemOssStorageController {
@PreAuthorize("@el.check('storage:list')") @PreAuthorize("@el.check('storage:list')")
public ResponseEntity<KitPageResult<SystemOssStorageVo>> queryOssStorage( public ResponseEntity<KitPageResult<SystemOssStorageVo>> queryOssStorage(
@Validated @RequestBody KitPageArgs<SystemQueryStorageArgs> pageArgs) { @Validated @RequestBody KitPageArgs<SystemQueryStorageArgs> pageArgs) {
SystemQueryStorageArgs args = pageArgs.getArgs(); Page<SystemOssStorageTb> page = new Page<>(pageArgs.getPage(), pageArgs.getSize());
Page<SystemOssStorageTb> page = new Page<>(args.getPage(), args.getSize()); return ResponseEntity.ok(systemOssStorageService.searchOssStorage(pageArgs.getArgs(), page));
return ResponseEntity.ok(systemOssStorageService.searchOssStorage(args, page));
} }
@ApiOperation("导出数据") @ApiOperation("导出数据")
@@ -17,8 +17,6 @@ package cn.odboy.system.controller;
import cn.odboy.base.KitPageArgs; import cn.odboy.base.KitPageArgs;
import cn.odboy.base.KitPageResult; import cn.odboy.base.KitPageResult;
import cn.odboy.framework.context.KitSpringBeanHolder;
import cn.odboy.framework.exception.BadRequestException;
import cn.odboy.system.dal.dataobject.SystemQuartzJobTb; import cn.odboy.system.dal.dataobject.SystemQuartzJobTb;
import cn.odboy.system.dal.dataobject.SystemQuartzLogTb; import cn.odboy.system.dal.dataobject.SystemQuartzLogTb;
import cn.odboy.system.dal.model.SystemQueryQuartzJobArgs; import cn.odboy.system.dal.model.SystemQueryQuartzJobArgs;
@@ -57,9 +55,8 @@ public class SystemQuartzJobController {
@PreAuthorize("@el.check('quartzJob:list')") @PreAuthorize("@el.check('quartzJob:list')")
public ResponseEntity<KitPageResult<SystemQuartzJobTb>> queryQuartzJobByCrud( public ResponseEntity<KitPageResult<SystemQuartzJobTb>> queryQuartzJobByCrud(
@Validated @RequestBody KitPageArgs<SystemQueryQuartzJobArgs> pageArgs) { @Validated @RequestBody KitPageArgs<SystemQueryQuartzJobArgs> pageArgs) {
SystemQueryQuartzJobArgs args = pageArgs.getArgs(); Page<SystemQuartzJobTb> page = new Page<>(pageArgs.getPage(), pageArgs.getSize());
Page<SystemQuartzJobTb> page = new Page<>(args.getPage(), args.getSize()); return ResponseEntity.ok(systemQuartzJobService.searchQuartzJobByArgs(pageArgs.getArgs(), page));
return ResponseEntity.ok(systemQuartzJobService.searchQuartzJobByArgs(args, page));
} }
@ApiOperation("导出任务数据") @ApiOperation("导出任务数据")
@@ -88,11 +85,6 @@ public class SystemQuartzJobController {
@PostMapping(value = "/createQuartzJob") @PostMapping(value = "/createQuartzJob")
@PreAuthorize("@el.check('quartzJob:add')") @PreAuthorize("@el.check('quartzJob:add')")
public ResponseEntity<Void> createQuartzJob(@Validated @RequestBody SystemQuartzJobTb args) { public ResponseEntity<Void> createQuartzJob(@Validated @RequestBody SystemQuartzJobTb args) {
if (args.getId() != null) {
throw new BadRequestException("无效参数id");
}
// 验证Bean是不是合法的, 合法的定时任务 Bean 需要用 @Service 定义
checkBean(args.getBeanName());
systemQuartzJobService.createJob(args); systemQuartzJobService.createJob(args);
return ResponseEntity.ok(null); return ResponseEntity.ok(null);
} }
@@ -102,8 +94,6 @@ public class SystemQuartzJobController {
@PreAuthorize("@el.check('quartzJob:edit')") @PreAuthorize("@el.check('quartzJob:edit')")
public ResponseEntity<Void> updateQuartzJob( public ResponseEntity<Void> updateQuartzJob(
@Validated(SystemQuartzJobTb.Update.class) @RequestBody SystemUpdateQuartzJobArgs args) { @Validated(SystemQuartzJobTb.Update.class) @RequestBody SystemUpdateQuartzJobArgs args) {
// 验证Bean是不是合法的, 合法的定时任务 Bean 需要用 @Service 定义
checkBean(args.getBeanName());
systemQuartzJobService.updateQuartzJobResumeCron(args); systemQuartzJobService.updateQuartzJobResumeCron(args);
return ResponseEntity.ok(null); return ResponseEntity.ok(null);
} }
@@ -131,17 +121,4 @@ public class SystemQuartzJobController {
systemQuartzJobService.deleteJobByIds(ids); systemQuartzJobService.deleteJobByIds(ids);
return ResponseEntity.ok(null); return ResponseEntity.ok(null);
} }
/**
* 验证Bean是不是合法的, 合法的定时任务 Bean 需要用 @Service 定义
*
* @param beanName Bean名称
*/
private void checkBean(String beanName) {
// 避免调用攻击者可以从SpringContextHolder获得控制jdbcTemplate类
// 并使用getDeclaredMethod调用jdbcTemplate的queryForMap函数,执行任意sql命令。
if (!KitSpringBeanHolder.getAllServiceBeanName().contains(beanName)) {
throw new BadRequestException("非法的 Bean,请重新输入!");
}
}
} }
@@ -18,21 +18,17 @@ package cn.odboy.system.controller;
import cn.hutool.core.lang.Dict; import cn.hutool.core.lang.Dict;
import cn.odboy.base.KitPageArgs; import cn.odboy.base.KitPageArgs;
import cn.odboy.base.KitPageResult; import cn.odboy.base.KitPageResult;
import cn.odboy.framework.exception.BadRequestException;
import cn.odboy.system.dal.dataobject.SystemRoleTb; import cn.odboy.system.dal.dataobject.SystemRoleTb;
import cn.odboy.system.dal.model.SystemCreateRoleArgs; import cn.odboy.system.dal.model.SystemCreateRoleArgs;
import cn.odboy.system.dal.model.SystemQueryRoleArgs; import cn.odboy.system.dal.model.SystemQueryRoleArgs;
import cn.odboy.system.dal.model.SystemRoleVo; import cn.odboy.system.dal.model.SystemRoleVo;
import cn.odboy.system.framework.permission.core.KitSecurityHelper;
import cn.odboy.system.service.SystemRoleService; import cn.odboy.system.service.SystemRoleService;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import java.io.IOException; import java.io.IOException;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
@@ -55,7 +51,7 @@ public class SystemRoleController {
@ApiOperation("获取单个role") @ApiOperation("获取单个role")
@PostMapping(value = "/queryRoleById") @PostMapping(value = "/queryRoleById")
@PreAuthorize("@el.check('roles:list')") @PreAuthorize("@el.check('roles:list')")
public ResponseEntity<SystemRoleTb> queryRoleById(@RequestBody SystemRoleTb args) { public ResponseEntity<SystemRoleVo> queryRoleById(@RequestBody SystemRoleTb args) {
return ResponseEntity.ok(systemRoleService.getRoleById(args.getId())); return ResponseEntity.ok(systemRoleService.getRoleById(args.getId()));
} }
@@ -78,22 +74,20 @@ public class SystemRoleController {
@PreAuthorize("@el.check('roles:list')") @PreAuthorize("@el.check('roles:list')")
public ResponseEntity<KitPageResult<SystemRoleVo>> queryRoleByArgs( public ResponseEntity<KitPageResult<SystemRoleVo>> queryRoleByArgs(
@Validated @RequestBody KitPageArgs<SystemQueryRoleArgs> pageArgs) { @Validated @RequestBody KitPageArgs<SystemQueryRoleArgs> pageArgs) {
SystemQueryRoleArgs args = pageArgs.getArgs(); Page<Object> page = new Page<>(pageArgs.getPage(), pageArgs.getSize());
Page<Object> page = new Page<>(args.getPage(), args.getSize()); return ResponseEntity.ok(systemRoleService.searchRoleByArgs(pageArgs.getArgs(), page));
return ResponseEntity.ok(systemRoleService.searchRoleByArgs(args, page));
} }
@ApiOperation("获取用户级别") @ApiOperation("获取用户级别")
@PostMapping(value = "/queryRoleLevel") @PostMapping(value = "/queryRoleLevel")
public ResponseEntity<Dict> queryRoleLevel() { public ResponseEntity<Dict> queryRoleLevel() {
return ResponseEntity.ok(Dict.create().set("level", checkRoleLevels(null))); return ResponseEntity.ok(systemRoleService.getRoleLevel());
} }
@ApiOperation("新增角色") @ApiOperation("新增角色")
@PostMapping(value = "/saveRole") @PostMapping(value = "/saveRole")
@PreAuthorize("@el.check('roles:add')") @PreAuthorize("@el.check('roles:add')")
public ResponseEntity<Void> saveRole(@Validated @RequestBody SystemCreateRoleArgs args) { public ResponseEntity<Void> saveRole(@Validated @RequestBody SystemCreateRoleArgs args) {
checkRoleLevels(args.getLevel());
systemRoleService.saveRole(args); systemRoleService.saveRole(args);
return ResponseEntity.ok(null); return ResponseEntity.ok(null);
} }
@@ -102,7 +96,6 @@ public class SystemRoleController {
@PostMapping(value = "/modifyRoleById") @PostMapping(value = "/modifyRoleById")
@PreAuthorize("@el.check('roles:edit')") @PreAuthorize("@el.check('roles:edit')")
public ResponseEntity<Void> modifyRoleById(@Validated(SystemRoleTb.Update.class) @RequestBody SystemRoleVo args) { public ResponseEntity<Void> modifyRoleById(@Validated(SystemRoleTb.Update.class) @RequestBody SystemRoleVo args) {
checkRoleLevels(args.getLevel());
systemRoleService.updateRoleById(args); systemRoleService.updateRoleById(args);
return ResponseEntity.ok(null); return ResponseEntity.ok(null);
} }
@@ -111,8 +104,6 @@ public class SystemRoleController {
@PostMapping(value = "/modifyBindMenuById") @PostMapping(value = "/modifyBindMenuById")
@PreAuthorize("@el.check('roles:edit')") @PreAuthorize("@el.check('roles:edit')")
public ResponseEntity<Void> modifyBindMenuById(@RequestBody SystemRoleVo args) { public ResponseEntity<Void> modifyBindMenuById(@RequestBody SystemRoleVo args) {
SystemRoleTb role = systemRoleService.getRoleById(args.getId());
checkRoleLevels(role.getLevel());
systemRoleService.updateBindMenuById(args); systemRoleService.updateBindMenuById(args);
return ResponseEntity.ok(null); return ResponseEntity.ok(null);
} }
@@ -121,30 +112,7 @@ public class SystemRoleController {
@PostMapping(value = "/removeRoleByIds") @PostMapping(value = "/removeRoleByIds")
@PreAuthorize("@el.check('roles:del')") @PreAuthorize("@el.check('roles:del')")
public ResponseEntity<Void> removeRoleByIds(@RequestBody Set<Long> ids) { public ResponseEntity<Void> removeRoleByIds(@RequestBody Set<Long> ids) {
for (Long id : ids) {
SystemRoleTb role = systemRoleService.getRoleById(id);
checkRoleLevels(role.getLevel());
}
// 验证是否被用户关联
systemRoleService.verifyBindRelationByIds(ids);
systemRoleService.deleteRoleByIds(ids); systemRoleService.deleteRoleByIds(ids);
return ResponseEntity.ok(null); return ResponseEntity.ok(null);
} }
/**
* 检查用户的角色级别
*
* @return /
*/
private int checkRoleLevels(Integer level) {
List<Integer> levels = systemRoleService.queryRoleByUsersId(KitSecurityHelper.getCurrentUserId()).stream()
.map(SystemRoleTb::getLevel).collect(Collectors.toList());
int min = Collections.min(levels);
if (level != null) {
if (level < min) {
throw new BadRequestException("权限不足, 你的角色级别:" + min + ", 低于操作的角色级别:" + level);
}
}
return min;
}
} }
@@ -15,15 +15,9 @@
*/ */
package cn.odboy.system.controller; package cn.odboy.system.controller;
import cn.hutool.core.collection.CollectionUtil;
import cn.odboy.base.KitPageArgs; import cn.odboy.base.KitPageArgs;
import cn.odboy.base.KitPageResult; import cn.odboy.base.KitPageResult;
import cn.odboy.base.KitSelectOptionVo; import cn.odboy.base.KitSelectOptionVo;
import cn.odboy.framework.exception.BadRequestException;
import cn.odboy.framework.properties.AppProperties;
import cn.odboy.system.constant.SystemCaptchaBizEnum;
import cn.odboy.system.dal.dataobject.SystemDeptTb;
import cn.odboy.system.dal.dataobject.SystemRoleTb;
import cn.odboy.system.dal.dataobject.SystemUserTb; import cn.odboy.system.dal.dataobject.SystemUserTb;
import cn.odboy.system.dal.model.SystemQueryUserArgs; import cn.odboy.system.dal.model.SystemQueryUserArgs;
import cn.odboy.system.dal.model.SystemUpdateUserPasswordArgs; import cn.odboy.system.dal.model.SystemUpdateUserPasswordArgs;
@@ -31,26 +25,17 @@ import cn.odboy.system.dal.model.SystemUserVo;
import cn.odboy.system.framework.permission.core.KitSecurityHelper; import cn.odboy.system.framework.permission.core.KitSecurityHelper;
import cn.odboy.system.service.SystemDataService; import cn.odboy.system.service.SystemDataService;
import cn.odboy.system.service.SystemDeptService; import cn.odboy.system.service.SystemDeptService;
import cn.odboy.system.service.SystemEmailService;
import cn.odboy.system.service.SystemRoleService;
import cn.odboy.system.service.SystemUserService; import cn.odboy.system.service.SystemUserService;
import cn.odboy.util.KitPageUtil;
import cn.odboy.util.KitRsaEncryptUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import java.io.IOException; import java.io.IOException;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
@@ -66,20 +51,13 @@ import org.springframework.web.multipart.MultipartFile;
@RequestMapping("/api/user") @RequestMapping("/api/user")
public class SystemUserController { public class SystemUserController {
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired @Autowired
private SystemUserService systemUserService; private SystemUserService systemUserService;
@Autowired @Autowired
private SystemDataService systemDataService; private SystemDataService systemDataService;
@Autowired @Autowired
private SystemDeptService systemDeptService; private SystemDeptService systemDeptService;
@Autowired
private SystemRoleService systemRoleService;
@Autowired
private SystemEmailService systemEmailService;
@Autowired
private AppProperties properties;
@ApiOperation("导出用户数据") @ApiOperation("导出用户数据")
@GetMapping(value = "/download") @GetMapping(value = "/download")
@@ -91,42 +69,16 @@ public class SystemUserController {
@ApiOperation("查询用户") @ApiOperation("查询用户")
@PostMapping @PostMapping
@PreAuthorize("@el.check('user:list')") @PreAuthorize("@el.check('user:list')")
public ResponseEntity<KitPageResult<SystemUserVo>> queryUserByArgs( public ResponseEntity<KitPageResult<SystemUserVo>> queryUserByArgs(@Validated @RequestBody KitPageArgs<SystemQueryUserArgs> pageArgs) {
@Validated @RequestBody KitPageArgs<SystemQueryUserArgs> pageArgs) { String currentUsername = KitSecurityHelper.getCurrentUsername();
Page<SystemUserTb> page = new Page<>(pageArgs.getPage(), pageArgs.getSize()); Page<SystemUserTb> page = new Page<>(pageArgs.getPage(), pageArgs.getSize());
SystemQueryUserArgs args = pageArgs.getArgs(); return ResponseEntity.ok(systemUserService.aggregationSearchUserByArgs(page, pageArgs.getArgs(), currentUsername));
if (!ObjectUtils.isEmpty(args.getDeptId())) {
args.getDeptIds().add(args.getDeptId());
// 先查找是否存在子节点
List<SystemDeptTb> data = systemDeptService.listDeptByPid(args.getDeptId());
// 然后把子节点的ID都加入到集合中
args.getDeptIds().addAll(systemDeptService.queryChildDeptIdByDeptIds(data));
}
// 数据权限
List<Long> dataScopes = systemDataService.queryDeptIdByArgs(
systemUserService.getUserByUsername(KitSecurityHelper.getCurrentUsername()));
// args.getDeptIds() 不为空并且数据权限不为空则取交集
if (!CollectionUtils.isEmpty(args.getDeptIds()) && !CollectionUtils.isEmpty(dataScopes)) {
// 取交集
args.getDeptIds().retainAll(dataScopes);
if (!CollectionUtil.isEmpty(args.getDeptIds())) {
return ResponseEntity.ok(systemUserService.searchUserByArgs(args, page));
}
} else {
// 否则取并集
args.getDeptIds().addAll(dataScopes);
return ResponseEntity.ok(systemUserService.searchUserByArgs(args, page));
}
return ResponseEntity.ok(KitPageUtil.emptyData());
} }
@ApiOperation("新增用户") @ApiOperation("新增用户")
@PostMapping(value = "/saveUser") @PostMapping(value = "/saveUser")
@PreAuthorize("@el.check('user:add')") @PreAuthorize("@el.check('user:add')")
public ResponseEntity<Object> saveUser(@Validated @RequestBody SystemUserVo args) { public ResponseEntity<Object> saveUser(@Validated @RequestBody SystemUserVo args) {
checkLevel(args);
// 默认密码 123456
args.setPassword(passwordEncoder.encode("123456"));
systemUserService.saveUser(args); systemUserService.saveUser(args);
return ResponseEntity.ok(null); return ResponseEntity.ok(null);
} }
@@ -135,18 +87,13 @@ public class SystemUserController {
@PostMapping(value = "/modifyUserById") @PostMapping(value = "/modifyUserById")
@PreAuthorize("@el.check('user:edit')") @PreAuthorize("@el.check('user:edit')")
public ResponseEntity<Object> modifyUserById(@Validated(SystemUserTb.Update.class) @RequestBody SystemUserVo args) { public ResponseEntity<Object> modifyUserById(@Validated(SystemUserTb.Update.class) @RequestBody SystemUserVo args) {
checkLevel(args);
systemUserService.updateUserById(args); systemUserService.updateUserById(args);
return ResponseEntity.ok(null); return ResponseEntity.ok(null);
} }
@ApiOperation("修改用户:个人中心") @ApiOperation("修改用户:个人中心")
@PostMapping(value = "modifyUserCenterInfoById") @PostMapping(value = "modifyUserCenterInfoById")
public ResponseEntity<Object> modifyUserCenterInfoById( public ResponseEntity<Object> modifyUserCenterInfoById(@Validated(SystemUserTb.Update.class) @RequestBody SystemUserTb args) {
@Validated(SystemUserTb.Update.class) @RequestBody SystemUserTb args) {
if (!args.getId().equals(KitSecurityHelper.getCurrentUserId())) {
throw new BadRequestException("不能修改他人资料");
}
systemUserService.updateUserCenterInfoById(args); systemUserService.updateUserCenterInfoById(args);
return ResponseEntity.ok(null); return ResponseEntity.ok(null);
} }
@@ -155,46 +102,22 @@ public class SystemUserController {
@PostMapping(value = "/removeUserByIds") @PostMapping(value = "/removeUserByIds")
@PreAuthorize("@el.check('user:del')") @PreAuthorize("@el.check('user:del')")
public ResponseEntity<Object> removeUserByIds(@RequestBody Set<Long> ids) { public ResponseEntity<Object> removeUserByIds(@RequestBody Set<Long> ids) {
for (Long id : ids) {
Integer currentLevel = Collections.min(
systemRoleService.queryRoleByUsersId(KitSecurityHelper.getCurrentUserId()).stream()
.map(SystemRoleTb::getLevel).collect(Collectors.toList()));
Integer optLevel = Collections.min(
systemRoleService.queryRoleByUsersId(id).stream().map(SystemRoleTb::getLevel)
.collect(Collectors.toList()));
if (currentLevel > optLevel) {
throw new BadRequestException(
"角色权限不足, 不能删除:" + systemUserService.getUserById(id).getUsername());
}
}
systemUserService.removeUserByIds(ids); systemUserService.removeUserByIds(ids);
return ResponseEntity.ok(null); return ResponseEntity.ok(null);
} }
@ApiOperation("修改密码") @ApiOperation("修改密码")
@PostMapping(value = "/modifyUserPasswordByUsername") @PostMapping(value = "/modifyUserPasswordByUsername")
public ResponseEntity<Object> modifyUserPasswordByUsername(@RequestBody SystemUpdateUserPasswordArgs passVo) public ResponseEntity<Object> modifyUserPasswordByUsername(@RequestBody SystemUpdateUserPasswordArgs passVo) throws Exception {
throws Exception { String currentUsername = KitSecurityHelper.getCurrentUsername();
String oldPass = systemUserService.updateUserPasswordByUsername(currentUsername, passVo);
KitRsaEncryptUtil.decryptByPrivateKey(properties.getRsa().getPrivateKey(), passVo.getOldPass());
String newPass =
KitRsaEncryptUtil.decryptByPrivateKey(properties.getRsa().getPrivateKey(), passVo.getNewPass());
SystemUserTb user = systemUserService.getUserByUsername(KitSecurityHelper.getCurrentUsername());
if (!passwordEncoder.matches(oldPass, user.getPassword())) {
throw new BadRequestException("修改失败,旧密码错误");
}
if (passwordEncoder.matches(newPass, user.getPassword())) {
throw new BadRequestException("新密码不能与旧密码相同");
}
systemUserService.updateUserPasswordByUsername(user.getUsername(), passwordEncoder.encode(newPass));
return ResponseEntity.ok(null); return ResponseEntity.ok(null);
} }
@ApiOperation("重置密码") @ApiOperation("重置密码")
@PostMapping(value = "/resetUserPasswordByIds") @PostMapping(value = "/resetUserPasswordByIds")
public ResponseEntity<Object> resetUserPasswordByIds(@RequestBody Set<Long> ids) { public ResponseEntity<Object> resetUserPasswordByIds(@RequestBody Set<Long> ids) {
String defaultPwd = passwordEncoder.encode("123456"); systemUserService.resetUserPasswordByIds(ids);
systemUserService.resetUserPasswordByIds(ids, defaultPwd);
return ResponseEntity.ok(null); return ResponseEntity.ok(null);
} }
@@ -206,34 +129,12 @@ public class SystemUserController {
@ApiOperation("修改邮箱") @ApiOperation("修改邮箱")
@PostMapping(value = "/modifyUserEmailByUsername/{code}") @PostMapping(value = "/modifyUserEmailByUsername/{code}")
public ResponseEntity<Object> modifyUserEmailByUsername(@PathVariable String code, @RequestBody SystemUserTb args) public ResponseEntity<Object> modifyUserEmailByUsername(@PathVariable String code, @RequestBody SystemUserTb args) throws Exception {
throws Exception { String currentUsername = KitSecurityHelper.getCurrentUsername();
String password = systemUserService.updateUserEmailByUsername(currentUsername, args, code);
KitRsaEncryptUtil.decryptByPrivateKey(properties.getRsa().getPrivateKey(), args.getPassword());
SystemUserTb user = systemUserService.getUserByUsername(KitSecurityHelper.getCurrentUsername());
if (!passwordEncoder.matches(password, user.getPassword())) {
throw new BadRequestException("密码错误");
}
systemEmailService.checkEmailCaptcha(SystemCaptchaBizEnum.EMAIL_RESET_EMAIL_CODE, args.getEmail(), code);
systemUserService.updateUserEmailByUsername(user.getUsername(), args.getEmail());
return ResponseEntity.ok(null); return ResponseEntity.ok(null);
} }
/**
* 如果当前用户的角色级别低于创建用户的角色级别,则抛出权限不足的错误
*
* @param args /
*/
private void checkLevel(SystemUserVo args) {
Integer currentLevel = Collections.min(
systemRoleService.queryRoleByUsersId(KitSecurityHelper.getCurrentUserId()).stream()
.map(SystemRoleTb::getLevel).collect(Collectors.toList()));
Integer optLevel = systemRoleService.getDeptLevelByRoles(args.getRoles());
if (currentLevel > optLevel) {
throw new BadRequestException("角色权限不足");
}
}
@ApiOperation("查询用户基础数据") @ApiOperation("查询用户基础数据")
@PostMapping(value = "/queryUserMetadataOptions") @PostMapping(value = "/queryUserMetadataOptions")
@PreAuthorize("@el.check('user:list')") @PreAuthorize("@el.check('user:list')")
@@ -15,14 +15,9 @@
*/ */
package cn.odboy.system.dal.mysql; package cn.odboy.system.dal.mysql;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.odboy.system.dal.dataobject.SystemDeptTb; import cn.odboy.system.dal.dataobject.SystemDeptTb;
import cn.odboy.system.dal.model.SystemQueryDeptArgs;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import java.util.List;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
/** /**
@@ -30,5 +30,6 @@ import org.apache.ibatis.annotations.Param;
*/ */
@Mapper @Mapper
public interface SystemDictDetailMapper extends BaseMapper<SystemDictDetailTb> { public interface SystemDictDetailMapper extends BaseMapper<SystemDictDetailTb> {
IPage<SystemDictDetailTb> selectPageByArgs(Page<SystemDictDetailTb> page, @Param("args") SystemQueryDictDetailArgs args); IPage<SystemDictDetailTb> selectPageByArgs(Page<SystemDictDetailTb> page, @Param("args") SystemQueryDictDetailArgs args);
} }
@@ -15,14 +15,9 @@
*/ */
package cn.odboy.system.dal.mysql; package cn.odboy.system.dal.mysql;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.odboy.system.dal.dataobject.SystemUserTb; import cn.odboy.system.dal.dataobject.SystemUserTb;
import cn.odboy.system.dal.model.SystemQueryUserArgs;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import java.util.List;
import java.util.Set; import java.util.Set;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
@@ -20,6 +20,7 @@ import java.util.Date;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
@@ -157,4 +158,12 @@ public class SystemUserOnlineInfoDAO {
public SystemUserOnlineVo queryUserOnlineModelByKey(String key) { public SystemUserOnlineVo queryUserOnlineModelByKey(String key) {
return redisHelper.get(key, SystemUserOnlineVo.class); return redisHelper.get(key, SystemUserOnlineVo.class);
} }
public void kickOutUser(Set<String> keys) throws Exception {
for (String token : keys) {
// 解密Key
token = KitDesEncryptUtil.desDecrypt(token);
this.logoutByToken(token);
}
}
} }
@@ -0,0 +1,117 @@
package cn.odboy.system.service;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.odboy.constant.CaptchaCodeEnum;
import cn.odboy.constant.SystemConst;
import cn.odboy.framework.exception.BadRequestException;
import cn.odboy.framework.properties.AppProperties;
import cn.odboy.framework.redis.KitRedisHelper;
import cn.odboy.system.dal.model.SystemUserInfoVo;
import cn.odboy.system.dal.model.SystemUserJwtVo;
import cn.odboy.system.dal.model.SystemUserLoginArgs;
import cn.odboy.system.dal.redis.SystemCacheKey;
import cn.odboy.system.dal.redis.SystemUserOnlineInfoDAO;
import cn.odboy.system.framework.permission.core.KitSecurityHelper;
import cn.odboy.system.framework.permission.core.handler.TokenProvider;
import cn.odboy.system.framework.permission.core.handler.UserDetailsHandler;
import cn.odboy.util.KitRsaEncryptUtil;
import com.wf.captcha.base.Captcha;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
@Service
public class SystemAuthService {
@Autowired
private KitRedisHelper redisHelper;
@Autowired
private SystemUserOnlineInfoDAO systemUserOnlineInfoDAO;
@Autowired
private TokenProvider tokenProvider;
@Autowired
private AppProperties properties;
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private UserDetailsHandler userDetailsService;
public Map<String, Object> doLogin(SystemUserLoginArgs loginRequest, HttpServletRequest request) throws Exception {
// 密码解密
String password =
KitRsaEncryptUtil.decryptByPrivateKey(properties.getRsa().getPrivateKey(), loginRequest.getPassword());
// 查询验证码
String code = redisHelper.get(loginRequest.getUuid(), String.class);
// 清除验证码
redisHelper.del(loginRequest.getUuid());
if (StrUtil.isBlank(code)) {
throw new BadRequestException("验证码不存在或已过期");
}
if (StrUtil.isBlank(loginRequest.getCode()) || !loginRequest.getCode().equalsIgnoreCase(code)) {
throw new BadRequestException("验证码错误");
}
// 获取用户信息
SystemUserJwtVo jwtUser = userDetailsService.loadUserByUsername(loginRequest.getUsername());
// 验证用户密码
if (!passwordEncoder.matches(password, jwtUser.getPassword())) {
throw new BadRequestException("登录密码错误");
}
Authentication authentication =
new UsernamePasswordAuthenticationToken(jwtUser, null, jwtUser.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication);
// 生成令牌
String token = tokenProvider.createToken(jwtUser);
// 返回 token 与 用户信息
Map<String, Object> authInfo = new HashMap<>(2) {{
put("token", String.format("%s %s", SystemConst.TOKEN_PREFIX, token));
put("user", BeanUtil.copyProperties(jwtUser, SystemUserInfoVo.class));
}};
if (properties.getLogin().isSingle()) {
// 踢掉之前已经登录的token
systemUserOnlineInfoDAO.kickOutByUsername(loginRequest.getUsername());
}
// 保存在线信息
systemUserOnlineInfoDAO.saveUserJwtModelByToken(jwtUser, token, request);
// 返回登录信息
return authInfo;
}
public SystemUserInfoVo getCurrentUserInfoVo() {
SystemUserJwtVo jwtUser = (SystemUserJwtVo) KitSecurityHelper.getCurrentUser();
return BeanUtil.copyProperties(jwtUser, SystemUserInfoVo.class);
}
public Map<String, Object> getCaptchaInfo() {
// 获取运算的结果
Captcha captcha = properties.getLogin().getCaptchaSetting().getCaptcha();
String uuid = SystemCacheKey.CAPTCHA_LOGIN + IdUtil.simpleUUID();
//当验证码类型为 arithmetic时且长度 >= 2 时, captcha.text()的结果有几率为浮点型
String captchaValue = captcha.text();
if (captcha.getCharType() - 1 == CaptchaCodeEnum.ARITHMETIC.ordinal() &&
captchaValue.contains(SystemConst.SYMBOL_DOT)) {
captchaValue = captchaValue.split("\\.")[0];
}
// 保存
redisHelper.set(uuid, captchaValue, properties.getLogin().getCaptchaSetting().getExpiration(),
TimeUnit.MINUTES);
// 验证码信息
return new HashMap<>(2) {{
put("img", captcha.toBase64());
put("uuid", uuid);
}};
}
public void doLogout(HttpServletRequest request) {
String token = tokenProvider.getToken(request);
systemUserOnlineInfoDAO.logoutByToken(token);
}
}
@@ -37,7 +37,7 @@ import org.springframework.stereotype.Service;
public class SystemDataService { public class SystemDataService {
@Autowired @Autowired
private SystemRoleService systemRoleService; private SystemUserRoleService systemUserRoleService;
@Autowired @Autowired
private SystemDeptService systemDeptService; private SystemDeptService systemDeptService;
@Autowired @Autowired
@@ -52,7 +52,7 @@ public class SystemDataService {
public List<Long> queryDeptIdByArgs(SystemUserTb user) { public List<Long> queryDeptIdByArgs(SystemUserTb user) {
List<Long> deptIds = new ArrayList<>(); List<Long> deptIds = new ArrayList<>();
// 查询用户角色 // 查询用户角色
List<SystemRoleVo> roleList = systemRoleService.queryRoleByUsersId(user.getId()); List<SystemRoleVo> roleList = systemUserRoleService.queryRoleByUsersId(user.getId());
// 获取对应的部门ID // 获取对应的部门ID
for (SystemRoleTb role : roleList) { for (SystemRoleTb role : roleList) {
SystemDataScopeEnum dataScopeEnum = SystemDataScopeEnum.find(role.getDataScope()); SystemDataScopeEnum dataScopeEnum = SystemDataScopeEnum.find(role.getDataScope());
@@ -57,9 +57,9 @@ public class SystemDeptService {
@Autowired @Autowired
private SystemDeptMapper systemDeptMapper; private SystemDeptMapper systemDeptMapper;
@Autowired @Autowired
private SystemUserService systemUserService; private SystemUserDeptService systemUserDeptService;
@Autowired @Autowired
private SystemRoleService systemRoleService; private SystemRoleDeptService systemRoleDeptService;
/** /**
* 创建 * 创建
@@ -95,11 +95,15 @@ public class SystemDeptService {
/** /**
* 删除 * 删除
* *
* @param deptSet / * @param ids /
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void deleteDeptByIds(Set<SystemDeptTb> deptSet) { public void deleteDeptByIds(Set<Long> ids) {
for (SystemDeptTb dept : deptSet) { // 获取部门, 和其所有子部门
Set<SystemDeptTb> depts = this.traverseDeptByIdWithPids(ids);
// 验证是否被角色或用户关联
this.verifyBindRelationByIds(depts);
for (SystemDeptTb dept : depts) {
systemDeptMapper.deleteById(dept.getId()); systemDeptMapper.deleteById(dept.getId());
this.updateDeptSubCnt(dept.getPid()); this.updateDeptSubCnt(dept.getPid());
} }
@@ -347,10 +351,10 @@ public class SystemDeptService {
*/ */
public void verifyBindRelationByIds(Set<SystemDeptTb> deptSet) { public void verifyBindRelationByIds(Set<SystemDeptTb> deptSet) {
Set<Long> deptIds = deptSet.stream().map(SystemDeptTb::getId).collect(Collectors.toSet()); Set<Long> deptIds = deptSet.stream().map(SystemDeptTb::getId).collect(Collectors.toSet());
if (systemUserService.countUserByDeptIds(deptIds) > 0) { if (systemUserDeptService.countUserByDeptIds(deptIds) > 0) {
throw new BadRequestException("所选部门存在用户关联,请解除后再试!"); throw new BadRequestException("所选部门存在用户关联,请解除后再试!");
} }
if (systemRoleService.countRoleByDeptIds(deptIds) > 0) { if (systemRoleDeptService.countRoleByDeptIds(deptIds) > 0) {
throw new BadRequestException("所选部门存在角色关联,请解除后再试!"); throw new BadRequestException("所选部门存在角色关联,请解除后再试!");
} }
} }
@@ -31,6 +31,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@@ -134,4 +135,13 @@ public class SystemDictDetailService {
return detailVo; return detailVo;
}).collect(Collectors.toList()); }).collect(Collectors.toList());
} }
public Map<String, List<SystemDictDetailVo>> getDictDetailMap(String dictName) {
String[] names = dictName.split("[,, ]");
Map<String, List<SystemDictDetailVo>> dictMap = new HashMap<>(16);
for (String name : names) {
dictMap.put(name, this.listDictDetailByName(name));
}
return dictMap;
}
} }
@@ -24,6 +24,7 @@ import cn.odboy.framework.properties.AppProperties;
import cn.odboy.framework.redis.KitRedisHelper; import cn.odboy.framework.redis.KitRedisHelper;
import cn.odboy.system.constant.SystemCaptchaBizEnum; import cn.odboy.system.constant.SystemCaptchaBizEnum;
import cn.odboy.system.dal.dataobject.SystemEmailConfigTb; import cn.odboy.system.dal.dataobject.SystemEmailConfigTb;
import cn.odboy.system.dal.model.SystemCheckEmailCaptchaArgs;
import cn.odboy.system.dal.model.SystemSendEmailArgs; import cn.odboy.system.dal.model.SystemSendEmailArgs;
import cn.odboy.system.dal.mysql.SystemEmailConfigMapper; import cn.odboy.system.dal.mysql.SystemEmailConfigMapper;
import cn.odboy.util.KitDesEncryptUtil; import cn.odboy.util.KitDesEncryptUtil;
@@ -112,7 +113,7 @@ public class SystemEmailService {
/** /**
* 校验邮箱验证码 * 校验邮箱验证码
*/ */
public void checkEmailCaptcha(SystemCaptchaBizEnum biEnum, String email, String code) { public void checkEmailCaptchaV1(SystemCaptchaBizEnum biEnum, String email, String code) {
String redisKey = biEnum.getRedisKey() + email; String redisKey = biEnum.getRedisKey() + email;
String value = redisHelper.get(redisKey, String.class); String value = redisHelper.get(redisKey, String.class);
if (value == null || !value.equals(code)) { if (value == null || !value.equals(code)) {
@@ -153,4 +154,12 @@ public class SystemEmailService {
SystemEmailConfigTb systemEmailConfigTb = systemEmailConfigMapper.selectById(1L); SystemEmailConfigTb systemEmailConfigTb = systemEmailConfigMapper.selectById(1L);
return systemEmailConfigTb == null ? new SystemEmailConfigTb() : systemEmailConfigTb; return systemEmailConfigTb == null ? new SystemEmailConfigTb() : systemEmailConfigTb;
} }
public void checkEmailCaptcha(SystemCheckEmailCaptchaArgs args) {
SystemCaptchaBizEnum biEnum = SystemCaptchaBizEnum.getByBizCode(args.getBizCode());
if (biEnum == null) {
throw new BadRequestException("不支持的业务");
}
this.checkEmailCaptchaV1(biEnum, args.getEmail(), args.getCode());
}
} }
@@ -84,6 +84,8 @@ public class SystemJobService {
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void deleteJobByIds(Set<Long> ids) { public void deleteJobByIds(Set<Long> ids) {
// 验证是否被用户关联
this.verifyBindRelationByIds(ids);
systemJobMapper.deleteByIds(ids); systemJobMapper.deleteByIds(ids);
} }
@@ -21,6 +21,8 @@ import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.IORuntimeException; import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.odboy.base.KitPageResult; import cn.odboy.base.KitPageResult;
import cn.odboy.constant.FileTypeEnum;
import cn.odboy.framework.context.KitSpringBeanHolder;
import cn.odboy.framework.exception.BadRequestException; import cn.odboy.framework.exception.BadRequestException;
import cn.odboy.framework.properties.AppProperties; import cn.odboy.framework.properties.AppProperties;
import cn.odboy.framework.server.core.KitFileLocalUploadHelper; import cn.odboy.framework.server.core.KitFileLocalUploadHelper;
@@ -180,4 +182,14 @@ public class SystemLocalStorageService {
this.injectQueryParams(args, wrapper); this.injectQueryParams(args, wrapper);
return systemLocalStorageMapper.selectList(wrapper); return systemLocalStorageMapper.selectList(wrapper);
} }
public SystemLocalStorageTb uploadPictureV1(MultipartFile file) {
// 判断文件是否为图片
String suffix = KitFileUtil.getSuffix(file.getOriginalFilename());
if (!FileTypeEnum.IMAGE.getCode().equals(KitFileUtil.getFileType(suffix))) {
throw new BadRequestException("只能上传图片");
}
return KitSpringBeanHolder.getBean(SystemLocalStorageService.class).uploadFile(null, file);
}
} }
@@ -31,6 +31,7 @@ import cn.odboy.system.dal.model.SystemQueryMenuArgs;
import cn.odboy.system.dal.model.SystemRoleVo; import cn.odboy.system.dal.model.SystemRoleVo;
import cn.odboy.system.dal.mysql.SystemMenuMapper; import cn.odboy.system.dal.mysql.SystemMenuMapper;
import cn.odboy.system.dal.mysql.SystemRoleMenuMapper; import cn.odboy.system.dal.mysql.SystemRoleMenuMapper;
import cn.odboy.system.framework.permission.core.KitSecurityHelper;
import cn.odboy.util.KitClassUtil; import cn.odboy.util.KitClassUtil;
import cn.odboy.util.KitFileUtil; import cn.odboy.util.KitFileUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@@ -40,6 +41,7 @@ import java.lang.reflect.Field;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -64,6 +66,8 @@ public class SystemMenuService {
private SystemRoleService systemRoleService; private SystemRoleService systemRoleService;
@Autowired @Autowired
private SystemRoleMenuService systemRoleMenuService; private SystemRoleMenuService systemRoleMenuService;
@Autowired
private SystemUserRoleService systemUserRoleService;
/** /**
* 创建 * 创建
@@ -251,7 +255,7 @@ public class SystemMenuService {
* @return / * @return /
*/ */
public List<SystemMenuTb> listMenuByUserId(Long currentUserId) { public List<SystemMenuTb> listMenuByUserId(Long currentUserId) {
List<SystemRoleVo> roles = systemRoleService.queryRoleByUsersId(currentUserId); List<SystemRoleVo> roles = systemUserRoleService.queryRoleByUsersId(currentUserId);
Set<Long> roleIds = roles.stream().map(SystemRoleTb::getId).collect(Collectors.toSet()); Set<Long> roleIds = roles.stream().map(SystemRoleTb::getId).collect(Collectors.toSet());
return new ArrayList<>(systemRoleMenuService.queryMenuByRoleIds(roleIds)); return new ArrayList<>(systemRoleMenuService.queryMenuByRoleIds(roleIds));
} }
@@ -454,4 +458,41 @@ public class SystemMenuService {
wrapper.orderByAsc(SystemMenuTb::getMenuSort); wrapper.orderByAsc(SystemMenuTb::getMenuSort);
return systemMenuMapper.selectList(wrapper); return systemMenuMapper.selectList(wrapper);
} }
public List<SystemMenuVo> buildFrontMenus() {
List<SystemMenuTb> menuList = this.listMenuByUserId(KitSecurityHelper.getCurrentUserId());
List<SystemMenuTb> menus = this.buildMenuTree(menuList);
return this.buildMenuVo(menus);
}
public Set<Long> listChildMenuSetByMenuId(Long id) {
Set<SystemMenuTb> menuSet = new HashSet<>();
List<SystemMenuTb> menuList = this.listMenuByPid(id);
menuSet.add(systemMenuMapper.selectById(id));
menuSet = this.queryChildMenuByArgs(menuList, menuSet);
return menuSet.stream().map(SystemMenuTb::getId).collect(Collectors.toSet());
}
public List<SystemMenuTb> listMenuSuperior(List<Long> ids) {
Set<SystemMenuTb> menus;
List<SystemMenuTb> systemMenuTbs;
if (CollectionUtil.isNotEmpty(ids)) {
menus = new LinkedHashSet<>(this.listMenuByIds(ids));
for (SystemMenuTb menu : menus) {
List<SystemMenuTb> menuList = this.querySuperiorMenuByArgs(menu, new ArrayList<>());
for (SystemMenuTb data : menuList) {
if (data.getId().equals(menu.getPid())) {
data.setSubCount(data.getSubCount() - 1);
}
}
menus.addAll(menuList);
}
// 编辑菜单时不显示自己以及自己下级的数据, 避免出现PID数据环形问题
menus = menus.stream().filter(i -> !ids.contains(i.getId())).collect(Collectors.toSet());
systemMenuTbs = this.buildMenuTree(new ArrayList<>(menus));
} else {
systemMenuTbs = this.listMenuByPid(null);
}
return systemMenuTbs;
}
} }
@@ -20,6 +20,7 @@ import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.odboy.base.KitPageResult; import cn.odboy.base.KitPageResult;
import cn.odboy.framework.context.KitSpringBeanHolder;
import cn.odboy.framework.exception.BadRequestException; import cn.odboy.framework.exception.BadRequestException;
import cn.odboy.framework.redis.KitRedisHelper; import cn.odboy.framework.redis.KitRedisHelper;
import cn.odboy.system.dal.dataobject.SystemQuartzJobTb; import cn.odboy.system.dal.dataobject.SystemQuartzJobTb;
@@ -58,6 +59,19 @@ public class SystemQuartzJobService {
@Autowired @Autowired
private KitRedisHelper redisHelper; private KitRedisHelper redisHelper;
/**
* 验证Bean是不是合法的, 合法的定时任务 Bean 需要用 @Service 定义
*
* @param beanName Bean名称
*/
private void checkBean(String beanName) {
// 避免调用攻击者可以从SpringContextHolder获得控制jdbcTemplate类
// 并使用getDeclaredMethod调用jdbcTemplate的queryForMap函数,执行任意sql命令。
if (!KitSpringBeanHolder.getAllServiceBeanName().contains(beanName)) {
throw new BadRequestException("非法的 Bean,请重新输入!");
}
}
/** /**
* 创建 * 创建
* *
@@ -65,6 +79,11 @@ public class SystemQuartzJobService {
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void createJob(SystemQuartzJobTb args) { public void createJob(SystemQuartzJobTb args) {
if (args.getId() != null) {
throw new BadRequestException("无效参数id");
}
// 验证Bean是不是合法的, 合法的定时任务 Bean 需要用 @Service 定义
checkBean(args.getBeanName());
if (!CronExpression.isValidExpression(args.getCronExpression())) { if (!CronExpression.isValidExpression(args.getCronExpression())) {
throw new BadRequestException("cron表达式格式错误"); throw new BadRequestException("cron表达式格式错误");
} }
@@ -79,6 +98,8 @@ public class SystemQuartzJobService {
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void updateQuartzJobResumeCron(SystemUpdateQuartzJobArgs args) { public void updateQuartzJobResumeCron(SystemUpdateQuartzJobArgs args) {
// 验证Bean是不是合法的, 合法的定时任务 Bean 需要用 @Service 定义
checkBean(args.getBeanName());
if (!CronExpression.isValidExpression(args.getCronExpression())) { if (!CronExpression.isValidExpression(args.getCronExpression())) {
throw new BadRequestException("cron表达式格式错误"); throw new BadRequestException("cron表达式格式错误");
} }
@@ -76,4 +76,20 @@ public class SystemRoleDeptService {
List<Long> deptIds = systemRoleDeptTbs.stream().map(SystemRoleDeptTb::getDeptId).collect(Collectors.toList()); List<Long> deptIds = systemRoleDeptTbs.stream().map(SystemRoleDeptTb::getDeptId).collect(Collectors.toList());
return systemDeptMapper.selectByIds(deptIds); return systemDeptMapper.selectByIds(deptIds);
} }
/**
* 根据部门ID统计角色数量
*
* @param deptIds 部门ID集合
* @return /
*/
public Long countRoleByDeptIds(Set<Long> deptIds) {
if (CollUtil.isEmpty(deptIds)) {
return 0L;
}
LambdaQueryWrapper<SystemRoleDeptTb> wrapper = new LambdaQueryWrapper<>();
wrapper.in(SystemRoleDeptTb::getDeptId, deptIds);
return systemRoleDeptMapper.selectCount(wrapper);
}
} }
@@ -18,24 +18,19 @@ package cn.odboy.system.service;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.odboy.base.KitPageResult; import cn.odboy.base.KitPageResult;
import cn.odboy.framework.exception.BadRequestException; import cn.odboy.framework.exception.BadRequestException;
import cn.odboy.system.dal.dataobject.SystemDeptTb;
import cn.odboy.system.dal.dataobject.SystemMenuTb; import cn.odboy.system.dal.dataobject.SystemMenuTb;
import cn.odboy.system.dal.dataobject.SystemRoleDeptTb;
import cn.odboy.system.dal.dataobject.SystemRoleMenuTb;
import cn.odboy.system.dal.dataobject.SystemRoleTb; import cn.odboy.system.dal.dataobject.SystemRoleTb;
import cn.odboy.system.dal.dataobject.SystemUserRoleTb;
import cn.odboy.system.dal.dataobject.SystemUserTb; import cn.odboy.system.dal.dataobject.SystemUserTb;
import cn.odboy.system.dal.model.SystemCreateRoleArgs; import cn.odboy.system.dal.model.SystemCreateRoleArgs;
import cn.odboy.system.dal.model.SystemQueryRoleArgs; import cn.odboy.system.dal.model.SystemQueryRoleArgs;
import cn.odboy.system.dal.model.SystemRoleCodeVo; import cn.odboy.system.dal.model.SystemRoleCodeVo;
import cn.odboy.system.dal.model.SystemRoleVo; import cn.odboy.system.dal.model.SystemRoleVo;
import cn.odboy.system.dal.mysql.SystemRoleDeptMapper;
import cn.odboy.system.dal.mysql.SystemRoleMapper; import cn.odboy.system.dal.mysql.SystemRoleMapper;
import cn.odboy.system.dal.mysql.SystemRoleMenuMapper; import cn.odboy.system.framework.permission.core.KitSecurityHelper;
import cn.odboy.system.dal.mysql.SystemUserRoleMapper;
import cn.odboy.util.KitFileUtil; import cn.odboy.util.KitFileUtil;
import cn.odboy.util.KitPageUtil; import cn.odboy.util.KitPageUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@@ -45,7 +40,6 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@@ -57,6 +51,7 @@ import org.springframework.transaction.annotation.Transactional;
@Service @Service
public class SystemRoleService { public class SystemRoleService {
@Autowired @Autowired
private SystemRoleMapper systemRoleMapper; private SystemRoleMapper systemRoleMapper;
@Autowired @Autowired
@@ -64,11 +59,9 @@ public class SystemRoleService {
@Autowired @Autowired
private SystemRoleDeptService systemRoleDeptService; private SystemRoleDeptService systemRoleDeptService;
@Autowired @Autowired
private SystemRoleDeptMapper systemRoleDeptMapper;
@Autowired
private SystemUserRoleMapper systemUserRoleMapper;
@Autowired
private SystemUserService systemUserService; private SystemUserService systemUserService;
@Autowired
private SystemUserRoleService systemUserRoleService;
/** /**
* 创建 * 创建
@@ -77,6 +70,7 @@ public class SystemRoleService {
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void saveRole(SystemCreateRoleArgs args) { public void saveRole(SystemCreateRoleArgs args) {
checkRoleLevels(args.getLevel());
if (this.getRoleByName(args.getName()) != null) { if (this.getRoleByName(args.getName()) != null) {
throw new BadRequestException("角色名称已存在"); throw new BadRequestException("角色名称已存在");
} }
@@ -100,6 +94,7 @@ public class SystemRoleService {
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void updateRoleById(SystemRoleVo args) { public void updateRoleById(SystemRoleVo args) {
checkRoleLevels(args.getLevel());
SystemRoleVo role = BeanUtil.copyProperties(systemRoleMapper.selectById(args.getId()), SystemRoleVo.class); SystemRoleVo role = BeanUtil.copyProperties(systemRoleMapper.selectById(args.getId()), SystemRoleVo.class);
SystemRoleTb role1 = this.getRoleByName(args.getName()); SystemRoleTb role1 = this.getRoleByName(args.getName());
if (role1 != null && !role1.getId().equals(role.getId())) { if (role1 != null && !role1.getId().equals(role.getId())) {
@@ -123,14 +118,16 @@ public class SystemRoleService {
/** /**
* 修改绑定的菜单 * 修改绑定的菜单
* *
* @param role / * @param args /
*/ */
public void updateBindMenuById(SystemRoleVo role) { public void updateBindMenuById(SystemRoleVo args) {
SystemRoleTb role = systemRoleMapper.selectById(args.getId());
checkRoleLevels(role.getLevel());
// 更新菜单 // 更新菜单
systemRoleMenuService.deleteRoleMenuByRoleId(role.getId()); systemRoleMenuService.deleteRoleMenuByRoleId(role.getId());
// 判断是否为空 // 判断是否为空
if (CollUtil.isNotEmpty(role.getMenus())) { if (CollUtil.isNotEmpty(args.getMenus())) {
systemRoleMenuService.batchInsertRoleMenu(role.getMenus(), role.getId()); systemRoleMenuService.batchInsertRoleMenu(args.getMenus(), role.getId());
} }
} }
@@ -141,6 +138,13 @@ public class SystemRoleService {
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void deleteRoleByIds(Set<Long> ids) { public void deleteRoleByIds(Set<Long> ids) {
List<Integer> roleLevels = systemRoleMapper.selectByIds(ids).stream().map(SystemRoleTb::getLevel).distinct().collect(Collectors.toList());
for (Integer roleLevel : roleLevels) {
checkRoleLevels(roleLevel);
}
// 验证是否被用户关联
this.verifyBindRelationByIds(ids);
// 删除角色
systemRoleMapper.deleteByIds(ids); systemRoleMapper.deleteByIds(ids);
// 删除角色部门关联数据、角色菜单关联数据 // 删除角色部门关联数据、角色菜单关联数据
systemRoleDeptService.batchDeleteRoleDept(ids); systemRoleDeptService.batchDeleteRoleDept(ids);
@@ -152,7 +156,6 @@ public class SystemRoleService {
* *
* @param roles 待导出的数据 * @param roles 待导出的数据
* @param response / * @param response /
* @throws IOException
*/ */
public void exportRoleExcel(List<SystemRoleVo> roles, HttpServletResponse response) throws IOException { public void exportRoleExcel(List<SystemRoleVo> roles, HttpServletResponse response) throws IOException {
List<Map<String, Object>> list = new ArrayList<>(); List<Map<String, Object>> list = new ArrayList<>();
@@ -180,7 +183,7 @@ public class SystemRoleService {
* 根据条件查询全部角色 * 根据条件查询全部角色
* *
* @param args 条件 * @param args 条件
* @return * @return /
*/ */
public List<SystemRoleVo> queryRoleByArgs(SystemQueryRoleArgs args) { public List<SystemRoleVo> queryRoleByArgs(SystemQueryRoleArgs args) {
// 查询角色基本信息 // 查询角色基本信息
@@ -199,10 +202,10 @@ public class SystemRoleService {
Page<SystemRoleTb> rolePage = new Page<>(args.getPage(), args.getSize()); Page<SystemRoleTb> rolePage = new Page<>(args.getPage(), args.getSize());
Page<SystemRoleTb> page = systemRoleMapper.selectPage(rolePage, wrapper); Page<SystemRoleTb> page = systemRoleMapper.selectPage(rolePage, wrapper);
List<SystemRoleTb> roles = page.getRecords(); List<SystemRoleTb> roles = page.getRecords();
return roles.stream().map(this::convertToRoleVo).collect(Collectors.toList()); return roles.stream().map(systemUserRoleService::convertToRoleVo).collect(Collectors.toList());
} else { } else {
List<SystemRoleTb> roles = systemRoleMapper.selectList(wrapper); List<SystemRoleTb> roles = systemRoleMapper.selectList(wrapper);
return roles.stream().map(this::convertToRoleVo).collect(Collectors.toList()); return roles.stream().map(systemUserRoleService::convertToRoleVo).collect(Collectors.toList());
} }
} }
@@ -211,7 +214,7 @@ public class SystemRoleService {
* *
* @param args 条件 * @param args 条件
* @param page 分页参数 * @param page 分页参数
* @return * @return /
*/ */
public KitPageResult<SystemRoleVo> searchRoleByArgs(SystemQueryRoleArgs args, Page<Object> page) { public KitPageResult<SystemRoleVo> searchRoleByArgs(SystemQueryRoleArgs args, Page<Object> page) {
args.setOffset(page.offset()); args.setOffset(page.offset());
@@ -220,41 +223,6 @@ public class SystemRoleService {
return KitPageUtil.toPage(roles, total); return KitPageUtil.toPage(roles, total);
} }
/**
* 根据用户ID查询
*
* @param userId 用户ID
* @return /
*/
public List<SystemRoleVo> queryRoleByUsersId(Long userId) {
// 查询用户角色关联
LambdaQueryWrapper<SystemUserRoleTb> userRoleWrapper = new LambdaQueryWrapper<>();
userRoleWrapper.eq(SystemUserRoleTb::getUserId, userId);
List<SystemUserRoleTb> userRoles = systemUserRoleMapper.selectList(userRoleWrapper);
if (CollUtil.isEmpty(userRoles)) {
return new ArrayList<>();
}
Set<Long> roleIds = userRoles.stream().map(SystemUserRoleTb::getRoleId).collect(Collectors.toSet());
List<SystemRoleTb> roles = systemRoleMapper.selectByIds(roleIds);
return roles.stream().map(this::convertToRoleVo).collect(Collectors.toList());
}
/**
* 根据角色查询角色级别
*
* @param roles /
* @return /
*/
public Integer getDeptLevelByRoles(Set<SystemRoleTb> roles) {
if (CollUtil.isEmpty(roles)) {
return Integer.MAX_VALUE;
}
Set<SystemRoleTb> roleSet = new HashSet<>();
for (SystemRoleTb role : roles) {
roleSet.add(getRoleById(role.getId()));
}
return Collections.min(roleSet.stream().map(SystemRoleTb::getLevel).collect(Collectors.toList()));
}
/** /**
* 获取用户权限信息 * 获取用户权限信息
@@ -269,7 +237,7 @@ public class SystemRoleService {
permissions.add("admin"); permissions.add("admin");
return permissions.stream().map(SystemRoleCodeVo::new).collect(Collectors.toList()); return permissions.stream().map(SystemRoleCodeVo::new).collect(Collectors.toList());
} }
List<SystemRoleVo> roles = this.queryRoleByUsersId(user.getId()); List<SystemRoleVo> roles = systemUserRoleService.queryRoleByUsersId(user.getId());
permissions = roles.stream().flatMap(role -> role.getMenus().stream()).map(SystemMenuTb::getPermission) permissions = roles.stream().flatMap(role -> role.getMenus().stream()).map(SystemMenuTb::getPermission)
.filter(StrUtil::isNotBlank).collect(Collectors.toSet()); .filter(StrUtil::isNotBlank).collect(Collectors.toSet());
return permissions.stream().map(SystemRoleCodeVo::new).collect(Collectors.toList()); return permissions.stream().map(SystemRoleCodeVo::new).collect(Collectors.toList());
@@ -286,56 +254,6 @@ public class SystemRoleService {
} }
} }
/**
* 根据ID查询
*
* @param id /
* @return /
*/
public SystemRoleTb getRoleById(Long id) {
return systemRoleMapper.selectById(id);
}
/**
* 根据部门ID统计角色数量
*
* @param deptIds 部门ID集合
* @return /
*/
public Long countRoleByDeptIds(Set<Long> deptIds) {
if (CollUtil.isEmpty(deptIds)) {
return 0L;
}
LambdaQueryWrapper<SystemRoleDeptTb> wrapper = new LambdaQueryWrapper<>();
wrapper.in(SystemRoleDeptTb::getDeptId, deptIds);
return systemRoleDeptMapper.selectCount(wrapper);
}
/**
* 转换为SystemRoleVo并关联查询菜单和部门信息
*
* @param role 角色基本信息
* @return 包含关联信息的SystemRoleVo
*/
private SystemRoleVo convertToRoleVo(SystemRoleTb role) {
if (role == null) {
return null;
}
SystemRoleVo roleVo = BeanUtil.copyProperties(role, SystemRoleVo.class);
// 查询关联的菜单信息
Set<SystemMenuTb> menus = systemRoleMenuService.queryMenuByRoleIds(
Collections.singleton(role.getId()));
roleVo.setMenus(menus);
// 查询关联的部门信息
List<SystemDeptTb> depts = systemRoleDeptService.listDeptByRoleId(role.getId());
roleVo.setDepts(new LinkedHashSet<>(depts));
return roleVo;
}
public Long countRoleByArgs(SystemQueryRoleArgs args) { public Long countRoleByArgs(SystemQueryRoleArgs args) {
LambdaQueryWrapper<SystemRoleTb> wrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SystemRoleTb> wrapper = new LambdaQueryWrapper<>();
if (args != null) { if (args != null) {
@@ -349,4 +267,33 @@ public class SystemRoleService {
} }
return systemRoleMapper.selectCount(wrapper); return systemRoleMapper.selectCount(wrapper);
} }
public SystemRoleVo getRoleById(Long id) {
SystemRoleTb roleTb = systemRoleMapper.selectById(id);
if (roleTb == null) {
return null;
}
return systemUserRoleService.convertToRoleVo(roleTb);
}
public Dict getRoleLevel() {
return Dict.create().set("level", checkRoleLevels(null));
}
/**
* 检查用户的角色级别
*
* @return /
*/
private int checkRoleLevels(Integer level) {
List<Integer> levels = systemUserRoleService.queryRoleByUsersId(KitSecurityHelper.getCurrentUserId()).stream()
.map(SystemRoleTb::getLevel).collect(Collectors.toList());
int min = Collections.min(levels);
if (level != null) {
if (level < min) {
throw new BadRequestException("权限不足, 你的角色级别:" + min + ", 低于操作的角色级别:" + level);
}
}
return min;
}
} }
@@ -0,0 +1,21 @@
package cn.odboy.system.service;
import cn.odboy.system.dal.dataobject.SystemUserTb;
import cn.odboy.system.dal.mysql.SystemUserMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class SystemUserDeptService {
@Autowired
private SystemUserMapper systemUserMapper;
public long countUserByDeptIds(Set<Long> deptIds) {
LambdaQueryWrapper<SystemUserTb> wrapper = new LambdaQueryWrapper<>();
wrapper.in(SystemUserTb::getDeptId, deptIds);
return systemUserMapper.selectCount(wrapper);
}
}
@@ -15,14 +15,26 @@
*/ */
package cn.odboy.system.service; package cn.odboy.system.service;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.odboy.framework.exception.BadRequestException;
import cn.odboy.system.dal.dataobject.SystemDeptTb;
import cn.odboy.system.dal.dataobject.SystemMenuTb;
import cn.odboy.system.dal.dataobject.SystemRoleTb; import cn.odboy.system.dal.dataobject.SystemRoleTb;
import cn.odboy.system.dal.dataobject.SystemUserRoleTb; import cn.odboy.system.dal.dataobject.SystemUserRoleTb;
import cn.odboy.system.dal.model.SystemRoleVo;
import cn.odboy.system.dal.model.SystemUserVo;
import cn.odboy.system.dal.mysql.SystemRoleMapper;
import cn.odboy.system.dal.mysql.SystemUserRoleMapper; import cn.odboy.system.dal.mysql.SystemUserRoleMapper;
import cn.odboy.system.framework.permission.core.KitSecurityHelper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@@ -30,8 +42,14 @@ import org.springframework.transaction.annotation.Transactional;
@Service @Service
public class SystemUserRoleService { public class SystemUserRoleService {
@Autowired
private SystemRoleMapper systemRoleMapper;
@Autowired @Autowired
private SystemUserRoleMapper systemUserRoleMapper; private SystemUserRoleMapper systemUserRoleMapper;
@Autowired
private SystemRoleMenuService systemRoleMenuService;
@Autowired
private SystemRoleDeptService systemRoleDeptService;
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void batchInsertUserRole(Set<SystemRoleTb> roles, Long userId) { public void batchInsertUserRole(Set<SystemRoleTb> roles, Long userId) {
@@ -55,4 +73,78 @@ public class SystemUserRoleService {
systemUserRoleMapper.delete(wrapper); systemUserRoleMapper.delete(wrapper);
} }
} }
/**
* 转换为SystemRoleVo并关联查询菜单和部门信息
*
* @param role 角色基本信息
* @return 包含关联信息的SystemRoleVo
*/
public SystemRoleVo convertToRoleVo(SystemRoleTb role) {
if (role == null) {
return null;
}
SystemRoleVo roleVo = BeanUtil.copyProperties(role, SystemRoleVo.class);
// 查询关联的菜单信息
Set<SystemMenuTb> menus = systemRoleMenuService.queryMenuByRoleIds(
Collections.singleton(role.getId()));
roleVo.setMenus(menus);
// 查询关联的部门信息
List<SystemDeptTb> depts = systemRoleDeptService.listDeptByRoleId(role.getId());
roleVo.setDepts(new LinkedHashSet<>(depts));
return roleVo;
}
/**
* 根据用户ID查询
*
* @param userId 用户ID
* @return /
*/
public List<SystemRoleVo> queryRoleByUsersId(Long userId) {
// 查询用户角色关联
LambdaQueryWrapper<SystemUserRoleTb> userRoleWrapper = new LambdaQueryWrapper<>();
userRoleWrapper.eq(SystemUserRoleTb::getUserId, userId);
List<SystemUserRoleTb> userRoles = systemUserRoleMapper.selectList(userRoleWrapper);
if (CollUtil.isEmpty(userRoles)) {
return new ArrayList<>();
}
Set<Long> roleIds = userRoles.stream().map(SystemUserRoleTb::getRoleId).collect(Collectors.toSet());
List<SystemRoleTb> roles = systemRoleMapper.selectByIds(roleIds);
return roles.stream().map(this::convertToRoleVo).collect(Collectors.toList());
}
/**
* 根据角色查询角色级别
*
* @param roles /
* @return /
*/
public Integer getDeptLevelByRoles(Set<SystemRoleTb> roles) {
if (CollUtil.isEmpty(roles)) {
return Integer.MAX_VALUE;
}
Set<SystemRoleTb> roleSet = new HashSet<>();
for (SystemRoleTb role : roles) {
roleSet.add(systemRoleMapper.selectById(role.getId()));
}
return Collections.min(roleSet.stream().map(SystemRoleTb::getLevel).collect(Collectors.toList()));
}
/**
* 如果当前用户的角色级别低于创建用户的角色级别,则抛出权限不足的错误
*
* @param args /
*/
public void checkLevel(SystemUserVo args) {
Integer currentLevel = Collections.min(
this.queryRoleByUsersId(KitSecurityHelper.getCurrentUserId()).stream()
.map(SystemRoleTb::getLevel).collect(Collectors.toList()));
Integer optLevel = this.getDeptLevelByRoles(args.getRoles());
if (currentLevel > optLevel) {
throw new BadRequestException("角色权限不足");
}
}
} }
@@ -17,12 +17,15 @@ package cn.odboy.system.service;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.odboy.base.KitPageArgs; import cn.odboy.base.KitPageArgs;
import cn.odboy.base.KitPageResult; import cn.odboy.base.KitPageResult;
import cn.odboy.base.KitSelectOptionVo; import cn.odboy.base.KitSelectOptionVo;
import cn.odboy.framework.exception.BadRequestException; import cn.odboy.framework.exception.BadRequestException;
import cn.odboy.framework.properties.AppProperties;
import cn.odboy.framework.server.core.KitFileLocalUploadHelper; import cn.odboy.framework.server.core.KitFileLocalUploadHelper;
import cn.odboy.system.constant.SystemCaptchaBizEnum;
import cn.odboy.system.dal.dataobject.SystemDeptTb; import cn.odboy.system.dal.dataobject.SystemDeptTb;
import cn.odboy.system.dal.dataobject.SystemJobTb; import cn.odboy.system.dal.dataobject.SystemJobTb;
import cn.odboy.system.dal.dataobject.SystemRoleTb; import cn.odboy.system.dal.dataobject.SystemRoleTb;
@@ -30,6 +33,7 @@ import cn.odboy.system.dal.dataobject.SystemUserJobTb;
import cn.odboy.system.dal.dataobject.SystemUserRoleTb; import cn.odboy.system.dal.dataobject.SystemUserRoleTb;
import cn.odboy.system.dal.dataobject.SystemUserTb; import cn.odboy.system.dal.dataobject.SystemUserTb;
import cn.odboy.system.dal.model.SystemQueryUserArgs; import cn.odboy.system.dal.model.SystemQueryUserArgs;
import cn.odboy.system.dal.model.SystemUpdateUserPasswordArgs;
import cn.odboy.system.dal.model.SystemUserVo; import cn.odboy.system.dal.model.SystemUserVo;
import cn.odboy.system.dal.mysql.SystemDeptMapper; import cn.odboy.system.dal.mysql.SystemDeptMapper;
import cn.odboy.system.dal.mysql.SystemJobMapper; import cn.odboy.system.dal.mysql.SystemJobMapper;
@@ -42,6 +46,7 @@ import cn.odboy.system.dal.redis.SystemUserOnlineInfoDAO;
import cn.odboy.system.framework.permission.core.KitSecurityHelper; import cn.odboy.system.framework.permission.core.KitSecurityHelper;
import cn.odboy.util.KitFileUtil; import cn.odboy.util.KitFileUtil;
import cn.odboy.util.KitPageUtil; import cn.odboy.util.KitPageUtil;
import cn.odboy.util.KitRsaEncryptUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -59,8 +64,11 @@ import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
@Service @Service
@@ -69,10 +77,22 @@ public class SystemUserService {
@Autowired @Autowired
private SystemUserMapper systemUserMapper; private SystemUserMapper systemUserMapper;
@Autowired @Autowired
private SystemJobMapper systemJobMapper;
@Autowired
private SystemRoleMapper systemRoleMapper;
@Autowired
private SystemDeptMapper systemDeptMapper;
@Autowired
private SystemUserJobService systemUserJobService; private SystemUserJobService systemUserJobService;
@Autowired @Autowired
private SystemUserRoleService systemUserRoleService; private SystemUserRoleService systemUserRoleService;
@Autowired @Autowired
private SystemEmailService systemEmailService;
@Autowired
private SystemDeptService systemDeptService;
@Autowired
private SystemDataService systemDataService;
@Autowired
private SystemUserInfoDAO systemUserInfoDAO; private SystemUserInfoDAO systemUserInfoDAO;
@Autowired @Autowired
private SystemUserOnlineInfoDAO systemUserOnlineInfoDAO; private SystemUserOnlineInfoDAO systemUserOnlineInfoDAO;
@@ -83,11 +103,10 @@ public class SystemUserService {
@Autowired @Autowired
private SystemUserRoleMapper systemUserRoleMapper; private SystemUserRoleMapper systemUserRoleMapper;
@Autowired @Autowired
private SystemJobMapper systemJobMapper; private AppProperties properties;
@Autowired @Autowired
private SystemRoleMapper systemRoleMapper; private PasswordEncoder passwordEncoder;
@Autowired
private SystemDeptMapper systemDeptMapper;
/** /**
* 新增用户 * 新增用户
@@ -96,6 +115,9 @@ public class SystemUserService {
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void saveUser(SystemUserVo args) { public void saveUser(SystemUserVo args) {
systemUserRoleService.checkLevel(args);
// 默认密码 123456
args.setPassword(passwordEncoder.encode("123456"));
args.setDeptId(args.getDept().getId()); args.setDeptId(args.getDept().getId());
if (this.getUserByUsername(args.getUsername()) != null) { if (this.getUserByUsername(args.getUsername()) != null) {
throw new BadRequestException("用户名已存在"); throw new BadRequestException("用户名已存在");
@@ -106,6 +128,7 @@ public class SystemUserService {
if (this.getUserByPhone(args.getPhone()) != null) { if (this.getUserByPhone(args.getPhone()) != null) {
throw new BadRequestException("手机号已存在"); throw new BadRequestException("手机号已存在");
} }
// 保存用户
systemUserMapper.insert(args); systemUserMapper.insert(args);
// 保存用户岗位 // 保存用户岗位
systemUserJobService.batchInsertUserJob(args.getJobs(), args.getId()); systemUserJobService.batchInsertUserJob(args.getJobs(), args.getId());
@@ -120,6 +143,7 @@ public class SystemUserService {
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void updateUserById(SystemUserVo args) { public void updateUserById(SystemUserVo args) {
systemUserRoleService.checkLevel(args);
SystemUserTb user = systemUserMapper.selectById(args.getId()); SystemUserTb user = systemUserMapper.selectById(args.getId());
SystemUserTb user1 = this.getUserByUsername(args.getUsername()); SystemUserTb user1 = this.getUserByUsername(args.getUsername());
SystemUserTb user2 = this.getUserByEmail(args.getEmail()); SystemUserTb user2 = this.getUserByEmail(args.getEmail());
@@ -163,6 +187,9 @@ public class SystemUserService {
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void updateUserCenterInfoById(SystemUserTb args) { public void updateUserCenterInfoById(SystemUserTb args) {
if (!args.getId().equals(KitSecurityHelper.getCurrentUserId())) {
throw new BadRequestException("不能修改他人资料");
}
SystemUserTb user = systemUserMapper.selectById(args.getId()); SystemUserTb user = systemUserMapper.selectById(args.getId());
SystemUserTb user1 = this.getUserByPhone(args.getPhone()); SystemUserTb user1 = this.getUserByPhone(args.getPhone());
if (user1 != null && !user.getId().equals(user1.getId())) { if (user1 != null && !user.getId().equals(user1.getId())) {
@@ -182,11 +209,26 @@ public class SystemUserService {
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void removeUserByIds(Set<Long> ids) { public void removeUserByIds(Set<Long> ids) {
Long currentUserId = KitSecurityHelper.getCurrentUserId();
// 校验权限
for (Long id : ids) { for (Long id : ids) {
// 清理缓存 Integer currentLevel = Collections.min(
SystemUserTb user = systemUserMapper.selectById(id); systemUserRoleService.queryRoleByUsersId(currentUserId).stream()
systemUserInfoDAO.deleteUserLoginInfoByUserName(user.getUsername()); .map(SystemRoleTb::getLevel).collect(Collectors.toList()));
Integer optLevel = Collections.min(
systemUserRoleService.queryRoleByUsersId(id).stream().map(SystemRoleTb::getLevel)
.collect(Collectors.toList()));
if (currentLevel > optLevel) {
throw new BadRequestException(
"角色权限不足, 不能删除:" + this.getUserById(id).getUsername());
} }
}
// 清理缓存
List<String> usernameList = systemUserMapper.selectByIds(ids).stream().map(SystemUserTb::getUsername).distinct().collect(Collectors.toList());
for (String username : usernameList) {
systemUserInfoDAO.deleteUserLoginInfoByUserName(username);
}
// 删除用户
systemUserMapper.deleteByIds(ids); systemUserMapper.deleteByIds(ids);
// 删除用户岗位 // 删除用户岗位
systemUserJobService.batchDeleteUserJob(ids); systemUserJobService.batchDeleteUserJob(ids);
@@ -198,10 +240,22 @@ public class SystemUserService {
* 修改密码 * 修改密码
* *
* @param username 用户名 * @param username 用户名
* @param encryptPassword 密码 * @param args 参数
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void updateUserPasswordByUsername(String username, String encryptPassword) { public void updateUserPasswordByUsername(String username, SystemUpdateUserPasswordArgs args) throws Exception {
String oldPass =
KitRsaEncryptUtil.decryptByPrivateKey(properties.getRsa().getPrivateKey(), args.getOldPass());
String newPass =
KitRsaEncryptUtil.decryptByPrivateKey(properties.getRsa().getPrivateKey(), args.getNewPass());
SystemUserTb user = this.getUserByUsername(username);
if (!passwordEncoder.matches(oldPass, user.getPassword())) {
throw new BadRequestException("修改失败,旧密码错误");
}
if (passwordEncoder.matches(newPass, user.getPassword())) {
throw new BadRequestException("新密码不能与旧密码相同");
}
String encryptPassword = passwordEncoder.encode(newPass);
systemUserMapper.updateUserPasswordByUsername(username, encryptPassword); systemUserMapper.updateUserPasswordByUsername(username, encryptPassword);
systemUserInfoDAO.deleteUserLoginInfoByUserName(username); systemUserInfoDAO.deleteUserLoginInfoByUserName(username);
} }
@@ -210,20 +264,20 @@ public class SystemUserService {
* 重置密码 * 重置密码
* *
* @param ids 用户id * @param ids 用户id
* @param password 密码
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void resetUserPasswordByIds(Set<Long> ids, String password) { public void resetUserPasswordByIds(Set<Long> ids) {
String defaultPwd = passwordEncoder.encode("123456");
List<SystemUserTb> users = systemUserMapper.selectByIds(ids); List<SystemUserTb> users = systemUserMapper.selectByIds(ids);
// 清除缓存 // 清除缓存
users.forEach(user -> { for (SystemUserTb user : users) {
// 清除缓存 // 清除缓存
systemUserInfoDAO.deleteUserLoginInfoByUserName(user.getUsername()); systemUserInfoDAO.deleteUserLoginInfoByUserName(user.getUsername());
// 强制退出 // 强制退出
systemUserOnlineInfoDAO.kickOutByUsername(user.getUsername()); systemUserOnlineInfoDAO.kickOutByUsername(user.getUsername());
}); }
// 重置密码 // 重置密码
systemUserMapper.updateUserPasswordByUserIds(password, ids); systemUserMapper.updateUserPasswordByUserIds(defaultPwd, ids);
} }
/** /**
@@ -265,11 +319,19 @@ public class SystemUserService {
* 修改邮箱 * 修改邮箱
* *
* @param username 用户名 * @param username 用户名
* @param email 邮箱 * @param args 参数
* @param code 验证码
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void updateUserEmailByUsername(String username, String email) { public void updateUserEmailByUsername(String username, SystemUserTb args, String code) throws Exception {
systemUserMapper.updateUserEmailByUsername(username, email); String password =
KitRsaEncryptUtil.decryptByPrivateKey(properties.getRsa().getPrivateKey(), args.getPassword());
SystemUserTb user = this.getUserByUsername(username);
if (!passwordEncoder.matches(password, user.getPassword())) {
throw new BadRequestException("密码错误");
}
systemEmailService.checkEmailCaptchaV1(SystemCaptchaBizEnum.EMAIL_RESET_EMAIL_CODE, args.getEmail(), code);
systemUserMapper.updateUserEmailByUsername(username, args.getEmail());
systemUserInfoDAO.deleteUserLoginInfoByUserName(username); systemUserInfoDAO.deleteUserLoginInfoByUserName(username);
} }
@@ -436,13 +498,11 @@ public class SystemUserService {
return null; return null;
} }
SystemUserVo userVo = BeanUtil.copyProperties(user, SystemUserVo.class); SystemUserVo userVo = BeanUtil.copyProperties(user, SystemUserVo.class);
// 查询关联的部门信息 // 查询关联的部门信息
if (user.getDeptId() != null) { if (user.getDeptId() != null) {
SystemDeptTb dept = systemDeptMapper.selectById(user.getDeptId()); SystemDeptTb dept = systemDeptMapper.selectById(user.getDeptId());
userVo.setDept(dept); userVo.setDept(dept);
} }
// 查询关联的岗位信息 // 查询关联的岗位信息
LambdaQueryWrapper<SystemUserJobTb> jobWrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SystemUserJobTb> jobWrapper = new LambdaQueryWrapper<>();
jobWrapper.eq(SystemUserJobTb::getUserId, user.getId()); jobWrapper.eq(SystemUserJobTb::getUserId, user.getId());
@@ -452,7 +512,6 @@ public class SystemUserService {
List<SystemJobTb> jobs = systemJobMapper.selectByIds(jobIds); List<SystemJobTb> jobs = systemJobMapper.selectByIds(jobIds);
userVo.setJobs(new LinkedHashSet<>(jobs)); userVo.setJobs(new LinkedHashSet<>(jobs));
} }
// 查询关联的角色信息 // 查询关联的角色信息
LambdaQueryWrapper<SystemUserRoleTb> roleWrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SystemUserRoleTb> roleWrapper = new LambdaQueryWrapper<>();
roleWrapper.eq(SystemUserRoleTb::getUserId, user.getId()); roleWrapper.eq(SystemUserRoleTb::getUserId, user.getId());
@@ -462,7 +521,6 @@ public class SystemUserService {
List<SystemRoleTb> roles = systemRoleMapper.selectByIds(roleIds); List<SystemRoleTb> roles = systemRoleMapper.selectByIds(roleIds);
userVo.setRoles(new LinkedHashSet<>(roles)); userVo.setRoles(new LinkedHashSet<>(roles));
} }
return userVo; return userVo;
} }
@@ -477,12 +535,6 @@ public class SystemUserService {
return this.convertToUserVo(this.getUserByUsername(username)); return this.convertToUserVo(this.getUserByUsername(username));
} }
public long countUserByDeptIds(Set<Long> deptIds) {
LambdaQueryWrapper<SystemUserTb> wrapper = new LambdaQueryWrapper<>();
wrapper.in(SystemUserTb::getDeptId, deptIds);
return systemUserMapper.selectCount(wrapper);
}
public SystemUserTb getUserByEmail(String email) { public SystemUserTb getUserByEmail(String email) {
LambdaQueryWrapper<SystemUserTb> wrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SystemUserTb> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SystemUserTb::getEmail, email); wrapper.eq(SystemUserTb::getEmail, email);
@@ -496,4 +548,30 @@ public class SystemUserService {
wrapper.eq(SystemUserTb::getEnabled, 1); wrapper.eq(SystemUserTb::getEnabled, 1);
return systemUserMapper.selectOne(wrapper); return systemUserMapper.selectOne(wrapper);
} }
public KitPageResult<SystemUserVo> aggregationSearchUserByArgs(Page<SystemUserTb> page, SystemQueryUserArgs args, String currentUsername) {
if (!ObjectUtils.isEmpty(args.getDeptId())) {
args.getDeptIds().add(args.getDeptId());
// 先查找是否存在子节点
List<SystemDeptTb> data = systemDeptService.listDeptByPid(args.getDeptId());
// 然后把子节点的ID都加入到集合中
args.getDeptIds().addAll(systemDeptService.queryChildDeptIdByDeptIds(data));
}
// 数据权限
List<Long> dataScopes = systemDataService.queryDeptIdByArgs(
this.getUserByUsername(currentUsername));
// args.getDeptIds() 不为空并且数据权限不为空则取交集
if (!CollectionUtils.isEmpty(args.getDeptIds()) && !CollectionUtils.isEmpty(dataScopes)) {
// 取交集
args.getDeptIds().retainAll(dataScopes);
if (!CollectionUtil.isEmpty(args.getDeptIds())) {
return this.searchUserByArgs(args, page);
}
} else {
// 否则取并集
args.getDeptIds().addAll(dataScopes);
return this.searchUserByArgs(args, page);
}
return KitPageUtil.emptyData();
}
} }