将开源版本的修改打补丁应用到商业版

This commit is contained in:
wsm
2026-04-09 19:33:52 +08:00
parent d94e9c9bc4
commit b52aec1611
111 changed files with 7215 additions and 275 deletions
@@ -0,0 +1,507 @@
package org.jeecg.modules.system.controller;
import cn.hutool.core.date.DateUtil;
import com.alibaba.druid.util.StringUtils;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.util.IOUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.UnauthorizedException;
import org.apiguardian.api.API;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.*;
import org.jeecg.modules.base.service.BaseCommonService;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.lang.reflect.Array;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.*;
/**
* @Description: 文件上传下载更新接口
* @Author: gelingjia
* @Date:2025.9.22
* @Version:V1.0
*/
@Tag(name = "文件上传下载更新接口")
@RestController
@RequestMapping("/sys/file")
@Slf4j
public class FileController {
@Autowired
public ISysBaseAPI sysBaseAPI;
@Autowired
private RedisUtil redisUtil;
@Autowired
private BaseCommonService baseCommonService;
@Value(value = "${jeecg.appName}")
private String applicationName;
/**
* 附件加密上传接口
*
* @param request
* @param response
* @return
*/
@AutoLog(value = "系统自动日志:文件加密上传")
@Operation(summary = "附件加密上传接口")
@PostMapping(value = "/upload")
public Result<Map<String,String>> upload(HttpServletRequest request, HttpServletResponse response) throws Exception {
Result<Map<String,String>> result = new Result<>();
// 将请求转换为 MultipartHttpServletRequest
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
//获取登录用户信息
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
if (sysUser != null) {
// 获取前端传递来的密级
String secLevel = multipartRequest.getParameter("secretLevel");
if (secLevel == null || secLevel.equals("")) {
result.setSuccess(false);
result.setMessage("上传附件密级为空。无法上传");
} else {
// 获取用户密级,如果为空则提示用户先设置密级
Integer userSecLevelObj = sysUser.getUserSecurityLevel();
if (userSecLevelObj == null) {
result.setSuccess(false);
result.setMessage("当前用户未设置人员密级,请先在用户管理中设置人员密级后再上传文件!(密级说明:1-非密,2-内部,3-秘密,4-机密)");
return result;
}
int userSecLevel = userSecLevelObj.intValue();
int fileSecLevel = Integer.parseInt(secLevel);
if (userSecLevel <= fileSecLevel) {
result.setSuccess(false);
result.setMessage("上传文件密级不能高于人员密级!");
} else {
String savePath = "";
String bizPath = request.getParameter("biz");
String secretLevelText =securityLevel(secLevel);
//设置上传文档的存储路径
if (StringUtils.isEmpty(bizPath)) {
Date now = new Date();
bizPath = "/"+secretLevelText + "/"+ DateUtil.year(now) + "/"+ (DateUtil.month(now) + 1) + "/"+ DateUtil.dayOfMonth(now);
}
else{
if (oConvertUtils.isNotEmpty(bizPath) && (bizPath.contains("../") || bizPath.contains("..\\"))) {
throw new JeecgBootException("上传目录bizPath,格式非法!");
}
bizPath = "/"+secretLevelText + "/"+ bizPath;
}
MultipartFile file = multipartRequest.getFile("file");// 获取上传文件对象
savePath = MinioUtil.encryptUpload(file, bizPath);//yxk-加密上传的地方在这里
long size = file.getSize();
String fileNameInDB = this.getFileNameinDB(secLevel, file);
JSONObject fileJsonObject = new JSONObject();
fileJsonObject.put("fileName", fileNameInDB);
fileJsonObject.put("filePath", savePath);
fileJsonObject.put("size", Integer.parseInt(String.valueOf(size)));
fileJsonObject.put("secretText", secretLevelText);
fileJsonObject.put("secretLevel", secLevel);
fileJsonObject.put("fileUploadType",applicationName);
fileJsonObject.put("uploadTime",new Date());
fileJsonObject.put("uploaderWorkNo", request.getParameter("workNo"));
fileJsonObject.put("uploader",request.getParameter("username"));
fileJsonObject.put("uploadPercent",request.getParameter("uploadPercent"));
fileJsonObject.put("uploadRes",request.getParameter("uploadRes"));
fileJsonObject.put("uploadStatus",request.getParameter("uploadStatus"));
fileJsonObject.put("isUploaded",request.getParameter("isUploaded"));
// 添加 business_id 支持(可选参数,用于关联业务表单)
String businessId = request.getParameter("business_id");
if (oConvertUtils.isNotEmpty(businessId)) {
fileJsonObject.put("businessId", businessId);
}
if(fileNameInDB.lastIndexOf(".")>-1){
fileJsonObject.put("fileSuffix",fileNameInDB.substring(fileNameInDB.lastIndexOf(".")));
}
String fileId = sysBaseAPI.addSysFileAttachment(fileJsonObject);
if (oConvertUtils.isNotEmpty(savePath)) {
HashMap<String, String> res = new HashMap<String,String>();
res.put("savePath",savePath);
res.put("fileId",fileId);
res.put("fileUploadType",applicationName);
result.setResult(res);
result.setMessage(savePath);
result.setSuccess(true);
baseCommonService.addLog("附件加密上传:" + savePath, CommonConstant.LOG_TYPE_2, CommonConstant.OPERATE_TYPE_2);
} else {
result.setMessage("上传失败!");
result.setSuccess(false);
}
}
}
} else {
result.setSuccess(false);
result.setMessage("当前用户失效,上传失败。请重新登录");
}
return result;
}
@AutoLog(value = "系统自动日志:文件删除")
@Operation(summary = "文件删除接口")
@GetMapping(value = "/delete")
public Result<String> delete(@RequestParam String id){
sysBaseAPI.deleteFileAttachment(id);
return Result.OK();
}
/**
* 文件解密下载接口
* 下载文件
*
* @param fileUrl
* @param request
* @param response
* @return
*/
@AutoLog(value = "系统自动日志:文件解密下载")
@Operation(summary = "附件下载接口")
@GetMapping(value = "/download")
public void download(@RequestParam String fileUrl, HttpServletRequest request, HttpServletResponse response) throws Exception {
boolean flag = TokenUtils.verifyToken(request, sysBaseAPI, redisUtil);
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
if (flag) {
if (sysUser != null) {
String bucketName = MinioUtil.getBucketName();
String objectName = fileUrl;
String fileName = fileUrl.substring(fileUrl.lastIndexOf("/") + 1);
InputStream inputStream = MinioUtil.getMinioFile(bucketName, objectName);
//文件流解密
byte[] fileBytes = IOUtils.toByteArray(inputStream);
byte[] decryptedBytes = SecureUtils.decrypt(fileBytes);
//response.setContentType("application/force-download");
response.setContentType("application/octet-stream");
response.addHeader("Content-Disposition", "attachment;fileName=\"" + fileName + "\"");
//IOUtils.copy(inputStream,response.getOutputStream());
baseCommonService.addLog("文件解密下载:" + fileUrl, CommonConstant.LOG_TYPE_2, CommonConstant.OPERATE_TYPE_2);
response.getOutputStream().write(decryptedBytes);
response.flushBuffer();
} else {
//"当前用户失效,下载失败。请重新登录
baseCommonService.addLog("当前用户失效,下载失败。无法查看文件:" + fileUrl, CommonConstant.LOG_TYPE_2, CommonConstant.OPERATE_TYPE_2, sysUser);
throw new UnauthorizedException("当前用户失效,下载失败。请重新登录");
}
} else {
//"token 校验是被
baseCommonService.addLog("token 校验失败。无法查看文件:" + fileUrl, CommonConstant.LOG_TYPE_2, CommonConstant.OPERATE_TYPE_2, sysUser);
throw new UnauthorizedException("token 校验失败");
}
}
// @Operation(summary = "文件预览临时方案")
// @GetMapping(value = "/view")
// public Result<String> downloadForView(@RequestParam String fileUrl, HttpServletRequest request, HttpServletResponse response) throws Exception {
// String bucketName = MinioUtil.getBucketName();
// String minioUrl = MinioUtil.getMinioUrl();
// String objectName = fileUrl;
// if(!objectName.startsWith("/")){
// objectName = "/" + objectName;
// }
// int dotIndex = objectName.lastIndexOf(".");
// String extension = (dotIndex == -1) ? "" : objectName.substring(dotIndex);
// String nameWithoutExtension = (dotIndex == -1) ? objectName : objectName.substring(0, dotIndex);
// String time = MinioUtil.getLastModifiedTime(objectName);
// String newFileName = "/temp" + nameWithoutExtension + time + extension;
// String checkFileExistence = MinioUtil.checkFileExistence(newFileName);
// log.info("查询缓存路径:" + checkFileExistence);
// if ("0".equals(checkFileExistence)) {
// InputStream inputStream = MinioUtil.getMinioFile(bucketName, objectName);
// //文件流解密
// byte[] fileBytes = IOUtils.toByteArray(inputStream);
// byte[] decryptedBytes = SecureUtils.decrypt(fileBytes);
// InputStream inputStream2 = new ByteArrayInputStream(decryptedBytes);
// String resPath = MinioUtil.upload(inputStream2, newFileName);
// if(!resPath.startsWith("/")){
// minioUrl = "/" + minioUrl;
// }
// resPath=minioUrl + bucketName + resPath;
// log.info("得到新缓存路径:" + resPath);
// return Result.OK(resPath);
// } else {
// log.info("返回已有缓存路径:" + checkFileExistence);
// return Result.OK(checkFileExistence);
// }
//
//
// }
/**
* 通过附件id查询附件路径
*
* @param id
* @return
*/
@Operation(summary = "通过附件id查询附件路径")
@GetMapping(value = "/getFilePathById")
public Result<?> getFileById(@RequestParam(name = "id") String id, HttpServletRequest request, HttpServletResponse response) {
Result result = new Result();
try {
String filePath = this.sysBaseAPI.getFilePath(id);
result.setResult(filePath);
} catch (Exception e) {
return result.error500("系统错误!");
}
return result;
}
/**
* 通过附件ids查询多个附件路径
*
* @param ids
* @return
*/
@Operation(summary = "通过附件ids查询多个附件路径")
@GetMapping(value = "/getFilePathByIds")
public Result<?> getFileByIds(@RequestParam(name = "ids") String ids, HttpServletRequest request, HttpServletResponse response) {
Result result = new Result();
try {
String filePath = this.sysBaseAPI.getFilesPath(ids);
result.setResult(filePath);
} catch (Exception e) {
return result.error500("系统错误!");
}
return result;
}
/**
* 通过附件id获取附件信息
* @param id
* @return
*/
@Operation(summary = "通过附件id获取附件信息")
@RequestMapping(value = "/file/getFileDetailById", method = RequestMethod.GET)
public Result<Map<String,Object>> getFileDetailById(@RequestParam(required = true) String id, HttpServletRequest request, HttpServletResponse response) {
Result result = new Result();
try {
Map<String,Object> res = this.sysBaseAPI.queryFileMapById(id);
result.setResult(res);
} catch (Exception e) {
return result.error500("系统错误!");
}
return result;
}
/**
* 通过附件ids获取(多)附件信息
* @param ids
* @return
*/
@Operation(summary = "通过附件ids获取(多)附件信息")
@RequestMapping(value = "/file/getFileDetailByIds", method = RequestMethod.GET)
public Result<JSONArray> getFileDetailByIds(@RequestParam(required = true) String ids, HttpServletRequest request, HttpServletResponse response) {
String[] idArray = ids.split(",");
if (idArray.length == 0) {
return Result.OK();
}
JSONArray jsonArray = this.sysBaseAPI.getFileDetialById(ids);
return Result.OK(jsonArray);
}
/**
* 公文系统文件下载接口
* 下载文件
* 请求地址:http://localhost:8080/officialdoc/file/{http://192.168.137.200:9000/official-doc/项目策划-质量保证大纲(生产部门使用)_1722237648135.pdf}
*
* @param fileUrl
* @param request
* @param response
* @return
*/
// @AutoLog(value = "系统自动日志:在线编辑解密下载文件")
// @Operation(summary = "在线编辑解密下载文件")
// @ApiImplicitParams({
// @ApiImplicitParam(name = "fileUrl", value = "fileUrl", required = false, dataType = "string", paramType = "body")
// })
// @GetMapping(value = "/downloadOnlineEdit")
// public void downloadOnlineEdit(@RequestParam(required = true) String fileUrl, HttpServletRequest request, HttpServletResponse response) throws Exception {
// boolean flag = TokenUtils.verifyToken(request, sysBaseAPI, redisUtil);
// LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
// if (flag) {
// if (sysUser != null) {
//
// String bucketName = MinioUtil.getBucketName();
// String objectName = fileUrl;
// String fileName = fileUrl.substring(fileUrl.lastIndexOf("/") + 1);
// InputStream inputStream = MinioUtil.getMinioFile(bucketName, objectName);
// response.reset();
// response.setContentType("application/force-download");
// response.addHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(fileName));
// ServletOutputStream outputStream = response.getOutputStream();
// byte[] fileBytes = IOUtils.toByteArray(inputStream);
// byte[] decryptedBytes = SecureUtils.decrypt(fileBytes);
// outputStream.write(decryptedBytes);
// baseCommonService.addLog("文件在线编辑解密下载:" + fileUrl, CommonConstant.LOG_TYPE_2, CommonConstant.OPERATE_TYPE_2);
// inputStream.close();
//
//
//
// } else {
// //"当前用户失效,下载失败。请重新登录
// baseCommonService.addLog("当前用户失效,下载失败。无法查看文件:" + fileUrl, CommonConstant.LOG_TYPE_2, CommonConstant.OPERATE_TYPE_2, "失败");
// throw new UnauthorizedException("当前用户失效,下载失败。请重新登录");
// }
//
// } else {
// //"token 校验是被
// baseCommonService.addLog("token 校验失败。无法查看文件:" + fileUrl, CommonConstant.LOG_TYPE_2, CommonConstant.OPERATE_TYPE_2, "失败");
// throw new UnauthorizedException("token 校验失败");
// }
// }
@AutoLog(value = "系统自动日志:更新文件")
@Operation(summary = "更新文件")
@PostMapping(value = "/upload/update")
public Result<?> uploadUpdate(@RequestParam(required = true) String fileUrl, HttpServletRequest request, HttpServletResponse response) {
Result<?> result = new Result<>();
String savePath = "";
fileUrl = URLDecoder.decode(fileUrl);
log.info("更新路径:" + fileUrl);
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
MultipartFile file = multipartRequest.getFile("file");// 获取上传文件对象
savePath = MinioUtil.uploadUpdate(file, fileUrl, null);
if (oConvertUtils.isNotEmpty(savePath)) {
result.setMessage(savePath);
baseCommonService.addLog("更新保存文件:" + savePath, CommonConstant.LOG_TYPE_2, CommonConstant.OPERATE_TYPE_2);
result.setSuccess(true);
} else {
result.setMessage("上传失败!");
baseCommonService.addLog("上传失败:", CommonConstant.LOG_TYPE_2, CommonConstant.OPERATE_TYPE_2);
result.setSuccess(false);
}
return result;
}
/**
* 更新文件信息
*
*
* @return
*/
@AutoLog(value = "更新文件信息")
@Operation(summary = "更新文件信息")
@GetMapping(value = "/updateFilesInfo")
public Result<String> updateFilesInfo(HttpServletRequest request, HttpServletResponse response) {
Result<?> result = new Result<>();
String bussinessId = request.getParameter("bussinessId");
String fileIds = request.getParameter("fileIds");
List<String> deliverablesList = Arrays.asList(fileIds.split(","));
this.sysBaseAPI.updateBusinessId(bussinessId,deliverablesList);
return Result.OK("更新文件信息!");
}
/**
* 通过附件BussinessId获取附件信息
* @param bussinessId
* @return
*/
@Operation(summary = "通过附件BussinessId获取附件信息")
@RequestMapping(value = "/getFileInfoByBussinessId", method = RequestMethod.GET)
public Result<JSONArray> getFileInfoByBussinessId(@RequestParam(required = true) String bussinessId,
HttpServletRequest request, HttpServletResponse response) {
// String misFlag = request.getParameter("misFlag");
String misFlag = "false";
JSONArray jsonArray = this.sysBaseAPI.getFileInfoByBussinessId(bussinessId, misFlag);
return Result.OK(jsonArray);
}
private String securityLevel(String secLevel) {
if ("1".equals(secLevel)) {
return "非密";
} else if ("2".equals(secLevel)) {
return "内部";
} else if ("3".equals(secLevel)) {
return "秘密";
} else if ("4".equals(secLevel)) {
return "机密";
} else return null;
}
/**
* 获取存储到数据库的文件名
*
* @param secLevel 文件密级
* @param file 上传的文件
* @return 原始文件名
*/
@NotNull
private String getFileNameinDB(String secLevel, MultipartFile file) {
String orgName = file.getOriginalFilename();// 获取文件名
assert orgName != null;
String fileNameInDB = CommonUtils.getFileName(orgName);
String pre =null ;
String suffix = null ;
String secLevelText =null ;
if(fileNameInDB.indexOf(".") == -1){
pre = fileNameInDB;
suffix = "";
}
else {
pre = fileNameInDB.substring(0, fileNameInDB.lastIndexOf("."));
suffix = fileNameInDB.substring(fileNameInDB.lastIndexOf("."));
}
if (org.apache.commons.lang3.StringUtils.isNotEmpty(secLevel)) {
//拼接文件名
if ("1".equals(secLevel)) {
secLevelText="(非密)" ;
} else if ("2".equals(secLevel)) {
secLevelText="(内部)";
} else if ("3".equals(secLevel)) {
secLevelText="(M)";
} else if ("4".equals(secLevel)) {
secLevelText="(J)";
} else {
secLevelText="";
};
}
return pre+secLevelText+suffix;
}
}
@@ -2,7 +2,8 @@ package org.jeecg.modules.system.controller;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
@@ -11,16 +12,15 @@ import org.jeecg.common.api.vo.Result;
import org.jeecg.common.config.TenantContext;
import org.jeecg.common.constant.CacheConstant;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.ImportExcelUtil;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.common.util.YouBianCodeUtil;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.config.mybatis.MybatisPlusSaasConfig;
import org.jeecg.modules.system.entity.SysDepart;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.entity.SysUserDepart;
import org.jeecg.modules.system.model.DepartIdModel;
import org.jeecg.modules.system.model.SysDepartTreeModel;
import org.jeecg.modules.system.service.ISysDepartService;
@@ -56,6 +56,7 @@ import java.util.*;
@RestController
@RequestMapping("/sys/sysDepart")
@Slf4j
@Tag(name = "部门管理模块", description = "处理用户与角色、部门的关系") // 1. 分类
public class SysDepartController {
@Autowired
@@ -174,6 +175,50 @@ public class SysDepartController {
}
}
/**
* 获取某个用户的所有所在部门的id和部门名
*
* @param userName 根据userName查所在部门
*/
@GetMapping("/queryAffiliatedDepts")
@Operation(summary = "根据角色username,查询所在部门", description = "根据角色username,查询所在部门") // 2. 接口描述
public Result<List<SysDepart>> queryAffiliatedDepts(
@RequestParam(name = "userName", required = false) String userName) {
try {
// 2. 使用 Optional 处理空逻辑,代码更具现代感
List<SysDepart> departList = Optional.ofNullable(userName)
.filter(oConvertUtils::isNotEmpty)
.map(sysDepartService::queryUserAffiliatedDepts)
.orElse(Collections.emptyList()); // 3. 没数据返回只读空列表,性能更好
return Result.OK(departList);
} catch (Exception e) {
log.error(e.getMessage(), e);
return Result.error(e.getMessage());
}
}
/**
* 根据departType查询所有二级部门部门
*
* @param departType 根据departType查询部门
*/
@GetMapping("/querySecondLevelDepts")
@Operation(summary = "根据部门类别查询第二层级的部门", description = "根据部门类别查询第二层级的部门") // 2. 接口描述
public Result<List<SysDepart>> querySecondLevelDepts(
@RequestParam(name = "departType", required = false) Integer departType) {
try {
// 2. 使用 Optional 处理空逻辑,代码更具现代感
List<SysDepart> departList = Optional.ofNullable(departType)
.filter(oConvertUtils::isNotEmpty)
.map(sysDepartService::querySecondLevelDepts)
.orElse(Collections.emptyList()); // 3. 没数据返回只读空列表,性能更好
return Result.OK(departList);
} catch (Exception e) {
log.error(e.getMessage(), e);
return Result.error(e.getMessage());
}
}
/**
* 添加新数据 添加用户新建的部门对象数据,并保存到数据库
*
@@ -0,0 +1,182 @@
package org.jeecg.modules.system.controller;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.query.QueryRuleEnum;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.system.entity.SysFileAttachment;
import org.jeecg.modules.system.service.ISysFileAttachmentService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
import org.jeecg.common.system.base.controller.JeecgController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;
import com.alibaba.fastjson.JSON;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.apache.shiro.authz.annotation.RequiresPermissions;
/**
* @Description: sys_file_attachment
* @Author: jeecg-boot
* @Date: 2026-03-26
* @Version: V1.0
*/
@Tag(name="sys_file_attachment")
@RestController
@RequestMapping("/system/sysFileAttachment")
@Slf4j
public class SysFileAttachmentController extends JeecgController<SysFileAttachment, ISysFileAttachmentService> {
@Autowired
private ISysFileAttachmentService sysFileAttachmentService;
/**
* 分页列表查询
*
* @param sysFileAttachment
* @param pageNo
* @param pageSize
* @param req
* @return
*/
//@AutoLog(value = "sys_file_attachment-分页列表查询")
@Operation(summary="sys_file_attachment-分页列表查询")
@GetMapping(value = "/list")
public Result<IPage<SysFileAttachment>> queryPageList(SysFileAttachment sysFileAttachment,
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
HttpServletRequest req) {
QueryWrapper<SysFileAttachment> queryWrapper = QueryGenerator.initQueryWrapper(sysFileAttachment, req.getParameterMap());
Page<SysFileAttachment> page = new Page<SysFileAttachment>(pageNo, pageSize);
IPage<SysFileAttachment> pageList = sysFileAttachmentService.page(page, queryWrapper);
return Result.OK(pageList);
}
/**
* 添加
*
* @param sysFileAttachment
* @return
*/
@AutoLog(value = "sys_file_attachment-添加")
@Operation(summary="sys_file_attachment-添加")
@RequiresPermissions("system:sys_file_attachment:add")
@PostMapping(value = "/add")
public Result<String> add(@RequestBody SysFileAttachment sysFileAttachment) {
sysFileAttachmentService.save(sysFileAttachment);
return Result.OK("添加成功!");
}
/**
* 编辑
*
* @param sysFileAttachment
* @return
*/
@AutoLog(value = "sys_file_attachment-编辑")
@Operation(summary="sys_file_attachment-编辑")
@RequiresPermissions("system:sys_file_attachment:edit")
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
public Result<String> edit(@RequestBody SysFileAttachment sysFileAttachment) {
sysFileAttachmentService.updateById(sysFileAttachment);
return Result.OK("编辑成功!");
}
/**
* 通过id删除
*
* @param id
* @return
*/
@AutoLog(value = "sys_file_attachment-通过id删除")
@Operation(summary="sys_file_attachment-通过id删除")
@RequiresPermissions("system:sys_file_attachment:delete")
@DeleteMapping(value = "/delete")
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
sysFileAttachmentService.removeById(id);
return Result.OK("删除成功!");
}
/**
* 批量删除
*
* @param ids
* @return
*/
@AutoLog(value = "sys_file_attachment-批量删除")
@Operation(summary="sys_file_attachment-批量删除")
@RequiresPermissions("system:sys_file_attachment:deleteBatch")
@DeleteMapping(value = "/deleteBatch")
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
this.sysFileAttachmentService.removeByIds(Arrays.asList(ids.split(",")));
return Result.OK("批量删除成功!");
}
/**
* 通过id查询
*
* @param id
* @return
*/
//@AutoLog(value = "sys_file_attachment-通过id查询")
@Operation(summary="sys_file_attachment-通过id查询")
@GetMapping(value = "/queryById")
public Result<SysFileAttachment> queryById(@RequestParam(name="id",required=true) String id) {
SysFileAttachment sysFileAttachment = sysFileAttachmentService.getById(id);
if(sysFileAttachment==null) {
return Result.error("未找到对应数据");
}
return Result.OK(sysFileAttachment);
}
/**
* 导出excel
*
* @param request
* @param sysFileAttachment
*/
@RequiresPermissions("system:sys_file_attachment:exportXls")
@RequestMapping(value = "/exportXls")
public ModelAndView exportXls(HttpServletRequest request, SysFileAttachment sysFileAttachment) {
return super.exportXls(request, sysFileAttachment, SysFileAttachment.class, "sys_file_attachment");
}
/**
* 通过excel导入数据
*
* @param request
* @param response
* @return
*/
@RequiresPermissions("system:sys_file_attachment:importExcel")
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
return super.importExcel(request, response, SysFileAttachment.class);
}
}
@@ -3,30 +3,29 @@ package org.jeecg.modules.system.controller;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.base.BaseMap;
import org.jeecg.common.config.TenantContext;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.constant.FlowEventTypeConst;
import org.jeecg.common.constant.SymbolConstant;
import org.jeecg.common.modules.redis.client.JeecgRedisClient;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.config.mybatis.MybatisPlusSaasConfig;
import org.jeecg.modules.base.service.BaseCommonService;
import org.jeecg.modules.system.dto.UserDeptSaveDTO;
import org.jeecg.modules.system.entity.*;
import org.jeecg.modules.system.model.TreeModel;
import org.jeecg.modules.system.service.*;
@@ -69,28 +68,29 @@ import lombok.extern.slf4j.Slf4j;
@RestController
@RequestMapping("/sys/role")
@Slf4j
@Tag(name = "角色管理模块", description = "处理用户与角色、部门的关系") // 1. 分类
public class SysRoleController {
@Autowired
private ISysRoleService sysRoleService;
@Autowired
private ISysPermissionDataRuleService sysPermissionDataRuleService;
@Autowired
private ISysRolePermissionService sysRolePermissionService;
@Autowired
private ISysPermissionService sysPermissionService;
@Autowired
private ISysUserRoleService sysUserRoleService;
@Autowired
private ISysUserRoleService sysUserRoleService;
@Autowired
private BaseCommonService baseCommonService;
@Autowired
private JeecgRedisClient jeecgRedisClient;
/**
* 分页列表查询 【系统角色,不做租户隔离】
* 分页列表查询 【系统角色,不做租户隔离】
* @param role
* @param pageNo
* @param pageSize
@@ -100,15 +100,15 @@ public class SysRoleController {
@RequiresPermissions("system:role:list")
@RequestMapping(value = "/list", method = RequestMethod.GET)
public Result<IPage<SysRole>> queryPageList(SysRole role,
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
@RequestParam(name="isMultiTranslate", required = false) Boolean isMultiTranslate,
HttpServletRequest req) {
//update-begin---author:wangshuai---date:2025-03-26---for:【issues/7948】角色解决根据id查询回显不对---
if(null != isMultiTranslate && isMultiTranslate){
pageSize = 100;
}
//update-end---author:wangshuai---date:2025-03-26---for:【issues/7948】角色解决根据id查询回显不对---
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
@RequestParam(name="isMultiTranslate", required = false) Boolean isMultiTranslate,
HttpServletRequest req) {
//update-begin---author:wangshuai---date:2025-03-26---for:【issues/7948】角色解决根据id查询回显不对---
if(null != isMultiTranslate && isMultiTranslate){
pageSize = 100;
}
//update-end---author:wangshuai---date:2025-03-26---for:【issues/7948】角色解决根据id查询回显不对---
Result<IPage<SysRole>> result = new Result<IPage<SysRole>>();
//QueryWrapper<SysRole> queryWrapper = QueryGenerator.initQueryWrapper(role, req.getParameterMap());
//IPage<SysRole> pageList = sysRoleService.page(page, queryWrapper);
@@ -119,7 +119,7 @@ public class SysRoleController {
result.setResult(pageList);
return result;
}
/**
* 分页列表查询【租户角色,做租户隔离】
* @param role
@@ -130,15 +130,15 @@ public class SysRoleController {
*/
@RequestMapping(value = "/listByTenant", method = RequestMethod.GET)
public Result<IPage<SysRole>> listByTenant(SysRole role,
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
HttpServletRequest req) {
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
HttpServletRequest req) {
Result<IPage<SysRole>> result = new Result<IPage<SysRole>>();
//此接口必须通过租户来隔离查询
if(MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL) {
role.setTenantId(oConvertUtils.getInt(!"0".equals(TenantContext.getTenant()) ? TenantContext.getTenant() : "", -1));
}
QueryWrapper<SysRole> queryWrapper = QueryGenerator.initQueryWrapper(role, req.getParameterMap());
Page<SysRole> page = new Page<SysRole>(pageNo, pageSize);
IPage<SysRole> pageList = sysRoleService.page(page, queryWrapper);
@@ -146,21 +146,21 @@ public class SysRoleController {
result.setResult(pageList);
return result;
}
/**
* 添加
* 添加
* @param role
* @return
*/
@RequestMapping(value = "/add", method = RequestMethod.POST)
@RequiresPermissions("system:role:add")
@RequiresPermissions("system:role:add")
public Result<SysRole> add(@RequestBody SysRole role) {
Result<SysRole> result = new Result<SysRole>();
try {
//开启多租户隔离,角色id自动生成10位
//update-begin---author:wangshuai---date:2024-05-23---for:【TV360X-42】角色新增时设置的编码,保存后不一致---
if(MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL && oConvertUtils.isEmpty(role.getRoleCode())){
//update-end---author:wangshuai---date:2024-05-23---for:【TV360X-42】角色新增时设置的编码,保存后不一致---
//update-end---author:wangshuai---date:2024-05-23---for:【TV360X-42】角色新增时设置的编码,保存后不一致---
role.setRoleCode(RandomUtil.randomString(10));
}
role.setCreateTime(new Date());
@@ -172,13 +172,13 @@ public class SysRoleController {
}
return result;
}
/**
* 编辑
* 编辑
* @param role
* @return
*/
@RequiresPermissions("system:role:edit")
@RequiresPermissions("system:role:edit")
@RequestMapping(value = "/edit",method = {RequestMethod.PUT,RequestMethod.POST})
public Result<SysRole> edit(@RequestBody SysRole role) {
Result<SysRole> result = new Result<SysRole>();
@@ -201,7 +201,7 @@ public class SysRoleController {
}
}
//------------------------------------------------------------------
boolean ok = sysRoleService.updateById(role);
if(ok) {
result.success("修改成功!");
@@ -209,17 +209,42 @@ public class SysRoleController {
}
return result;
}
/**
* 通过id删除
* 编辑
* @param userDeptSaveDTO
* @return
*/
@Operation(summary = "根据用户id,角色id更新部门id", description = "根据用户id,角色id更新部门id") // 2. 接口描述
@RequestMapping(value = "/saveDeptsForUser", method = {RequestMethod.PUT, RequestMethod.POST})
public Result<Boolean> saveDeptsForUser(@Valid @RequestBody UserDeptSaveDTO userDeptSaveDTO) {
// 1. 调用 Service 层,获取执行结果(通常 Service 返回 boolean
boolean isSuccess = sysRoleService.saveDeptForRoleUser(
userDeptSaveDTO.getUserId(),
userDeptSaveDTO.getRoleId(),
userDeptSaveDTO.getDeptIds()
);
// 2. 根据结果返回对应的 Result 对象
if (isSuccess) {
// 使用静态方法(假设你的 Result 类支持,这是最常见的做法)
return Result.ok("修改成功!");
} else {
// 如果失败,返回错误状态,而不是 null
return Result.error("修改失败,请稍后重试");
}
}
/**
* 通过id删除
* @param id
* @return
*/
@RequiresPermissions("system:role:delete")
@RequiresPermissions("system:role:delete")
@RequestMapping(value = "/delete", method = RequestMethod.DELETE)
public Result<?> delete(@RequestParam(name="id",required=true) String id) {
//如果是saas隔离的情况下,判断当前租户id是否是当前租户下的
if(MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL){
//如果是saas隔离的情况下,判断当前租户id是否是当前租户下的
if(MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL){
//获取当前用户
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
int tenantId = oConvertUtils.getInt(TenantContext.getTenant(), 0);
@@ -230,25 +255,23 @@ public class SysRoleController {
return Result.error("删除角色失败,当前角色不在此租户中。");
}
}
//update-begin---author:wangshuai---date:2024-01-16---for:【QQYUN-7974】禁止删除 admin 角色---
//是否存在admin角色
sysRoleService.checkAdminRoleRejectDel(id);
//update-end---author:wangshuai---date:2024-01-16---for:【QQYUN-7974】禁止删除 admin 角色---
sysRoleService.deleteRole(id);
// 角色删除,触发同步工作流
this.throwSynchronizationProcessSignal(id);
return Result.ok("删除角色成功");
}
/**
* 批量删除
* 批量删除
* @param ids
* @return
*/
@RequiresPermissions("system:role:deleteBatch")
@RequiresPermissions("system:role:deleteBatch")
@RequestMapping(value = "/deleteBatch", method = RequestMethod.DELETE)
public Result<SysRole> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
baseCommonService.addLog("删除角色操作,角色ids" + ids, CommonConstant.LOG_TYPE_2, CommonConstant.OPERATE_TYPE_4);
@@ -274,15 +297,13 @@ public class SysRoleController {
//验证是否为admin角色
sysRoleService.checkAdminRoleRejectDel(ids);
sysRoleService.deleteBatchRole(ids.split(","));
// 角色删除,触发同步工作流
this.throwSynchronizationProcessSignal(ids);
result.success("删除角色成功!");
}
return result;
}
/**
* 通过id查询
* 通过id查询
* @param id
* @return
*/
@@ -301,7 +322,7 @@ public class SysRoleController {
/**
* 查询全部角色(参与租户隔离)
*
*
* @return
*/
@RequestMapping(value = "/queryall", method = RequestMethod.GET)
@@ -343,14 +364,14 @@ public class SysRoleController {
}
return result;
}
/**
* 校验角色编码唯一
* 校验角色编码唯一
*/
@RequestMapping(value = "/checkRoleCode", method = RequestMethod.GET)
public Result<Boolean> checkUsername(String id,String roleCode) {
Result<Boolean> result = new Result<>();
//如果此参数为false则程序发生异常
//如果此参数为false则程序发生异常
result.setResult(true);
log.info("--验证角色编码是否唯一---id:"+id+"--roleCode:"+roleCode);
try {
@@ -396,7 +417,7 @@ public class SysRoleController {
sysRole.setTenantId(oConvertUtils.getInt(TenantContext.getTenant(), 0));
}
//------------------------------------------------------------------------------------------------
// Step.1 组装查询条件
QueryWrapper<SysRole> queryWrapper = QueryGenerator.initQueryWrapper(sysRole, request.getParameterMap());
//Step.2 AutoPoi 导出Excel
@@ -422,7 +443,7 @@ public class SysRoleController {
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
// 获取上传文件对象
// 获取上传文件对象
MultipartFile file = entity.getValue();
ImportParams params = new ImportParams();
params.setTitleRows(2);
@@ -443,7 +464,7 @@ public class SysRoleController {
}
return Result.error("文件导入失败!");
}
/**
* 查询数据规则数据
*/
@@ -472,7 +493,7 @@ public class SysRoleController {
//TODO 以后按钮权限的查询也走这个请求 无非在map中多加两个key
}
}
/**
* 保存数据规则至角色菜单关联表
*/
@@ -499,8 +520,8 @@ public class SysRoleController {
}
return Result.ok("保存成功!");
}
/**
* 用户角色授权功能,查询菜单权限树
* @param request
@@ -522,9 +543,9 @@ public class SysRoleController {
List<TreeModel> treeList = new ArrayList<>();
getTreeModelList(treeList, list, null);
Map<String,Object> resMap = new HashMap(5);
//全部树节点数据
//全部树节点数据
resMap.put("treeList", treeList);
//全部树ids
//全部树ids
resMap.put("ids", ids);
result.setResult(resMap);
result.setSuccess(true);
@@ -533,7 +554,7 @@ public class SysRoleController {
}
return result;
}
private void getTreeModelList(List<TreeModel> treeList,List<SysPermission> metaList,TreeModel temp) {
for (SysPermission permission : metaList) {
String tempPid = permission.getParentId();
@@ -549,19 +570,110 @@ public class SysRoleController {
getTreeModelList(treeList, metaList, tree);
}
}
}
}
/**
* TODO 权限未完成(明道云接口,租户应用)
* 分页获取全部角色列表(包含每个角色的数量)
* @return
*/
@RequestMapping(value = "/queryPageRoleCount", method = RequestMethod.GET)
public Result<IPage<SysUserRoleCountVo>> queryPageRoleCount(@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize) {
Result<IPage<SysUserRoleCountVo>> result = new Result<>();
/**
* 根据指定的权限IDs,查询其下所有子孙节点并构建树
*/
@RequestMapping(value = "/queryTreeListByIds", method = RequestMethod.GET)
@Operation(summary = "根据指定的部门id,返回其下属所有的syspermession", description = "根据指定的部门id,返回其下属所有的syspermession")
public Result<Map<String, Object>> queryTreeList(@RequestParam(name = "ids") String idsStr) {
Result<Map<String, Object>> result = new Result<>();
try {
// 1. 获取所有原始数据
LambdaQueryWrapper<SysPermission> query = new LambdaQueryWrapper<>();
query.eq(SysPermission::getDelFlag, CommonConstant.DEL_FLAG_0);
query.orderByAsc(SysPermission::getSortNo);
List<SysPermission> allList = sysPermissionService.list(query);
// 2. 准备初始 ID 集合(假设传入逗号分隔的字符串)
List<String> startIds = Arrays.asList(idsStr.split(","));
// 3. 筛选出目标范围:初始节点 + 它们的所有子孙
List<SysPermission> filteredList = new ArrayList<>();
Set<String> addedIds = new HashSet<>(); // 用于去重
for (SysPermission p : allList) {
if (startIds.contains(p.getId())) {
filteredList.add(p);
addedIds.add(p.getId());
// 递归寻找当前节点的所有后代
getChildrenSysPermission(p.getId(), allList, filteredList);
}
}
// 4. 统计最终范围内所有的 ID(用于前端勾选等场景)
List<String> finalIds = filteredList.stream().map(SysPermission::getId).collect(Collectors.toList());
// 5. 构建树形结构
List<TreeModel> treeList = new ArrayList<>();
// 注意:这里的 startIds 用于告诉构建函数,谁是这棵“局部树”的根
getTreeModelListByScope(treeList, filteredList, null, startIds);
Map<String, Object> resMap = new HashMap<>(5);
resMap.put("treeList", treeList);
resMap.put("ids", finalIds);
result.setResult(resMap);
result.setSuccess(true);
} catch (Exception e) {
log.error(e.getMessage(), e);
result.error500("查询失败");
}
return result;
}
/**
* 递归构建树模型(适配局部搜索)
*/
private void getTreeModelListByScope(List<TreeModel> treeList, List<SysPermission> metaList, TreeModel temp, List<String> startIds) {
for (SysPermission permission : metaList) {
String tempPid = permission.getParentId();
TreeModel tree = new TreeModel(permission.getId(), tempPid, permission.getName(), permission.getRuleFlag(), permission.isLeaf());
if (temp == null) {
// 如果当前没有父节点,且该节点属于我们指定的初始起始点,则它就是根
if (startIds.contains(permission.getId())) {
treeList.add(tree);
if (!tree.getIsLeaf()) {
getTreeModelListByScope(treeList, metaList, tree, startIds);
}
}
} else {
// 如果有父节点,匹配 PID
if (Objects.equals(tempPid, temp.getKey())) {
temp.getChildren().add(tree);
if (!tree.getIsLeaf()) {
getTreeModelListByScope(treeList, metaList, tree, startIds);
}
}
}
}
}
/**
* 递归寻找子节点(顺藤摸瓜)
*/
private void getChildrenSysPermission(String permissionId, List<SysPermission> metaList, List<SysPermission> filteredList) {
for (SysPermission sysPermission : metaList) {
if (Objects.equals(sysPermission.getParentId(), permissionId)) {
filteredList.add(sysPermission);
// 继续深挖
getChildrenSysPermission(sysPermission.getId(), metaList, filteredList);
}
}
}
/**
* 分页获取全部角色列表(包含每个角色的数量)
* @return
*/
@RequestMapping(value = "/queryPageRoleCount", method = RequestMethod.GET)
public Result<IPage<SysUserRoleCountVo>> queryPageRoleCount(@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize) {
Result<IPage<SysUserRoleCountVo>> result = new Result<>();
LambdaQueryWrapper<SysRole> query = new LambdaQueryWrapper<SysRole>();
//------------------------------------------------------------------------------------------------
//是否开启系统管理模块的多租户数据隔离【SAAS多租户模式】
@@ -569,38 +681,27 @@ public class SysRoleController {
query.eq(SysRole::getTenantId, oConvertUtils.getInt(TenantContext.getTenant(), 0));
}
//------------------------------------------------------------------------------------------------
Page<SysRole> page = new Page<>(pageNo, pageSize);
IPage<SysRole> pageList = sysRoleService.page(page, query);
List<SysRole> records = pageList.getRecords();
IPage<SysUserRoleCountVo> sysRoleCountPage = new PageDTO<>();
List<SysUserRoleCountVo> sysCountVoList = new ArrayList<>();
//循环角色数据获取每个角色下面对应的角色数量
for (SysRole role:records) {
LambdaQueryWrapper<SysUserRole> countQuery = new LambdaQueryWrapper<>();
Page<SysRole> page = new Page<>(pageNo, pageSize);
IPage<SysRole> pageList = sysRoleService.page(page, query);
List<SysRole> records = pageList.getRecords();
IPage<SysUserRoleCountVo> sysRoleCountPage = new PageDTO<>();
List<SysUserRoleCountVo> sysCountVoList = new ArrayList<>();
//循环角色数据获取每个角色下面对应的角色数量
for (SysRole role:records) {
LambdaQueryWrapper<SysUserRole> countQuery = new LambdaQueryWrapper<>();
countQuery.eq(SysUserRole::getRoleId,role.getId());
long count = sysUserRoleService.count(countQuery);
SysUserRoleCountVo countVo = new SysUserRoleCountVo();
BeanUtils.copyProperties(role,countVo);
countVo.setCount(count);
sysCountVoList.add(countVo);
}
sysRoleCountPage.setRecords(sysCountVoList);
sysRoleCountPage.setTotal(pageList.getTotal());
sysRoleCountPage.setSize(pageList.getSize());
result.setSuccess(true);
result.setResult(sysRoleCountPage);
return result;
}
/**
* 角色删除,触发同步工作流
*
* @param roleIds
*/
private void throwSynchronizationProcessSignal(String roleIds) {
// 触发流程同步信号事件
BaseMap baseMap = new BaseMap();
baseMap.put("roleIds", roleIds);
jeecgRedisClient.sendMessage(FlowEventTypeConst.DELETE_ROLE_2_BPM_REDIS_HANDLER, baseMap);
long count = sysUserRoleService.count(countQuery);
SysUserRoleCountVo countVo = new SysUserRoleCountVo();
BeanUtils.copyProperties(role,countVo);
countVo.setCount(count);
sysCountVoList.add(countVo);
}
sysRoleCountPage.setRecords(sysCountVoList);
sysRoleCountPage.setTotal(pageList.getTotal());
sysRoleCountPage.setSize(pageList.getSize());
result.setSuccess(true);
result.setResult(sysRoleCountPage);
return result;
}
}
@@ -9,6 +9,8 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
@@ -27,6 +29,7 @@ import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.*;
import org.jeecg.config.mybatis.MybatisPlusSaasConfig;
import org.jeecg.modules.base.service.BaseCommonService;
import org.jeecg.modules.system.dto.DeptRoleVO;
import org.jeecg.modules.system.entity.*;
import org.jeecg.modules.system.model.DepartIdModel;
import org.jeecg.modules.system.model.SysUserSysDepartModel;
@@ -34,6 +37,7 @@ import org.jeecg.modules.system.service.*;
import org.jeecg.modules.system.util.ImportOldUserUtil;
import org.jeecg.modules.system.vo.SysDepartUsersVO;
import org.jeecg.modules.system.vo.SysUserExportVo;
import org.jeecg.modules.system.vo.SysUserRoleDeptsVo;
import org.jeecg.modules.system.vo.SysUserRoleVO;
import org.jeecg.modules.system.vo.lowapp.DepartAndUserInfo;
import org.jeecg.modules.system.vo.lowapp.UpdateDepartInfo;
@@ -42,6 +46,7 @@ import org.jeecgframework.poi.excel.def.NormalExcelConstants;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
import org.jetbrains.kotlin.com.intellij.psi.SyntaxTraverser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
@@ -66,6 +71,7 @@ import java.util.stream.Collectors;
@Slf4j
@RestController
@RequestMapping("/sys/user")
@Tag(name = "用户管理模块", description = "处理用户与角色、部门的关系") // 1. 分类
public class SysUserController {
@Autowired
@@ -106,7 +112,8 @@ public class SysUserController {
@Autowired
private JeecgRedisClient jeecgRedisClient;
/**
* 获取租户下用户数据(支持租户隔离)
* @param user
@@ -152,6 +159,24 @@ public class SysUserController {
return sysUserService.queryPageList(req, queryWrapper, pageSize, pageNo);
}
/**
* 获取系统用户数据(查询全部用户,不做租户隔离)
*
* @param user
* @param pageNo
* @param pageSize
* @param req
* @return
*/
@RequiresPermissions("system:user:listAll")
@RequestMapping(value = "/listAllExcludeAdmin", method = RequestMethod.GET)
public Result<IPage<SysUser>> queryAllPageListExcludeAdmin(SysUser user, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest req) {
QueryWrapper<SysUser> queryWrapper = QueryGenerator.initQueryWrapper(user, req.getParameterMap());
queryWrapper.notLike("username", "admin");
return sysUserService.queryPageList(req, queryWrapper, pageSize, pageNo);
}
@RequiresPermissions("system:user:add")
@RequestMapping(value = "/add", method = RequestMethod.POST)
public Result<SysUser> add(@RequestBody JSONObject jsonObject) {
@@ -260,7 +285,7 @@ public class SysUserController {
baseCommonService.addLog("批量删除用户, ids " +ids ,CommonConstant.LOG_TYPE_2, 3);
List<String> userNameList = sysUserService.userIdToUsername(Arrays.asList(ids.split(",")));
this.sysUserService.deleteBatchUsers(ids);
// 用户变更,触发同步工作流
if (!userNameList.isEmpty()) {
String joinedString = String.join(",", userNameList);
@@ -475,15 +500,66 @@ public class SysUserController {
@RequestParam(name="realname",required=false) String realname,
@RequestParam(name="username",required=false) String username,
@RequestParam(name="isMultiTranslate",required=false) String isMultiTranslate,
@RequestParam(name="id",required = false) String id) {
@RequestParam(name="id",required = false) String id,
@RequestParam(name="searchSecurityLevel",required = false) Integer searchSecurityLevel
) {
//update-begin-author:taoyan date:2022-7-14 for: VUEN-1702【禁止问题】sql注入漏洞
String[] arr = new String[]{departId, realname, username, id};
SqlInjectionUtil.filterContent(arr, SymbolConstant.SINGLE_QUOTATION_MARK);
//update-end-author:taoyan date:2022-7-14 for: VUEN-1702【禁止问题】sql注入漏洞
IPage<SysUser> pageList = sysUserDepartService.queryDepartUserPageList(departId, username, realname, pageSize, pageNo,id,isMultiTranslate);
IPage<SysUser> pageList = sysUserDepartService.queryDepartUserPageList(departId, username, realname, pageSize, pageNo,id,searchSecurityLevel,isMultiTranslate);
return Result.OK(pageList);
}
/**
* 用户选择组件 专用 根据用户账号或部门,角色分页查询
* @param departId
* @param username
* @return
*/
@RequestMapping(value = "/queryUserRoleComponentData", method = RequestMethod.GET)
@Operation(summary = "根据角色ID,部门ID以及用户密级查询用户列表", description = "原生用户查询逻辑加上密级筛选以及角色筛选") // 2. 接口描述
public Result<IPage<SysUser>> queryUserRoleComponentData(
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
@RequestParam(name = "departId", required = false) String departId,
@RequestParam(name = "roleId", required = false) String roleId,
@RequestParam(name="realname",required=false) String realname,
@RequestParam(name="username",required=false) String username,
@RequestParam(name="isMultiTranslate",required=false) String isMultiTranslate,
@RequestParam(name="id",required = false) String id,
@RequestParam(name="searchSecurityLevel",required = false) Integer searchSecurityLevel
) {
//update-begin-author:taoyan date:2022-7-14 for: VUEN-1702【禁止问题】sql注入漏洞
String[] arr = new String[]{departId, realname, username, id};
SqlInjectionUtil.filterContent(arr, SymbolConstant.SINGLE_QUOTATION_MARK);
//update-end-author:taoyan date:2022-7-14 for: VUEN-1702【禁止问题】sql注入漏洞
IPage<SysUser> pageList = sysUserDepartService.queryDepartRoleUserPageList(departId,roleId,username, realname, pageSize, pageNo,id,searchSecurityLevel,isMultiTranslate);
return Result.OK(pageList);
}
/**
* 用户选择组件 专用 根据用户账号或部门,角色分页查询
* @param deptRoleVO
* @return
*/
@RequestMapping(value = "/queryUserByDeptAndROle", method = RequestMethod.GET)
@Operation(summary = "根据角色ID,部门ID以及用户密级查询当前用户列表", description = "原生用户查询逻辑加上密级筛选以及角色筛选") // 2. 接口描述
public Result<List<SysUser>> queryUserByDeptAndROle(DeptRoleVO deptRoleVO
) {
try {
List<SysUser> sysUserList = sysUserService.queryUserByDeptAndROle(
deptRoleVO.getDeptId(),
deptRoleVO.getRoleId(),
deptRoleVO.getSecretLevel()
);
return Result.ok(sysUserList); // 假设你的 Result 有 ok 方法
} catch (Exception e) {
log.error("查询用户列表失败", e); // 记得打日志
return Result.error("查询失败:" + e.getMessage()); // 返回错误信息
}
}
/**
* 导出excel
*
@@ -607,6 +683,21 @@ public class SysUserController {
return result;
}
@RequestMapping(value = "/userRoleListWithDepts", method = RequestMethod.GET)
public Result<IPage<SysUserRoleDeptsVo>> userRoleListWithDepts(
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize, HttpServletRequest req) {
Result<IPage<SysUserRoleDeptsVo>> result = new Result<IPage<SysUserRoleDeptsVo>>();
Page<SysUserRoleDeptsVo> page = new Page<SysUserRoleDeptsVo>(pageNo, pageSize);
String roleId = req.getParameter("roleId");
String username = req.getParameter("username");
IPage<SysUserRoleDeptsVo> pageList = sysUserService.getUserByRoleIdWithDeptIds(page,roleId,username);
result.setSuccess(true);
result.setResult(pageList);
return result;
}
/**
* 给指定角色添加用户
*
@@ -887,7 +978,7 @@ public class SysUserController {
}
return result;
}
/**
* 查询当前用户的所有部门/当前部门编码
* @return
@@ -910,12 +1001,12 @@ public class SysUserController {
return result;
}
/**
* 用户注册接口
*
*
* @param jsonObject
* @param user
* @return
@@ -978,7 +1069,7 @@ public class SysUserController {
if(oConvertUtils.isEmpty(realname)){
realname = username;
}
try {
user.setCreateTime(new Date());// 设置创建时间
String salt = oConvertUtils.randomGen(8);
@@ -1073,7 +1164,7 @@ public class SysUserController {
result.setSuccess(true);
return result;
}
/**
* 用户更改密码
*/
@@ -1125,11 +1216,11 @@ public class SysUserController {
return result;
}
}
/**
* 根据TOKEN获取用户的部分信息(返回的数据是可供表单设计器使用的数据)
*
*
* @return
*/
@GetMapping("/getUserSectionInfoByToken")
@@ -1140,7 +1231,7 @@ public class SysUserController {
if (oConvertUtils.isEmpty(token)) {
username = JwtUtil.getUserNameByToken(request);
} else {
username = JwtUtil.getUsername(token);
username = JwtUtil.getUsername(token);
}
log.debug(" ------ 通过令牌获取部分用户信息,当前用户: " + username);
@@ -1161,7 +1252,7 @@ public class SysUserController {
return Result.error(500, "查询失败:" + e.getMessage());
}
}
/**
* 【APP端接口】获取用户列表 根据用户名和真实名 模糊匹配
* @param keyword
@@ -1198,7 +1289,7 @@ public class SysUserController {
log.error(e.getMessage(), e);
return Result.error(500, "查询失败:" + e.getMessage());
}
}
/**
@@ -1771,7 +1862,7 @@ public class SysUserController {
Integer tenantId = sysUser.getLoginTenantId();
LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
String userId = loginUser.getId();
// 判断 指定的租户ID是不是当前登录用户的租户
LambdaQueryWrapper<SysUserTenant> query = new LambdaQueryWrapper<>();
query.eq(SysUserTenant::getTenantId, tenantId);
@@ -1780,7 +1871,7 @@ public class SysUserController {
if(null == one){
return result.error500("非租户下的用户,不允许修改!");
}
// 修改 loginTenantId
LambdaQueryWrapper<SysUser> update = new LambdaQueryWrapper<SysUser>()
.eq(SysUser::getId, userId);
@@ -1788,7 +1879,7 @@ public class SysUserController {
updateUser.setLoginTenantId(tenantId);
sysUserService.update(updateUser, update);
return Result.ok();
}
}
/**
* 应用用户导出
@@ -1799,7 +1890,7 @@ public class SysUserController {
public ModelAndView exportAppUser(HttpServletRequest request) {
return sysUserService.exportAppUser(request);
}
/**
* 应用用户导入
* @param request
@@ -0,0 +1,15 @@
package org.jeecg.modules.system.dto;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@Data
public class DeptRoleVO {
@NotBlank(message = "角色id不为空")
private String roleId;
@NotBlank(message = "deptId不为空")
private String deptId;
@NotBlank(message = "secretLevel不为空")
private Integer secretLevel;
}
@@ -0,0 +1,15 @@
package org.jeecg.modules.system.dto;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@Data
public class UserDeptSaveDTO {
@NotBlank(message = "角色id不为空")
private String roleId;
@NotBlank(message = "userId不为空")
private String userId;
@NotBlank(message = "deptId不为空")
private String deptIds;
}
@@ -88,6 +88,7 @@ public class SysDepart implements Serializable {
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date updateTime;
/**租户ID*/
private java.lang.Integer tenantId;
@@ -102,7 +103,11 @@ public class SysDepart implements Serializable {
@TableField(exist = false)
private String oldDirectorUserIds;
//update-end---author:wangshuai ---date:20200308 for[JTC-119]新增字段负责人ids和旧的负责人ids
/**部门类型(0所领导,1职能部门,2业务部门,3专项组)*/
@Dict(dicCode = "depart_type")
private String departType;
/**
* 重写equals方法
*/
@@ -0,0 +1,132 @@
package org.jeecg.modules.system.entity;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.math.BigDecimal;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.TableLogic;
import org.jeecg.common.constant.ProvinceCityArea;
import org.jeecg.common.util.SpringContextUtils;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
import org.jeecgframework.poi.excel.annotation.Excel;
import org.jeecg.common.aspect.annotation.Dict;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* @Description: sys_file_attachment
* @Author: jeecg-boot
* @Date: 2026-03-26
* @Version: V1.0
*/
@Data
@TableName("sys_file_attachment")
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
@Schema(description="sys_file_attachment")
public class SysFileAttachment implements Serializable {
private static final long serialVersionUID = 1L;
/**id*/
@TableId(type = IdType.ASSIGN_ID)
@Schema(description = "id")
private java.lang.String id;
/**创建人*/
@Schema(description = "创建人")
private java.lang.String createBy;
/**创建日期*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@Schema(description = "创建日期")
private java.util.Date createTime;
/**更新人*/
@Schema(description = "更新人")
private java.lang.String updateBy;
/**更新日期*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@Schema(description = "更新日期")
private java.util.Date updateTime;
/**单位编码*/
@Excel(name = "单位编码", width = 15)
@Schema(description = "单位编码")
private java.lang.String orgCode;
/**附件名称*/
@Excel(name = "附件名称", width = 15)
@Schema(description = "附件名称")
private java.lang.String fileName;
/**密级*/
@Excel(name = "密级", width = 15)
@Schema(description = "密级")
private java.lang.String secretLevel;
/**路径*/
@Excel(name = "路径", width = 15)
@Schema(description = "路径")
private java.lang.String path;
/**密级名称*/
@Excel(name = "密级名称", width = 15)
@Schema(description = "密级名称")
private java.lang.String secretText;
/**部门编码*/
@Excel(name = "部门编码", width = 15)
@Schema(description = "部门编码")
private java.lang.String deptCode;
/**租户id*/
@Excel(name = "租户id", width = 15)
@Schema(description = "租户id")
private java.lang.String tenantId;
/**文件大小(b)*/
@Excel(name = "文件大小(b)", width = 15)
@Schema(description = "文件大小(b)")
private java.lang.Integer size;
/**备用字段*/
@Excel(name = "备用字段", width = 15)
@Schema(description = "备用字段")
private java.lang.String extend;
/**备用字段2*/
@Excel(name = "备用字段2", width = 15)
@Schema(description = "备用字段2")
private java.lang.String extend2;
/**备用字段3*/
@Excel(name = "备用字段3", width = 15)
@Schema(description = "备用字段3")
private java.lang.String extend3;
/**备用字段4*/
@Excel(name = "备用字段4", width = 15)
@Schema(description = "备用字段4")
private java.lang.String extend4;
/**文件id*/
@Excel(name = "文件id", width = 15)
@Schema(description = "文件id")
private java.lang.String fileId;
/**文件后缀*/
@Excel(name = "文件后缀", width = 15)
@Schema(description = "文件后缀")
private java.lang.String fileSuffix;
/**文件类别*/
@Excel(name = "文件类别", width = 15)
@Schema(description = "文件类别")
private java.lang.String fileType;
/**向上名称*/
@Excel(name = "向上名称", width = 15)
@Schema(description = "向上名称")
private java.lang.String upName;
/**文件上传类型*/
@Excel(name = "文件上传类型", width = 15)
@Schema(description = "文件上传类型")
private java.lang.String fileUploadType;
/**关联业务表单id*/
@Excel(name = "关联业务表单id", width = 15)
@Schema(description = "关联业务表单id")
private java.lang.String businessId;
/**删除状态(0,正常,1已删除)*/
@TableLogic
@Dict(dicCode = "del_flag")
private String delFlag;
}
@@ -2,15 +2,12 @@ package org.jeecg.modules.system.entity;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.jeecg.common.aspect.annotation.Dict;
import org.jeecgframework.poi.excel.annotation.Excel;
import org.springframework.format.annotation.DateTimeFormat;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.io.Serializable;
@@ -30,6 +27,7 @@ import lombok.experimental.Accessors;
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("sys_user")
public class SysUser implements Serializable {
private static final long serialVersionUID = 1L;
@@ -211,4 +209,20 @@ public class SysUser implements Serializable {
*/
@TableField(exist = false)
private boolean izBindThird;
/**
* 人员密级(3非密,4一般,5重要)
*/
@Excel(name = "密级", width = 15,dicCode="user_security_level")
@Dict(dicCode = "user_security_level")
private Integer userSecurityLevel;
/**
* 是否为专项(0非专项,1专项)
*/
@Excel(name = "人员是否专项", width = 15,dicCode="user_is_special")
@Dict(dicCode = "is_special")
private Integer isSpecial;
}
@@ -39,6 +39,11 @@ public class SysUserRole implements Serializable {
/**租户ID*/
private java.lang.Integer tenantId;
/**
* 部门id
*/
private String deptId;
public SysUserRole() {
}
@@ -0,0 +1,17 @@
package org.jeecg.modules.system.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.jeecg.modules.system.entity.SysFileAttachment;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @Description: sys_file_attachment
* @Author: jeecg-boot
* @Date: 2026-03-26
* @Version: V1.0
*/
public interface SysFileAttachmentMapper extends BaseMapper<SysFileAttachment> {
}
@@ -9,6 +9,8 @@ import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.entity.SysUserDepart;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import javax.validation.constraints.NotBlank;
/**
* @Description: 用户部门mapper接口
* @author: jeecg-boot
@@ -40,7 +42,18 @@ public interface SysUserDepartMapper extends BaseMapper<SysUserDepart>{
*/
IPage<SysUser> queryDepartUserPageList(Page<SysUser> page, @Param("orgCode") String orgCode, @Param("username") String username, @Param("realname") String realname);
/**
/**
* 根据部门查询部门用户
* @param page
* @param orgCode
* @param username
* @param realname
* @return
*/
IPage<SysUser> queryOneDepartUserPageList(Page<SysUser> page, @Param("orgCode") String orgCode, @Param("username") String username, @Param("realname") String realname);
/**
* 获取用户信息
* @param page
* @param orgCode
@@ -6,10 +6,13 @@ import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.jeecg.modules.system.entity.SysDepart;
import org.jeecg.modules.system.entity.SysUser;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.jeecg.modules.system.entity.SysUserDepart;
import org.jeecg.modules.system.model.SysUserSysDepartModel;
import org.jeecg.modules.system.vo.SysUserDepVo;
import org.jeecg.modules.system.vo.SysUserRoleDeptsVo;
import java.util.List;
@@ -77,7 +80,16 @@ public interface SysUserMapper extends BaseMapper<SysUser> {
* @return
*/
IPage<SysUser> getUserByRoleId(Page page, @Param("roleId") String roleId, @Param("username") String username);
/**
* 根据角色Id查询带部门的用户信息
* @param page
* @param roleId 角色id
* @param username 用户登录账户
* @return
*/
IPage<SysUserRoleDeptsVo> getUserByRoleIdWithDeptIds(Page page, @Param("roleId") String roleId, @Param("username") String username);
/**
* 根据用户名设置部门ID
* @param username
@@ -91,7 +103,8 @@ public interface SysUserMapper extends BaseMapper<SysUser> {
* @return
*/
public SysUser getUserByPhone(@Param("phone") String phone);
public List<SysDepart> queryUserAffiliatedDepts(@Param("userName") String userName);
/**
* 根据邮箱查询用户信息
@@ -222,4 +235,13 @@ public interface SysUserMapper extends BaseMapper<SysUser> {
*/
@Select("select id,phone from sys_user where phone = #{phone} and username = #{username}")
SysUser getUserByNameAndPhone(@Param("phone") String phone, @Param("username") String username);
/**
* 通过部门id和角色id,密级获取用户
* @param deptId
* @param roleId
* @parm secretLevel
* @return
*/
List<SysUser> queryUserByDeptAndROle( String deptId, String roleId, Integer secretLevel);
}
@@ -3,6 +3,7 @@ package org.jeecg.modules.system.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import org.jeecg.modules.system.entity.SysUserRole;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
@@ -40,4 +41,9 @@ public interface SysUserRoleMapper extends BaseMapper<SysUserRole> {
@Select("select id from sys_role where id in (select role_id from sys_user_role where user_id = (select id from sys_user where username=#{username}))")
List<String> getRoleIdByUserName(@Param("username") String username);
@Update("UPDATE sys_user_role SET dept_id = #{deptIds} " +
"WHERE user_id = #{userId} AND role_id = #{roleId}")
int saveDeptForRoleUser(@Param("userId") String userId,
@Param("roleId") String roleId,
@Param("deptIds") String deptIds);
}
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.jeecg.modules.system.mapper.SysFileAttachmentMapper">
</mapper>
@@ -39,6 +39,23 @@
</if>
</select>
<!-- 根据部门查询部门用户 分页 -->
<select id="queryOneDepartUserPageList" resultType="org.jeecg.modules.system.entity.SysUser">
select DISTINCT a.* from sys_user a
left join sys_user_depart b on b.user_id = a.id
left join sys_depart c on b.dep_id = c.id
where a.del_flag = 0
and a.status = 1
and c.org_code = #{orgCode} <!-- 重点:直接等于,不要like -->
and a.username!='_reserve_user_external'
<if test="username!=null and username!=''">
and a.username like concat('%',#{username},'%')
</if>
<if test="realname!=null and realname!=''">
and a.realname like concat('%',#{realname},'%')
</if>
</select>
<!--获取用户信息(聊天专用)-->
<select id="getUserInformation" resultType="org.jeecg.modules.system.entity.SysUser">
select DISTINCT a.* from sys_user a
@@ -58,7 +58,32 @@
and username = #{username}
</if>
</select>
<select id="getUserByRoleIdWithDeptIds" resultType="org.jeecg.modules.system.vo.SysUserRoleDeptsVo">
SELECT
u.id as user_id,
u.*,
r.dept_id AS deptId FROM sys_user u
INNER JOIN sys_user_role r ON u.id = r.user_id
WHERE u.del_flag = 0
AND r.role_id = #{roleId}
<if test="username != null and username != ''">
AND u.username = #{username}
</if>
</select>
<select id="queryUserAffiliatedDepts" resultType="org.jeecg.modules.system.entity.SysDepart">
SELECT
d.* FROM
sys_depart d
INNER JOIN sys_user_depart ud ON d.id = ud.dep_id
INNER JOIN sys_user u ON ud.user_id = u.id
<where>
<if test="userName != null and userName != ''">
AND u.username = #{userName}
</if>
</where>
</select>
<!-- 修改用户部门code -->
<update id="updateUserDepart">
UPDATE sys_user SET
@@ -298,4 +323,20 @@
and sut.tenant_id=#{tenantId}
and sut.status = '1'
</select>
<!--根据部门id获取用户数据-->
<select id="queryUserByDeptAndROle" resultType="org.jeecg.modules.system.entity.SysUser">
SELECT
u.*
FROM
sys_user u
INNER JOIN
sys_user_role
AS tem ON u.id = tem.user_id
where u.user_security_level >= #{secretLevel}
and tem.dept_id LIKE CONCAT('%', #{deptId}, '%')
and tem.role_id = #{roleId}
GROUP BY u.username
</select>
</mapper>
@@ -75,6 +75,8 @@ public class SysDepartTreeModel implements Serializable{
private Date updateTime;
private String departType;
//update-begin---author:wangshuai ---date:20200308 for[JTC-119]在部门管理菜单下设置部门负责人,新增字段部门负责人ids
/**部门负责人ids*/
private String directorUserIds;
@@ -113,6 +115,7 @@ public class SysDepartTreeModel implements Serializable{
this.updateBy = sysDepart.getUpdateBy();
this.updateTime = sysDepart.getUpdateTime();
this.directorUserIds = sysDepart.getDirectorUserIds();
this.departType = sysDepart.getDepartType();
if(0 == sysDepart.getIzLeaf()){
this.isLeaf = false;
}else{
@@ -166,6 +169,14 @@ public class SysDepartTreeModel implements Serializable{
this.id = id;
}
public String getDepartType() {
return departType;
}
public void setDepartType(String departType) {
this.departType = departType;
}
public List<SysDepartTreeModel> getChildren() {
return children;
}
@@ -385,7 +396,8 @@ public class SysDepartTreeModel implements Serializable{
Objects.equals(updateBy, model.updateBy) &&
Objects.equals(updateTime, model.updateTime) &&
Objects.equals(directorUserIds, model.directorUserIds) &&
Objects.equals(children, model.children);
Objects.equals(children, model.children) &&
Objects.equals(departType, model.departType);
}
/**
@@ -181,6 +181,10 @@ public interface ISysDepartService extends IService<SysDepart>{
*/
List<SysDepart> getMyDepartList();
List<SysDepart> queryUserAffiliatedDepts(String userName);
List<SysDepart> querySecondLevelDepts(Integer departType);
/**
* 删除部门
* @param id
@@ -0,0 +1,14 @@
package org.jeecg.modules.system.service;
import org.jeecg.modules.system.entity.SysFileAttachment;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @Description: sys_file_attachment
* @Author: jeecg-boot
* @Date: 2026-03-26
* @Version: V1.0
*/
public interface ISysFileAttachmentService extends IService<SysFileAttachment> {
}
@@ -61,6 +61,15 @@ public interface ISysRoleService extends IService<SysRole> {
*/
public boolean deleteBatchRole(String[] roleids);
/**
* 批量删除角色
* @param userId
* @param roleId
* @param deptIds
* @return
*/
Boolean saveDeptForRoleUser(String userId,String roleId,String deptIds);
/**
* 根据角色id和当前租户判断当前角色是否存在这个租户中
* @param id
@@ -54,9 +54,24 @@ public interface ISysUserDepartService extends IService<SysUserDepart> {
* @param isMultiTranslate 是否多字段翻译
* @return
*/
IPage<SysUser> queryDepartUserPageList(String departId, String username, String realname, int pageSize, int pageNo,String id,String isMultiTranslate);
IPage<SysUser> queryDepartUserPageList(String departId,String username, String realname, int pageSize, int pageNo,String id,Integer userSecurityLevel,String isMultiTranslate);
/**
/**
* 用户组件数据查询
* @param departId
* @param roleId
* @param username
* @param pageSize
* @param pageNo
* @param realname
* @param id
* @param isMultiTranslate 是否多字段翻译
* @return
*/
IPage<SysUser> queryDepartRoleUserPageList(String departId, String roleId, String username, String realname, int pageSize, int pageNo,String id,Integer userSecurityLevel,String isMultiTranslate);
/**
* 获取用户信息
* @param tenantId
* @param departId
@@ -13,12 +13,15 @@ import org.jeecg.modules.system.entity.SysRoleIndex;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.model.SysUserSysDepartModel;
import org.jeecg.modules.system.vo.SysUserExportVo;
import org.jeecg.modules.system.vo.SysUserRoleDeptsVo;
import org.jeecg.modules.system.vo.SysUserRoleVO;
import org.jeecg.modules.system.vo.lowapp.DepartAndUserInfo;
import org.jeecg.modules.system.vo.lowapp.UpdateDepartInfo;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotBlank;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
@@ -181,6 +184,15 @@ public interface ISysUserService extends IService<SysUser> {
*/
public IPage<SysUser> getUserByRoleId(Page<SysUser> page,String roleId, String username);
/**
* 根据角色Id查询
* @param page
* @param roleId 角色id
* @param username 用户账户名称
* @return
*/
public IPage<SysUserRoleDeptsVo> getUserByRoleIdWithDeptIds(Page<SysUserRoleDeptsVo> page, String roleId, String username);
/**
* 通过用户名获取用户角色集合
*
@@ -482,4 +494,6 @@ public interface ISysUserService extends IService<SysUser> {
* @param username
*/
void updatePasswordNotBindPhone(String oldPassword, String password, String username);
List<SysUser> queryUserByDeptAndROle(@NotBlank(message = "deptId不为空") String deptId, @NotBlank(message = "角色id不为空") String roleId, @NotBlank(message = "secretLevel不为空") Integer secretLevel);
}
@@ -1,5 +1,9 @@
package org.jeecg.modules.system.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
@@ -70,6 +74,7 @@ import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.util.*;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Value;
/**
* @Description: 底层共通业务API,提供其他独立模块调用
@@ -137,6 +142,12 @@ public class SysBaseApiImpl implements ISysBaseAPI {
@Autowired
private IDictTableWhiteListHandler dictTableWhiteListHandler;
@Autowired
ISysFileAttachmentService sysFileAttachmentService;
@Value(value = "${jeecg.appName}")
private String applicationName;
@Override
//@SensitiveDecode
public LoginUser getUserByName(String username) {
@@ -1841,4 +1852,251 @@ public class SysBaseApiImpl implements ISysBaseAPI {
}
}
/**
* 新增附件
*
* @param jsonObject
* @return
*/
@Override
public String addSysFileAttachment(JSONObject jsonObject) {
SysFileAttachment fileAttachment = new SysFileAttachment();
String filePath = jsonObject.getString("filePath");
String fileName = jsonObject.getString("fileName");
Integer size = jsonObject.getInteger("size");
fileAttachment.setFileName(fileName);
fileAttachment.setPath(filePath);
fileAttachment.setSize(size);
String secretLevel = ObjectUtil.isNotEmpty(jsonObject.get("secretLevel")) ? jsonObject.getString("secretLevel") : null;
String secretText = ObjectUtil.isNotEmpty(jsonObject.get("secretText")) ? jsonObject.getString("secretText") : null;
String businessId = ObjectUtil.isNotEmpty(jsonObject.get("businessId")) ? jsonObject.getString("businessId") : null;
fileAttachment.setSecretLevel(secretLevel);
fileAttachment.setSecretText(secretText);
fileAttachment.setBusinessId(businessId);
String fileSuffix = ObjectUtil.isNotEmpty(jsonObject.get("fileSuffix")) ? jsonObject.getString("fileSuffix") : null;
String fileUploadType = ObjectUtil.isNotEmpty(jsonObject.get("fileUploadType")) ? jsonObject.getString("fileUploadType") : null;
fileAttachment.setFileSuffix(fileSuffix);
fileAttachment.setFileUploadType(fileUploadType);
LambdaQueryWrapper<SysFileAttachment> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SysFileAttachment::getPath, filePath).eq(SysFileAttachment::getFileName, fileName);
SysFileAttachment entity = this.sysFileAttachmentService.getOne(wrapper);
if(entity==null){
boolean b = this.sysFileAttachmentService.save(fileAttachment);
if (b) {
return fileAttachment.getId();
}
}else{
return entity.getId();
}
return null;
}
/**
* 删除附件
*
* @param id
* @return
*/
@Override
public void deleteFileAttachment(String id) {
if (StringUtils.isNotEmpty(id)) {
this.sysFileAttachmentService.removeById(id);
}
}
/**
* 通过附件id查询附件
*
* @param id
* @return
*/
@Override
public String getFilePath(String id) {
if (StringUtils.isEmpty(id)) {
return null;
}
List<String> list = Arrays.asList(id.split(","));
List<SysFileAttachment> fileAttachments = this.sysFileAttachmentService.list(new LambdaQueryWrapper<SysFileAttachment>()
.in(SysFileAttachment::getId, list));
if (!CollectionUtil.isEmpty(fileAttachments)) {
List<Map<String, Object>> maps = new ArrayList<>();
for (SysFileAttachment fileAttachment : fileAttachments) {
Map<String, Object> map = new HashMap<>(4);
map.put("fileName", fileAttachment.getFileName());
map.put("filePath", fileAttachment.getPath());
map.put("secretLevel", fileAttachment.getSecretLevel());
map.put("secretText", fileAttachment.getSecretText());
maps.add(map);
}
JSONArray array = JSONArray.parseArray(JSON.toJSONString(maps));
return array.toString();
}
return null;
}
@Override
public JSONArray getFileDetialById(String ids) {
if (StringUtils.isEmpty(ids)) {
return null;
}
List<String> list = Arrays.asList(ids.split(","));
List<SysFileAttachment> fileAttachments = this.sysFileAttachmentService.list(new LambdaQueryWrapper<SysFileAttachment>()
.in(SysFileAttachment::getId, list));
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
Integer userSecretLevel = sysUser.getUserSecurityLevel();
if (!CollectionUtil.isEmpty(fileAttachments)) {
List<Map<String, Object>> maps = new ArrayList<>();
for (SysFileAttachment fileAttachment : fileAttachments) {
Map<String, Object> map = new HashMap<>(6);
map.put("filePath", fileAttachment.getPath());
map.put("fileName", fileAttachment.getFileName());
map.put("secretLevel", fileAttachment.getSecretLevel() == null ? "0" : fileAttachment.getSecretLevel());
map.put("secretText", fileAttachment.getSecretText());
map.put("size", fileAttachment.getSize());
map.put("id", fileAttachment.getId());
map.put("fileSuffix", fileAttachment.getFileSuffix());
map.put("fileUploadType", fileAttachment.getFileUploadType());
map.put("createTime", DateUtil.format(fileAttachment.getCreateTime(), DatePattern.NORM_DATETIME_FORMAT));
map.put("updateTIme", DateUtil.format(fileAttachment.getUpdateTime(), DatePattern.NORM_DATETIME_FORMAT));
map.put("createBy", fileAttachment.getCreateBy());
map.put("updateBy", fileAttachment.getUpdateBy());
if (Integer.parseInt(map.get("secretLevel").toString()) < userSecretLevel) {
maps.add(map);
}
}
return JSONArray.parseArray(JSON.toJSONString(maps));
}
return null;
}
@Override
public JSONArray getFileInfoByBussinessId(String bussinessId, String misFlag) {
LambdaQueryWrapper<SysFileAttachment> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(SysFileAttachment::getBusinessId, bussinessId);
if(misFlag.equals("true")){
queryWrapper.eq(SysFileAttachment::getFileUploadType,"Mis");
}else{
queryWrapper.eq(SysFileAttachment::getFileUploadType,applicationName);
}
List<SysFileAttachment> fileAttachments = this.sysFileAttachmentService.list(queryWrapper);
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
Integer userSecretLevel = sysUser.getUserSecurityLevel();
if (!CollectionUtil.isEmpty(fileAttachments)) {
List<Map<String, Object>> maps = new ArrayList<>();
for (SysFileAttachment fileAttachment : fileAttachments) {
Map<String, Object> map = new HashMap<>(6);
map.put("filePath", fileAttachment.getPath());
map.put("fileUrl", fileAttachment.getPath());
map.put("fileName", fileAttachment.getFileName());
map.put("secretLevel", fileAttachment.getSecretLevel() == null ? "0" : fileAttachment.getSecretLevel());
map.put("secretText", fileAttachment.getSecretText());
map.put("size", fileAttachment.getSize());
map.put("id", fileAttachment.getId());
map.put("fileSuffix", fileAttachment.getFileSuffix());
map.put("fileUploadType", fileAttachment.getFileUploadType());
map.put("createTime", DateUtil.format(fileAttachment.getCreateTime(), DatePattern.NORM_DATETIME_FORMAT));
map.put("updateTIme", DateUtil.format(fileAttachment.getUpdateTime(), DatePattern.NORM_DATETIME_FORMAT));
map.put("createBy", fileAttachment.getCreateBy());
map.put("updateBy", fileAttachment.getUpdateBy());
if (Integer.parseInt(map.get("secretLevel").toString()) < userSecretLevel) {
maps.add(map);
}
}
return JSONArray.parseArray(JSON.toJSONString(maps));
}
return null;
}
/**
* 通过附件id查询附件
*
* @param ids
* @return
*/
@Override
public String getFilesPath(String ids) {
if (StringUtils.isEmpty(ids)) {
return null;
}
List<String> list = Arrays.asList(ids.split(","));
List<SysFileAttachment> fileAttachments = this.sysFileAttachmentService.list(new LambdaQueryWrapper<SysFileAttachment>()
.in(SysFileAttachment::getId, list));
if (!CollectionUtil.isEmpty(fileAttachments)) {
StringBuilder sb = new StringBuilder();
for (SysFileAttachment fileAttachment : fileAttachments) {
sb.append(fileAttachment.getPath()).append(",");
}
return sb.toString();
}
return null;
}
/**
* 根据文件id查询文件对象
*
* @param id
* @return
*/
@Override
public Map<String, Object> queryFileMapById(String id) {
Map<String, Object> map = new HashMap<>();
SysFileAttachment fileAttachment = this.sysFileAttachmentService.getById(id);
if (ObjectUtil.isNotEmpty(fileAttachment)) {
map.put("fileName", fileAttachment.getFileName());
map.put("id", fileAttachment.getId());
map.put("filePath", fileAttachment.getPath());
map.put("secretLevel", fileAttachment.getSecretLevel());
map.put("secretText", fileAttachment.getSecretText());
map.put("fileSuffix", fileAttachment.getFileSuffix());
map.put("fileUploadType", fileAttachment.getFileUploadType());
map.put("createTime", DateUtil.format(fileAttachment.getCreateTime(), DatePattern.NORM_DATETIME_FORMAT));
map.put("updateTIme", DateUtil.format(fileAttachment.getUpdateTime(), DatePattern.NORM_DATETIME_FORMAT));
map.put("createBy", fileAttachment.getCreateBy());
map.put("updateBy", fileAttachment.getUpdateBy());
return map;
}
return null;
}
/**
* 通过fileId更新所有附件的bussinessId
*
* @param businessId
* @return
* @author ywy
*/
@Override
public String updateBusinessId(String businessId, List<String> deliverablesList){
LambdaQueryWrapper<SysFileAttachment> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(SysFileAttachment::getBusinessId, businessId);
queryWrapper.eq(SysFileAttachment::getFileUploadType,applicationName);
List<SysFileAttachment> list = this.sysFileAttachmentService.list(queryWrapper);
for(SysFileAttachment file: list) {
file.setExtend(file.getBusinessId());
file.setBusinessId("");
this.sysFileAttachmentService.updateById(file);
}
for(String fileId: deliverablesList){
LambdaQueryWrapper<SysFileAttachment> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SysFileAttachment::getId, fileId);
SysFileAttachment one = this.sysFileAttachmentService.getOne(wrapper);
if(one!=null){
one.setBusinessId(businessId);
this.sysFileAttachmentService.updateById(one);
}
}
return "";
}
}
@@ -884,6 +884,37 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
return null;
}
@Override
public List<SysDepart> queryUserAffiliatedDepts(String userName){
return this.sysUserMapper.queryUserAffiliatedDepts(userName);
}
public interface OrgCategoryConstant {
String COMPANY = "1";
String ORGANIZATION = "2";
String POSITION = "3"; // 岗位
}
public interface OrgTypeConstant {
String FIRST_LEVEL_DEPT = "1";
String SECOND_LEVEL_DEPT = "2";
}
@Override
public List<SysDepart> querySecondLevelDepts(Integer departType) {
return this.lambdaQuery()
// 2. 状态:建议直接使用常量
.eq(SysDepart::getDelFlag, CommonConstant.DEL_FLAG_0)
// 3. 核心条件
.eq(SysDepart::getDepartType, departType)
.eq(SysDepart::getOrgType,OrgTypeConstant.SECOND_LEVEL_DEPT)
// 4. 使用常量替代魔法数字,且保持类型一致(String)
.ne(SysDepart::getOrgCategory, OrgCategoryConstant.POSITION)
// 5. 排序(树形结构通常需要排序)
.orderByAsc(SysDepart::getDepartOrder)
.list();
}
@Override
public void deleteDepart(String id) {
//删除部门设置父级的叶子结点
@@ -0,0 +1,19 @@
package org.jeecg.modules.system.service.impl;
import org.jeecg.modules.system.entity.SysFileAttachment;
import org.jeecg.modules.system.mapper.SysFileAttachmentMapper;
import org.jeecg.modules.system.service.ISysFileAttachmentService;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
/**
* @Description: sys_file_attachment
* @Author: jeecg-boot
* @Date: 2026-03-26
* @Version: V1.0
*/
@Service
public class SysFileAttachmentServiceImpl extends ServiceImpl<SysFileAttachmentMapper, SysFileAttachment> implements ISysFileAttachmentService {
}
@@ -11,6 +11,7 @@ import org.jeecg.common.util.ImportExcelUtil;
import org.jeecg.modules.system.entity.SysRole;
import org.jeecg.modules.system.mapper.SysRoleMapper;
import org.jeecg.modules.system.mapper.SysUserMapper;
import org.jeecg.modules.system.mapper.SysUserRoleMapper;
import org.jeecg.modules.system.service.ISysRoleService;
import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.entity.ImportParams;
@@ -37,6 +38,8 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
SysRoleMapper sysRoleMapper;
@Autowired
SysUserMapper sysUserMapper;
@Autowired
SysUserRoleMapper sysUserRoleMapper;
@Override
@@ -89,6 +92,15 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
return true;
}
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean saveDeptForRoleUser(String userId,String roleId,String deptIds){
if(sysUserRoleMapper.saveDeptForRoleUser(userId,roleId,deptIds) != 0){
return true;
}
return false;
}
@Override
@Transactional(rollbackFor = Exception.class)
public boolean deleteBatchRole(String[] roleIds) {
@@ -2,6 +2,7 @@ package org.jeecg.modules.system.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
@@ -15,12 +16,14 @@ import org.jeecg.config.mybatis.MybatisPlusSaasConfig;
import org.jeecg.modules.system.entity.SysDepart;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.entity.SysUserDepart;
import org.jeecg.modules.system.entity.SysUserRole;
import org.jeecg.modules.system.mapper.SysUserDepartMapper;
import org.jeecg.modules.system.mapper.SysUserMapper;
import org.jeecg.modules.system.mapper.SysUserTenantMapper;
import org.jeecg.modules.system.model.DepartIdModel;
import org.jeecg.modules.system.service.ISysDepartService;
import org.jeecg.modules.system.service.ISysUserDepartService;
import org.jeecg.modules.system.service.ISysUserRoleService;
import org.jeecg.modules.system.service.ISysUserService;
import org.jeecg.modules.system.vo.SysUserDepVo;
import org.springframework.beans.factory.annotation.Autowired;
@@ -48,8 +51,10 @@ public class SysUserDepartServiceImpl extends ServiceImpl<SysUserDepartMapper, S
private SysUserMapper sysUserMapper;
@Autowired
private SysUserTenantMapper userTenantMapper;
@Autowired
private ISysUserRoleService sysUserRoleService;
@Autowired
private SysUserDepartMapper sysUserDepartMapper;
/**
* 根据用户id查询部门信息
*/
@@ -152,7 +157,7 @@ public class SysUserDepartServiceImpl extends ServiceImpl<SysUserDepartMapper, S
* @return
*/
@Override
public IPage<SysUser> queryDepartUserPageList(String departId, String username, String realname, int pageSize, int pageNo,String id,String isMultiTranslate) {
public IPage<SysUser> queryDepartUserPageList(String departId, String username, String realname, int pageSize, int pageNo,String id,Integer searchSecurityLevel,String isMultiTranslate) {
IPage<SysUser> pageList = null;
// 部门ID不存在 直接查询用户表即可
Page<SysUser> page = new Page<SysUser>(pageNo, pageSize);
@@ -225,6 +230,139 @@ public class SysUserDepartServiceImpl extends ServiceImpl<SysUserDepartMapper, S
}
pageList.setRecords(new ArrayList<SysUser>(map.values()));
}
if (Objects.nonNull(searchSecurityLevel)) {
// 筛选保留用户密级 >= 搜索密级的记录
List<SysUser> filteredUsers = pageList.getRecords().stream()
.filter(user -> {
Integer userLevel = user.getUserSecurityLevel();
// 注意这里的括号闭合})
return userLevel != null && userLevel >= searchSecurityLevel;
}) // 这里之前多了一个点且少了一个反括号
.collect(Collectors.toList());
// 重新设置到分页对象
pageList.setRecords(filteredUsers);
}
return pageList;
}
/**
*
* @param departId
* @param roleId
* @param username
* @param realname
* @param pageSize
* @param pageNo
* @param id
* @param isMultiTranslate 是否多字段翻译
* @return
*/
@Override
public IPage<SysUser> queryDepartRoleUserPageList(String departId, String roleId, String username, String realname, int pageSize, int pageNo,String id,Integer searchSecurityLevel,String isMultiTranslate) {
IPage<SysUser> pageList = null;
// 部门ID不存在 直接查询用户表即可
Page<SysUser> page = new Page<SysUser>(pageNo, pageSize);
if(oConvertUtils.isEmpty(departId)){
LambdaQueryWrapper<SysUser> query = new LambdaQueryWrapper<>();
//update-begin---author:wangshuai ---date:20220104 for[JTC-297]已冻结用户仍可设置为代理人------------
query.eq(SysUser::getStatus,Integer.parseInt(CommonConstant.STATUS_1));
//update-end---author:wangshuai ---date:20220104 for[JTC-297]已冻结用户仍可设置为代理人------------
//update-begin---author:liusq ---date:20231215 for逗号分割多个用户翻译问题------------
if(oConvertUtils.isNotEmpty(username)){
String COMMA = ",";
if(oConvertUtils.isNotEmpty(isMultiTranslate) && username.contains(COMMA)){
String[] usernameArr = username.split(COMMA);
query.in(SysUser::getUsername,usernameArr);
}else {
query.like(SysUser::getUsername, username);
}
}
//update-end---author:liusq ---date:20231215 for逗号分割多个用户翻译问题------------
//update-begin---author:wangshuai ---date:20220608 for[VUEN-1238]邮箱回复时发送到显示的为用户id------------
if(oConvertUtils.isNotEmpty(id)){
//update-begin---author:wangshuai ---date:2024-06-25 forTV360X-1482写信选择用户后第一次回显没翻译------------
String COMMA = ",";
if(oConvertUtils.isNotEmpty(isMultiTranslate) && id.contains(COMMA)){
String[] idArr = id.split(COMMA);
query.in(SysUser::getId, Arrays.asList(idArr));
}else {
query.eq(SysUser::getId, id);
}
//update-end---author:wangshuai ---date:2024-06-25 forTV360X-1482写信选择用户后第一次回显没翻译------------
}
//update-end---author:wangshuai ---date:20220608 for[VUEN-1238]邮箱回复时发送到显示的为用户id------------
//update-begin---author:wangshuai ---date:20220902 for[VUEN-2121]临时用户不能直接显示------------
query.ne(SysUser::getUsername,"_reserve_user_external");
//update-end---author:wangshuai ---date:20220902 for[VUEN-2121]临时用户不能直接显示------------
//------------------------------------------------------------------------------------------------
//是否开启系统管理模块的多租户数据隔离SAAS多租户模式
if (MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL) {
String tenantId = oConvertUtils.getString(TenantContext.getTenant(), "0");
//update-begin---author:wangshuai ---date:20221223 for[QQYUN-3371]租户逻辑改造改成关系表------------
List<String> userIdList = userTenantMapper.getUserIdsByTenantId(Integer.valueOf(tenantId));
if(null!=userIdList && userIdList.size()>0){
query.in(SysUser::getId,userIdList);
}
//update-end---author:wangshuai ---date:20221223 for[QQYUN-3371]租户逻辑改造改成关系表------------
}
//------------------------------------------------------------------------------------------------
pageList = sysUserMapper.selectPage(page, query);
}else{
// 有部门ID 需要走自定义sql
SysDepart sysDepart = sysDepartService.getById(departId);
pageList = sysUserDepartMapper.queryOneDepartUserPageList(page, sysDepart.getOrgCode(), username, realname);
}
List<SysUser> userList = pageList.getRecords();
if(userList!=null && userList.size()>0){
List<String> userIds = userList.stream().map(SysUser::getId).collect(Collectors.toList());
Map<String, SysUser> map = new HashMap(5);
if(userIds!=null && userIds.size()>0){
// 查部门名称
Map<String,String> useDepNames = this.getDepNamesByUserIds(userIds);
userList.forEach(item->{
//TODO 临时借用这个字段用于页面展示
item.setOrgCodeTxt(useDepNames.get(item.getId()));
item.setSalt("");
item.setPassword("");
// 去重
map.put(item.getId(), item);
});
}
pageList.setRecords(new ArrayList<SysUser>(map.values()));
}
if (Objects.nonNull(searchSecurityLevel)) {
// 筛选保留用户密级 >= 搜索密级的记录
List<SysUser> filteredUsers = pageList.getRecords().stream()
.filter(user -> {
Integer userLevel = user.getUserSecurityLevel();
// 注意这里的括号闭合})
return userLevel != null && userLevel >= searchSecurityLevel;
}) // 这里之前多了一个点且少了一个反括号
.collect(Collectors.toList());
// 重新设置到分页对象
pageList.setRecords(filteredUsers);
}
if (Objects.nonNull(roleId)) {
Set<String> userIdSet = sysUserRoleService.listObjs(
Wrappers.lambdaQuery(SysUserRole.class)
.select(SysUserRole::getUserId)
.eq(SysUserRole::getRoleId, roleId),
String::valueOf
).stream().collect(Collectors.toSet());
List<SysUser> filteredUsers = pageList.getRecords().stream()
.filter(user -> {
String userId = user.getId();
// 注意这里的括号闭合})
return userIdSet.contains(userId);
})
.collect(Collectors.toList());
pageList.setRecords(filteredUsers);
}
return pageList;
}
@@ -266,6 +404,8 @@ public class SysUserDepartServiceImpl extends ServiceImpl<SysUserDepartMapper, S
return pageList;
}
@Override
public IPage<SysUser> getUserInformation(Integer tenantId, String departId,String roleId, String keyword, Integer pageSize, Integer pageNo, String excludeUserIdList) {
IPage<SysUser> pageList = null;
@@ -42,10 +42,7 @@ import org.jeecg.modules.system.entity.*;
import org.jeecg.modules.system.mapper.*;
import org.jeecg.modules.system.model.SysUserSysDepartModel;
import org.jeecg.modules.system.service.*;
import org.jeecg.modules.system.vo.SysUserDepVo;
import org.jeecg.modules.system.vo.SysUserExportVo;
import org.jeecg.modules.system.vo.SysUserPositionVo;
import org.jeecg.modules.system.vo.UserAvatar;
import org.jeecg.modules.system.vo.*;
import org.jeecg.modules.system.vo.lowapp.AppExportUserVo;
import org.jeecg.modules.system.vo.lowapp.DepartAndUserInfo;
import org.jeecg.modules.system.vo.lowapp.DepartInfo;
@@ -70,6 +67,7 @@ import org.springframework.web.servlet.ModelAndView;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotBlank;
import java.io.IOException;
import java.lang.reflect.Array;
import java.util.*;
@@ -135,6 +133,8 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
@Autowired
private RedisUtil redisUtil;
@Autowired
private SysUserMapper sysUserMapper;
@Override
public Result<IPage<SysUser>> queryPageList(HttpServletRequest req, QueryWrapper<SysUser> queryWrapper, Integer pageSize, Integer pageNo) {
@@ -170,6 +170,14 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
}
//update-end-author:taoyan--date:20220104--for: JTC-372 用户冻结问题 online授权用户组件选择用户都能看到被冻结的用户
// 假设前端传的参数名也是 userSecurityLevel
String securityLevel = req.getParameter("searchSecurityLevel");
if (oConvertUtils.isNotEmpty(securityLevel)) {
int levelInt = Integer.parseInt(securityLevel);
// 将条件加入 queryWrapper对应数据库字段名为 user_security_level
queryWrapper.ge("user_security_level", levelInt);
}
//update-begin---author:wangshuai---date:2024-03-08---for:QQYUN-8110在线通讯录支持设置权限(只能看分配的技术支持)---
String tenantId = TokenUtils.getTenantIdByRequest(req);
String lowAppId = TokenUtils.getLowAppIdByRequest(req);
@@ -576,6 +584,18 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
//update-end---author:wangshuai ---date:20230220 for[QQYUN-3980]组织管理中 职位功能 职位表加租户id 加职位-用户关联表------------
}
/**
* 根据角色Id查询
* @param page
* @param roleId 角色id
* @param username 用户账户名称
* @return
*/
@Override
public IPage<SysUserRoleDeptsVo> getUserByRoleIdWithDeptIds(Page<SysUserRoleDeptsVo> page, String roleId, String username){
//update-begin---author:wangshuai ---date:20230220 for[QQYUN-3980]组织管理中 职位功能 职位表加租户id 加职位-用户关联表------------
return userMapper.getUserByRoleIdWithDeptIds(page, roleId, username);
}
@Override
@CacheEvict(value= {CacheConstant.SYS_USERS_CACHE}, key="#username")
@@ -2394,4 +2414,9 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
String newPassWord = PasswordUtil.encrypt(username, password, user.getSalt());
this.userMapper.update(new SysUser().setPassword(newPassWord), new LambdaQueryWrapper<SysUser>().eq(SysUser::getId, user.getId()));
}
@Override
public List<SysUser> queryUserByDeptAndROle(@NotBlank(message = "deptId不为空") String deptId, @NotBlank(message = "角色id不为空") String roleId, @NotBlank(message = "secretLevel不为空") Integer secretLevel){
return sysUserMapper.queryUserByDeptAndROle(deptId,roleId,secretLevel);
}
}
@@ -0,0 +1,20 @@
package org.jeecg.modules.system.vo;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.jeecg.common.aspect.annotation.Dict;
import org.jeecg.modules.system.entity.SysUser;
@Data
@EqualsAndHashCode(callSuper = true) // hash值比较需考虑父值相等
@Accessors(chain = true) // 开启链式调用
public class SysUserRoleDeptsVo extends SysUser {
/** 部门ID(来自中间表) */
private String deptId;
/** 用户ID */
private String userId;
}