Browse Source

代码提交

zhuwei 2 years ago
parent
commit
5f9342b06c
23 changed files with 723 additions and 666 deletions
  1. 9 5
      blade-auth/src/main/java/org/springblade/auth/service/BladeUserDetailsServiceImpl.java
  2. 1 1
      blade-common/src/main/java/org/springblade/common/constant/LauncherConstant.java
  3. 1 1
      blade-common/src/main/java/org/springblade/common/utils/AsyncConfigurer.java
  4. 530 529
      blade-ops/blade-resource/src/main/java/org/springblade/resource/endpoint/LargeFileEndpoint.java
  5. 13 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/ProjectInfo.java
  6. 6 0
      blade-service-api/blade-system-api/src/main/java/org/springblade/system/vo/CheckedTreeVO.java
  7. 6 0
      blade-service-api/blade-system-api/src/main/java/org/springblade/system/vo/GrantTreeVO.java
  8. 6 0
      blade-service-api/blade-system-api/src/main/java/org/springblade/system/vo/GrantVO.java
  9. 0 1
      blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchiveExaminingReportController.java
  10. 28 4
      blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchivesAutoController.java
  11. 42 102
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TaskServiceImpl.java
  12. 4 1
      blade-service/blade-control/src/main/java/org/springblade/control/mapper/DictInfoMapper.xml
  13. 0 8
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExcelTabController.java
  14. 2 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ProjectInfoMapper.java
  15. 15 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ProjectInfoMapper.xml
  16. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreePrivateMapper.xml
  17. 3 3
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ExcelTabServiceImpl.java
  18. 8 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeServiceImpl.java
  19. 22 0
      blade-service/blade-system/src/main/java/org/springblade/system/controller/MenuController.java
  20. 1 1
      blade-service/blade-system/src/main/java/org/springblade/system/controller/RoleController.java
  21. 1 2
      blade-service/blade-system/src/main/java/org/springblade/system/mapper/MenuMapper.xml
  22. 1 1
      blade-service/blade-system/src/main/java/org/springblade/system/service/IRoleService.java
  23. 23 4
      blade-service/blade-system/src/main/java/org/springblade/system/service/impl/RoleServiceImpl.java

+ 9 - 5
blade-auth/src/main/java/org/springblade/auth/service/BladeUserDetailsServiceImpl.java

@@ -245,19 +245,22 @@ public class BladeUserDetailsServiceImpl implements UserDetailsService {
         if (clientId != null) {
             switch (clientId) {
                 case "client":
-                    result = "1"; //WEB=客户端
+                    result = "1"; //WEB = 客户端
                     break;
                 case "uni-app":
-                    result = "2"; //APP=APP端
+                    result = "2"; //APP = APP端
                     break;
                 case "archives":
-                    result = "3"; //archives=档案
+                    result = "3"; //archives = 档案
                     break;
                 case "saber":
-                    result = "4"; //manger=后管
+                    result = "4"; //manger = 后管
                     break;
                 case "hac":
-                    result = "5"; //hac=成本管控系统
+                    result = "5"; //hac = 成本管控系统
+                    break;
+                case "lar":
+                    result = "6"; //lar = 征拆系统
                     break;
             }
         }
@@ -267,6 +270,7 @@ public class BladeUserDetailsServiceImpl implements UserDetailsService {
                 || (("3").equals(result) && user.getUserType().contains("3")) //档案
                 || (("4").equals(result) && user.getUserType().contains("4")) //后管
                 || (("5").equals(result)) // 成本管控系统
+                || (("6").equals(result)) // 征拆系统
         ) {
             //放行
             return;

+ 1 - 1
blade-common/src/main/java/org/springblade/common/constant/LauncherConstant.java

@@ -46,7 +46,7 @@ public interface LauncherConstant {
     String APPLICATION_XXLJOB_ADMIN_NAME = APPLICATION_NAME_PREFIX + "xxljob-admin";
 
     /**
-     * nacos dev 地址 172.31.222.127   127.0.0.107
+     * nacos dev 地址 172.31.222.127   192.168.0.109 127.0.0.1
      */
     String NACOS_DEV_ADDR = "127.0.0.1:8848";
 

+ 1 - 1
blade-common/src/main/java/org/springblade/common/utils/AsyncConfigurer.java

@@ -15,7 +15,7 @@ public class AsyncConfigurer {
     /**
      * cpu 核心数量
      */
-    public static final int cpuNum = 1;//Runtime.getRuntime().availableProcessors();
+    public static final int cpuNum = 4;//Runtime.getRuntime().availableProcessors();
 
     /**
      * 线程池配置

+ 530 - 529
blade-ops/blade-resource/src/main/java/org/springblade/resource/endpoint/LargeFileEndpoint.java

@@ -27,6 +27,7 @@ import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.pdfbox.pdmodel.PDDocument;
 import org.springblade.common.constant.CommonConstant;
+import org.springblade.common.utils.SystemUtils;
 import org.springblade.core.cache.utils.CacheUtil;
 import org.springblade.core.oss.model.BladeFile;
 import org.springblade.core.secure.annotation.PreAuth;
@@ -72,539 +73,539 @@ import java.util.concurrent.locks.ReentrantLock;
 @Api(value = "大文件存储端点", tags = "大文件存储端点")
 public class LargeFileEndpoint {
 
-	/**
-	 * 对象存储构建类
-	 */
-	private final OssBuilder ossBuilder;
-
-	private final ILargeFileService iLargeFileService;
-
-	private final Lock lock = new ReentrantLock();
-
-	private final CommonFileClient commonFileClient;
-
-	@Autowired
-	StringRedisTemplate RedisTemplate;
-
-	private final String bucketName = "bladex-chongqing-info";
-
-	private final String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
-
-	/**
-	 * 创建存储桶
-	 *
-	 * @param bucketName 存储桶名称
-	 * @return Bucket
-	 */
-	@SneakyThrows
-	@PostMapping("/make-bucket")
-	@PreAuth(RoleConstant.HAS_ROLE_ADMIN)
-	public R makeBucket(@RequestParam String bucketName) {
-		ossBuilder.template().makeBucket(bucketName);
-		return R.success("创建成功");
-	}
-
-	/**
-	 * 创建存储桶
-	 *
-	 * @param bucketName 存储桶名称
-	 * @return R
-	 */
-	@SneakyThrows
-	@PostMapping("/remove-bucket")
-	@PreAuth(RoleConstant.HAS_ROLE_ADMIN)
-	public R removeBucket(@RequestParam String bucketName) {
-		ossBuilder.template().removeBucket(bucketName);
-		return R.success("删除成功");
-	}
-
-
-	/**
-	 * @return
-	 * @throws Exception
-	 **/
-	@SneakyThrows
-	@PostMapping("/upload-file1234")
-	public R uploadByfile123(@RequestParam(value = "file", required = false) MultipartFile file,
-							 @RequestParam(value = "identifier", required = false) String identifier,
-							 @RequestParam(value = "chunkNumber", required = false) Integer chunkNumber,
-							 @RequestParam(value = "chunkSize", required = false) Integer chunkSize,
-							 @RequestParam(value = "currentChunkSize", required = false) String currentChunkSize,
-							 @RequestParam(value = "filename", required = false) String filename,
-							 @RequestParam(value = "relativePath", required = false) String relativePath,
-							 @RequestParam(value = "totalChunks", required = false) Integer totalChunks,
-							 @RequestParam(value = "totalSize", required = false) String totalSize,
-							 @RequestParam(value = "objectType", required = false) String objectType) {
-
-		// 文件上传
-		String taskKey = "upload/20221220/" + filename;
-		UmsAdminLoginLogDO param = new UmsAdminLoginLogDO();
-		if (file == null && totalChunks >= 0 && StringUtils.isNotEmpty(identifier)) {
-			// 请求阿里云oss获取分片唯一ID
-			String ossSlicesId = this.getUploadId(taskKey);
-			RedisTemplate.opsForValue().set(identifier, ossSlicesId);
-			return R.fail("没有文件");
-		}
-
-		String uploadId = RedisTemplate.opsForValue().get(identifier);
-
-		UmsAdminLoginLogDO redisParam = (UmsAdminLoginLogDO) CacheUtil.get("oss", "PartETag", uploadId);
-		if (redisParam != null) {
-			param.setPartETags(redisParam.getPartETags());
-		}
-
-		Map<Integer, PartETag> partETags = param.getPartETags();
-
-		UploadPartRequest request = new UploadPartRequest();
-		request.setInputStream(file.getInputStream());
-		request.setBucketName(bucketName);
-		request.setPartNumber(chunkNumber);
-		request.setPartSize(Long.parseLong(currentChunkSize));
-		request.setKey(filename);
-		request.setMd5Digest(identifier);
-		request.setUploadId(uploadId);
-
-		try {
-			UploadPartResult uploadPartResult = ossBuilder.template().uploadPart(request);
-			PartETag partETag = uploadPartResult.getPartETag();
-			partETags.put(chunkNumber, partETag);
-			//分片编号等于总片数的时候合并文件,如果符合条件则合并文件,否则继续等待
-			if (chunkNumber == totalChunks) {
-				//合并文件,注意:partETags必须是所有分片的所以必须存入redis,然后取出放入集合
-				String url = this.completePartUploadFile(filename, uploadId,
-						new ArrayList<>(partETags.values()));
-				//oss地址返回后存入并清除redis
-				RedisTemplate.delete(uploadId);
-				return R.data(url);
-			} else {
-				RedisTemplate.opsForHash().putAll(uploadId, partETags);
-				CacheUtil.put("oss", "PartETag", uploadId, param);
-			}
-		} catch (Exception e) {
-			e.printStackTrace();
-		}
-
-		return R.data("");
-	}
-
-	/**
-	 * 分块上传完成获取结果
-	 */
-	public String completePartUploadFile(String fileKey, String uploadId, List<PartETag> partETags) {
-		CompleteMultipartUploadRequest request = new CompleteMultipartUploadRequest(bucketName, fileKey, uploadId,
-				partETags);
-		ossBuilder.template().completeMultipartUpload(request);
-		String downLoadUrl = getDownloadUrl(fileKey, bucketName);
-		return downLoadUrl;
-	}
-
-	/**
-	 * 获取bucket文件的下载链接
-	 *
-	 * @param pathFile   首字母不带/的路径和文件
-	 * @param bucketName
-	 * @return 上报返回null, 成功返回地址
-	 */
-	public String getDownloadUrl(String pathFile, String bucketName) {
-		if (bucketName == null || "".equals(bucketName)) {
-			bucketName = bucketName;
-		}
-		StringBuffer url = new StringBuffer();
-		url.append("http://").append(bucketName).append(endpoint).append("/");
-		if (pathFile != null && !"".equals(pathFile)) {
-			url.append(pathFile);
-		}
-		return url.toString();
-	}
-
-	public String getUploadId(String fileKey) {
-		InitiateMultipartUploadRequest request = new InitiateMultipartUploadRequest(bucketName, fileKey);
-		// 初始化分片
-		InitiateMultipartUploadResult unrest = ossBuilder.template().initiateMultipartUpload(request);
-		// 返回uploadId,它是分片上传事件的唯一标识,您可以根据这个ID来发起相关的操作,如取消分片上传、查询分片上传等。
-		String uploadId = unrest.getUploadId();
-		return uploadId;
-	}
-
-	/**
-	 * @return
-	 * @throws Exception
-	 **/
-	@SneakyThrows
-	@PostMapping("/upload-file")
-	public R uploadByfile(@RequestParam(value = "file", required = false) MultipartFile file,
-						  @RequestParam(value = "identifier", required = false) String identifier,
-						  @RequestParam(value = "chunkNumber", required = false) Integer chunkNumber,
-						  @RequestParam(value = "chunkSize", required = false) Integer chunkSize,
-						  @RequestParam(value = "currentChunkSize", required = false) String currentChunkSize,
-						  @RequestParam(value = "filename", required = false) String filename,
-						  @RequestParam(value = "relativePath", required = false) String relativePath,
-						  @RequestParam(value = "totalChunks", required = false) Integer totalChunks,
-						  @RequestParam(value = "totalSize", required = false) String totalSize,
-						  @RequestParam(value = "objectType", required = false) String objectType) throws Exception {
-		R result = new R();
-		// 判断是否上传
-		if (file == null) {
-			result.setSuccess(false);
-			result.setMsg("没有文件!");
-			return result;
-		}
-		MultipartFileParam param = new MultipartFileParam();
-		param.setFile(file);
-		param.setIdentifier(identifier);
-		param.setChunkNumber(chunkNumber);
-		param.setChunkSize(chunkSize);
-		param.setCurrentChunkSize(currentChunkSize);
-		param.setFilename(filename);
-		param.setRelativePath(relativePath);
-		param.setTotalChunks(totalChunks);
-		param.setTotalSize(totalSize);
-		param.setObjectType(objectType);
-		return uploadByMappedByteBuffer(param);
-	}
-
-	/**
-	 * 分块上传
-	 * 第一步:获取RandomAccessFile,随机访问文件类的对象
-	 * 第二步:调用RandomAccessFile的getChannel()方法,打开文件通道 FileChannel
-	 * 第三步:获取当前是第几个分块,计算文件的最后偏移量
-	 * 第四步:获取当前文件分块的字节数组,用于获取文件字节长度
-	 * 第五步:使用文件通道FileChannel类的 map()方法创建直接字节缓冲器  MappedByteBuffer
-	 * 第六步:将分块的字节数组放入到当前位置的缓冲区内  mappedByteBuffer.put(byte[] b);
-	 * 第七步:释放缓冲区
-	 * 第八步:检查文件是否全部完成上传
-	 */
-
-	public R uploadByMappedByteBuffer(MultipartFileParam param) throws Exception {
-		R result = new R();
-		if (param.getIdentifier() == null || "".equals(param.getIdentifier())) {
-			return result;
-		}
-		// 判断是否上传
-		if (param.getFile() == null) {
-			result.setSuccess(false);
-			result.setMsg("没有文件!");
-			return result;
-		}
-		if (checkMd5(param.getFile().getInputStream(), param.getIdentifier())) {
-			result.setSuccess(false);
-			result.setMsg("文件的Identifier对不上!");
-			return result;
-		}
-		/**
-		 * 查询是否已经上传该分片
-		 * **/
-		QueryWrapper<LargeFile> wrapper = new QueryWrapper<LargeFile>()
-				.eq("file_key", param.getIdentifier()).eq("is_deleted", 0).eq("shard_index", param.getChunkNumber()).orderByDesc("shard_index");
-		LargeFile list = iLargeFileService.getOne(wrapper);
-		int state = 0;
-
-		if (list != null) {
-			if (StringUtils.isNotEmpty(list.getPath())) {
-				File chfile = new File(list.getPath());
-				if (chfile.exists()) {
-					result.setSuccess(true);
-					result.setMsg("该分片已上传!");
-					result.setData(list.getShardIndex());
-					result.setCode(200);
-					return result;
-				} else {
-					iLargeFileService.remove(wrapper);
-				}
-			}
-		}
-
-
-		// 文件名称
-		String fileName = getFileName(param);
-		// 临时文件名称
-		String tempFileName = param.getIdentifier() + fileName.substring(fileName.lastIndexOf(".")) + "." + param.getChunkNumber();
-		// 获取文件路径
-		/**Windows文件路径要加在哪个盘**/
-		String filePath = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL) + "largeFile/";
-		//String filePath ="/Users/hongchuangyanfa/Desktop/largeFile/";
-
-		File tempFile = buildUploadFile(tempFileName);
-
-		//为了防止win路径有时会抛异常,增加一个处理
-		try {
-			param.getFile().transferTo(tempFile);
-		} catch (Exception e) {
-			writeMultipartFileToFile(param, tempFile);
-		}
-
-
-		/**
-		 * 以上意思是把每个分片都保存成本地一个文件,如 测试.mp4.1 最后合并
-		 * ===================================================
-		 * 以下注释是把分片存到一个文件,持续写入,感觉不太保险**/
-
-		LargeFile largeFile = new LargeFile();
-		largeFile.setFileKey(param.getIdentifier());
-		largeFile.setName(tempFileName);
-		largeFile.setPath(filePath + fileName);
-		largeFile.setShardIndex(param.getChunkNumber());
-		largeFile.setShardSize(param.getChunkSize());
-		largeFile.setSize(Integer.valueOf(param.getCurrentChunkSize()));
-		largeFile.setShardTotal(param.getTotalChunks());
-		largeFile.setSuffix(param.getObjectType());
-		iLargeFileService.save(largeFile);
-
-		if ((param.getTotalChunks() + "").equals(param.getChunkNumber() + "")) {
-			Thread.sleep(1000);
-			//第八步 检查文件是否全部完成上传
-			lock.lock();
-			try {
-				// 检测是否为最后一块分片
-				QueryWrapper<LargeFile> wrapper1 = new QueryWrapper<LargeFile>()
-						.eq("file_key", param.getIdentifier()).eq("is_deleted", 0);
-
-				Integer count = Math.toIntExact(iLargeFileService.count(wrapper1));
-				if (count.equals(param.getTotalChunks())) {
-					/**每个文件保存到本地所使用的合并各个文件**/
-					merge(largeFile, filePath);
-					String path = largeFile.getPath(); //获取到的路径 没有.1 .2 这样的东西
-
-					//截取视频所在的路径
-					path = path.replace(filePath, "");
-					File file = new File(filePath + path);
-					//修改成原来的文件名
-					renameFile(file, param.getFilename());
-					FileInputStream inputStream = new FileInputStream(filePath + param.getFilename());
-//				上传oss
-					long l = System.currentTimeMillis();
-					System.out.println("kaishi====================================" + l);
-					BladeFile bladeFile = ossBuilder.template().putFile(param.getFilename(), inputStream);
-					System.out.println("param.getFilename()====================================" + param.getFilename());
-					System.out.println("bladeFile====================================" + bladeFile.getOriginalName());
-					long l1 = System.currentTimeMillis();
-					System.out.println("jieshu====================================" + (l1 - l));
-
-					File file1 = new File(filePath + param.getFilename());
-					MultipartFile multipartFile = getMultipartFile(file1);
-					NewBladeFile newBladeFile = new NewBladeFile();
-					if (param.getFilename().contains("pdf")) {
-//					FileInputStream inputStream1 = new FileInputStream(filePath + param.getFilename());
-						try {
-							//PDDocument document = PDDocument.load(multipartFile.getInputStream());
-							PdfReader pdfReader = new PdfReader(multipartFile.getInputStream());
-							int pages = pdfReader.getNumberOfPages();
-							//获取文件页数
-							newBladeFile.setPage(pages);
-						} catch (IOException e) {
-							e.printStackTrace();
-						}
-						//pdf的路径就是文件上传的路径
-						newBladeFile.setPdfUrl(bladeFile.getLink());
-					} else if (param.getFilename().contains("xlsx") || param.getFilename().contains("xls")) {
-						newBladeFile = this.commonFileClient.excelToPdf(multipartFile);
-					} else if (param.getFilename().contains("docx")) {
-						newBladeFile = this.commonFileClient.wordToPdf(multipartFile);
-					} else if (param.getFilename().contains("png") || param.getFilename().contains("jpg")) {
-
-						newBladeFile = this.commonFileClient.pngOrJpgToPdf(multipartFile);
-					}
-					BeanUtils.copyProperties(bladeFile, newBladeFile);
-					newBladeFile.setFileSize(multipartFile.getSize() / 1024);
-					//删除本地文件
-					file1.delete();
-					iLargeFileService.updateLargeFileDeleted(param.getIdentifier());
-					result.setSuccess(true);
-					result.setMsg("上传成功!");
-					result.setData(newBladeFile);
-					result.setCode(200);
-					return result;
-				}
-			} catch (FileNotFoundException e) {
-				e.printStackTrace();
-			} catch (InterruptedException e) {
-				e.printStackTrace();
-			} finally {
-				lock.unlock();
-			}
-		}
-		result.setCode(200);
-		result.setSuccess(true);
-		result.setMsg("上传成功!");
-		result.setData(largeFile.getShardIndex());
-		return result;
-	}
-
-	public void writeMultipartFileToFile(MultipartFileParam param, File tempFile) throws IOException {
-		byte[] data = param.getFile().getBytes(); // 获取二进制数据
-		FileOutputStream outputStream = new FileOutputStream(tempFile);
-		try {
-			outputStream.write(data); // 将二进制数据写入到文件中
-		} finally {
-			outputStream.close(); // 关闭输出流
-		}
-	}
-
-	/**
-	 * file 转 MultipartFile
-	 **/
-	public static MultipartFile getMultipartFile(File file) {
-		DiskFileItem item = new DiskFileItem("file",
-				MediaType.MULTIPART_FORM_DATA_VALUE,
-				true,
-				file.getName(), (int) file.length(), file.getParentFile());
-		try {
-			OutputStream os = item.getOutputStream();
-			os.write(FileUtils.readFileToByteArray(file));
-		} catch (IOException e) {
-			e.printStackTrace();
-		}
-		return new CommonsMultipartFile(item);
-	}
-
-	/**
-	 * 构建上传目录和文件
-	 */
-	private File buildUploadFile(String name) {
-		String fileName = name;
-		String fullDir = buildUploadDir();
-		return new File(fullDir, fileName);
-	}
-
-	/**
-	 * 构建上传完整目录
-	 */
-	private String buildUploadDir() {
-		String fullDir = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL) + "largeFile/";
-		//String fullDir ="/Users/hongchuangyanfa/Desktop/largeFile/";
-		File dir = new File(fullDir);
-		if (!dir.exists()) {
-			dir.mkdirs();
-		}
-		return fullDir;
-	}
-
-	/**
-	 * md5校验
-	 */
-	private boolean checkMd5(InputStream is, String md5) {
-		String check = "";
-		try {
-			check = DigestUtils.md5DigestAsHex(is);
-		} catch (IOException e) {
-			e.printStackTrace();
-		}
-		if (!check.equalsIgnoreCase(md5)) {
-			return false;
-		}
-		return true;
-	}
-
-	/**
-	 * @author fengxinglie
-	 * 合并分页
-	 */
-	private void merge(LargeFile largeFile, String basePath) throws FileNotFoundException, InterruptedException {
-		//合并分片开始
-		String path = largeFile.getPath(); //获取到的路径 没有.1 .2 这样的东西
-		//截取视频所在的路径
-		path = path.replace(basePath, "");
-		Integer shardTotal = largeFile.getShardTotal();
-		File newFile = new File(basePath + path);
-		FileOutputStream outputStream = new FileOutputStream(newFile, true); // 文件追加写入
-		FileInputStream fileInputStream = null; //分片文件
-		byte[] byt = new byte[10 * 1024 * 1024];
-		int len;
-		try {
-			for (int i = 0; i < shardTotal; i++) {
-				// 读取第i个分片
-				fileInputStream = new FileInputStream(new File(basePath + path + "." + (i + 1))); // course\6sfSqfOwzmik4A4icMYuUe.mp4.1
-				while ((len = fileInputStream.read(byt)) != -1) {
-					outputStream.write(byt, 0, len);
-				}
-			}
-		} catch (IOException e) {
-		} finally {
-			try {
-				if (fileInputStream != null) {
-					fileInputStream.close();
-				}
-				outputStream.close();
-			} catch (Exception e) {
+    /**
+     * 对象存储构建类
+     */
+    private final OssBuilder ossBuilder;
+
+    private final ILargeFileService iLargeFileService;
+
+    private final Lock lock = new ReentrantLock();
+
+    private final CommonFileClient commonFileClient;
+
+    @Autowired
+    StringRedisTemplate RedisTemplate;
+
+    private final String bucketName = "bladex-chongqing-info";
+
+    private final String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
+
+    /**
+     * 创建存储桶
+     *
+     * @param bucketName 存储桶名称
+     * @return Bucket
+     */
+    @SneakyThrows
+    @PostMapping("/make-bucket")
+    @PreAuth(RoleConstant.HAS_ROLE_ADMIN)
+    public R makeBucket(@RequestParam String bucketName) {
+        ossBuilder.template().makeBucket(bucketName);
+        return R.success("创建成功");
+    }
+
+    /**
+     * 创建存储桶
+     *
+     * @param bucketName 存储桶名称
+     * @return R
+     */
+    @SneakyThrows
+    @PostMapping("/remove-bucket")
+    @PreAuth(RoleConstant.HAS_ROLE_ADMIN)
+    public R removeBucket(@RequestParam String bucketName) {
+        ossBuilder.template().removeBucket(bucketName);
+        return R.success("删除成功");
+    }
+
+
+    /**
+     * @return
+     * @throws Exception
+     **/
+    @SneakyThrows
+    @PostMapping("/upload-file1234")
+    public R uploadByfile123(@RequestParam(value = "file", required = false) MultipartFile file,
+                             @RequestParam(value = "identifier", required = false) String identifier,
+                             @RequestParam(value = "chunkNumber", required = false) Integer chunkNumber,
+                             @RequestParam(value = "chunkSize", required = false) Integer chunkSize,
+                             @RequestParam(value = "currentChunkSize", required = false) String currentChunkSize,
+                             @RequestParam(value = "filename", required = false) String filename,
+                             @RequestParam(value = "relativePath", required = false) String relativePath,
+                             @RequestParam(value = "totalChunks", required = false) Integer totalChunks,
+                             @RequestParam(value = "totalSize", required = false) String totalSize,
+                             @RequestParam(value = "objectType", required = false) String objectType) {
+
+        // 文件上传
+        String taskKey = "upload/20221220/" + filename;
+        UmsAdminLoginLogDO param = new UmsAdminLoginLogDO();
+        if (file == null && totalChunks >= 0 && StringUtils.isNotEmpty(identifier)) {
+            // 请求阿里云oss获取分片唯一ID
+            String ossSlicesId = this.getUploadId(taskKey);
+            RedisTemplate.opsForValue().set(identifier, ossSlicesId);
+            return R.fail("没有文件");
+        }
+
+        String uploadId = RedisTemplate.opsForValue().get(identifier);
+
+        UmsAdminLoginLogDO redisParam = (UmsAdminLoginLogDO) CacheUtil.get("oss", "PartETag", uploadId);
+        if (redisParam != null) {
+            param.setPartETags(redisParam.getPartETags());
+        }
+
+        Map<Integer, PartETag> partETags = param.getPartETags();
+
+        UploadPartRequest request = new UploadPartRequest();
+        request.setInputStream(file.getInputStream());
+        request.setBucketName(bucketName);
+        request.setPartNumber(chunkNumber);
+        request.setPartSize(Long.parseLong(currentChunkSize));
+        request.setKey(filename);
+        request.setMd5Digest(identifier);
+        request.setUploadId(uploadId);
+
+        try {
+            UploadPartResult uploadPartResult = ossBuilder.template().uploadPart(request);
+            PartETag partETag = uploadPartResult.getPartETag();
+            partETags.put(chunkNumber, partETag);
+            //分片编号等于总片数的时候合并文件,如果符合条件则合并文件,否则继续等待
+            if (chunkNumber == totalChunks) {
+                //合并文件,注意:partETags必须是所有分片的所以必须存入redis,然后取出放入集合
+                String url = this.completePartUploadFile(filename, uploadId,
+                        new ArrayList<>(partETags.values()));
+                //oss地址返回后存入并清除redis
+                RedisTemplate.delete(uploadId);
+                return R.data(url);
+            } else {
+                RedisTemplate.opsForHash().putAll(uploadId, partETags);
+                CacheUtil.put("oss", "PartETag", uploadId, param);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return R.data("");
+    }
+
+    /**
+     * 分块上传完成获取结果
+     */
+    public String completePartUploadFile(String fileKey, String uploadId, List<PartETag> partETags) {
+        CompleteMultipartUploadRequest request = new CompleteMultipartUploadRequest(bucketName, fileKey, uploadId,
+                partETags);
+        ossBuilder.template().completeMultipartUpload(request);
+        String downLoadUrl = getDownloadUrl(fileKey, bucketName);
+        return downLoadUrl;
+    }
+
+    /**
+     * 获取bucket文件的下载链接
+     *
+     * @param pathFile   首字母不带/的路径和文件
+     * @param bucketName
+     * @return 上报返回null, 成功返回地址
+     */
+    public String getDownloadUrl(String pathFile, String bucketName) {
+        if (bucketName == null || "".equals(bucketName)) {
+            bucketName = bucketName;
+        }
+        StringBuffer url = new StringBuffer();
+        url.append("http://").append(bucketName).append(endpoint).append("/");
+        if (pathFile != null && !"".equals(pathFile)) {
+            url.append(pathFile);
+        }
+        return url.toString();
+    }
+
+    public String getUploadId(String fileKey) {
+        InitiateMultipartUploadRequest request = new InitiateMultipartUploadRequest(bucketName, fileKey);
+        // 初始化分片
+        InitiateMultipartUploadResult unrest = ossBuilder.template().initiateMultipartUpload(request);
+        // 返回uploadId,它是分片上传事件的唯一标识,您可以根据这个ID来发起相关的操作,如取消分片上传、查询分片上传等。
+        String uploadId = unrest.getUploadId();
+        return uploadId;
+    }
+
+
+    /**
+     * @return
+     * @throws Exception-----------------------------------------------------------------------
+     **/
+    @SneakyThrows
+    @PostMapping("/upload-file")
+    public R uploadByfile(@RequestParam(value = "file", required = false) MultipartFile file,
+                          @RequestParam(value = "identifier", required = false) String identifier,
+                          @RequestParam(value = "chunkNumber", required = false) Integer chunkNumber,
+                          @RequestParam(value = "chunkSize", required = false) Integer chunkSize,
+                          @RequestParam(value = "currentChunkSize", required = false) String currentChunkSize,
+                          @RequestParam(value = "filename", required = false) String filename,
+                          @RequestParam(value = "relativePath", required = false) String relativePath,
+                          @RequestParam(value = "totalChunks", required = false) Integer totalChunks,
+                          @RequestParam(value = "totalSize", required = false) String totalSize,
+                          @RequestParam(value = "objectType", required = false) String objectType) throws Exception {
+        R result = new R();
+        // 判断是否上传
+        if (file == null) {
+            result.setSuccess(false);
+            result.setMsg("没有文件!");
+            return result;
+        }
+        MultipartFileParam param = new MultipartFileParam();
+        param.setFile(file);
+        param.setIdentifier(identifier);
+        param.setChunkNumber(chunkNumber);
+        param.setChunkSize(chunkSize);
+        param.setCurrentChunkSize(currentChunkSize);
+        param.setFilename(filename);
+        param.setRelativePath(relativePath);
+        param.setTotalChunks(totalChunks);
+        param.setTotalSize(totalSize);
+        param.setObjectType(objectType);
+        return uploadByMappedByteBuffer(param);
+    }
+
+    public static String getSysLocalFileUrl() {
+        String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
+        if (SystemUtils.isMacOs()) {
+            file_path = "/Users/hongchuangyanfa/Desktop/";
+        } else if (SystemUtils.isWindows()) {
+            file_path = "C://upload";
+        }
+        return file_path;
+    }
+
+    /**
+     * 分块上传
+     * 第一步:获取RandomAccessFile,随机访问文件类的对象
+     * 第二步:调用RandomAccessFile的getChannel()方法,打开文件通道 FileChannel
+     * 第三步:获取当前是第几个分块,计算文件的最后偏移量
+     * 第四步:获取当前文件分块的字节数组,用于获取文件字节长度
+     * 第五步:使用文件通道FileChannel类的 map()方法创建直接字节缓冲器  MappedByteBuffer
+     * 第六步:将分块的字节数组放入到当前位置的缓冲区内  mappedByteBuffer.put(byte[] b);
+     * 第七步:释放缓冲区
+     * 第八步:检查文件是否全部完成上传
+     */
+
+    public R uploadByMappedByteBuffer(MultipartFileParam param) throws Exception {
+        R result = new R();
+
+        // 首次
+        if (param.getIdentifier() == null || "".equals(param.getIdentifier())) {
+            return result;
+        }
+
+        // 判断是否上传
+        if (param.getFile() == null) {
+            result.setSuccess(false);
+            result.setMsg("没有文件!");
+            return result;
+        }
+        if (checkMd5(param.getFile().getInputStream(), param.getIdentifier())) {
+            result.setSuccess(false);
+            result.setMsg("文件的Identifier对不上!");
+            return result;
+        }
+
+        // 获取文件路径
+        String filePath = this.getSysLocalFileUrl() + "largeFile/";
+        /**
+         * 查询是否已经上传该分片
+         * **/
+        QueryWrapper<LargeFile> wrapper = new QueryWrapper<LargeFile>()
+                .eq("file_key", param.getIdentifier()).eq("is_deleted", 0).eq("shard_index", param.getChunkNumber()).orderByDesc("shard_index");
+        LargeFile list = iLargeFileService.getOne(wrapper);
+        LargeFile largeFile = null;
+        if (list != null) { // 该分片已经上传
+            if (StringUtils.isNotEmpty(list.getPath())) {
+                File chfile = new File(list.getPath());
+                if (chfile.exists()) {
+                    result.setSuccess(true);
+                    result.setMsg("该分片已上传!");
+                    result.setData(list.getShardIndex());
+                    result.setCode(200);
+                } else {
+                    iLargeFileService.remove(wrapper);
+                    largeFile = addLocalFileOne(param, filePath);
+                }
+            }
+        } else {  //没有上传时
+            largeFile = addLocalFileOne(param, filePath);
+        }
+
+        // 是否为最后一片
+        if ((param.getTotalChunks() + "").equals(param.getChunkNumber() + "")) {
+            // 检测是否为最后一块分片
+            for (int i = 0; i <= 2; i++) {
+                QueryWrapper<LargeFile> wrapper1 = new QueryWrapper<LargeFile>()
+                        .eq("file_key", param.getIdentifier()).eq("is_deleted", 0);
+                Integer count = Math.toIntExact(iLargeFileService.count(wrapper1));
+                if (count.equals(param.getTotalChunks())) {
+                    NewBladeFile newBladeFile = SaveOssInfo(param, largeFile, filePath);
+                    result.setData(newBladeFile);
+                    result.setCode(200);
+                    result.setSuccess(true);
+                    result.setMsg("操作成功!");
+                } else {
+                    Thread.sleep(2000);
+                }
+            }
+        }
+        return result;
+    }
+
+
+    public NewBladeFile SaveOssInfo(MultipartFileParam param, LargeFile largeFile, String filePath) {
+        lock.lock();
+        NewBladeFile newBladeFile = new NewBladeFile();
+        try {
+            /**每个文件保存到本地所使用的合并各个文件**/
+            merge(largeFile, filePath);
+            String path = largeFile.getPath(); //获取到的路径 没有.1 .2 这样的东西
+            //截取视频所在的路径
+            path = path.replace(filePath, "");
+            File file = new File(filePath + path);
+            //修改成原来的文件名
+            renameFile(file, param.getFilename());
+            FileInputStream inputStream = new FileInputStream(filePath + param.getFilename());
+            //上传oss
+            BladeFile bladeFile = ossBuilder.template().putFile(param.getFilename(), inputStream);
+            File file1 = new File(filePath + param.getFilename());
+            MultipartFile multipartFile = getMultipartFile(file1);
+            if (param.getFilename().contains("pdf")) {
+                try {
+                    PdfReader pdfReader = new PdfReader(multipartFile.getInputStream());
+                    int pages = pdfReader.getNumberOfPages();
+                    //获取文件页数
+                    newBladeFile.setPage(pages);
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+                //pdf的路径就是文件上传的路径
+                newBladeFile.setPdfUrl(bladeFile.getLink());
+            } else if (param.getFilename().contains("xlsx") || param.getFilename().contains("xls")) {
+                newBladeFile = this.commonFileClient.excelToPdf(multipartFile);
+            } else if (param.getFilename().contains("docx")) {
+                newBladeFile = this.commonFileClient.wordToPdf(multipartFile);
+            } else if (param.getFilename().contains("png") || param.getFilename().contains("jpg")) {
+
+                newBladeFile = this.commonFileClient.pngOrJpgToPdf(multipartFile);
+            }
+            BeanUtils.copyProperties(bladeFile, newBladeFile);
+            newBladeFile.setFileSize(multipartFile.getSize() / 1024);
+            //删除本地文件
+            file1.delete();
+            iLargeFileService.updateLargeFileDeleted(param.getIdentifier());
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        } finally {
+            lock.unlock();
+        }
+        return newBladeFile;
+    }
+
+    public LargeFile addLocalFileOne(MultipartFileParam param, String filePath) throws IOException {
+        // 文件名称
+        String fileName = getFileName(param);
+        // 临时文件名称
+        String tempFileName = param.getIdentifier() + fileName.substring(fileName.lastIndexOf(".")) + "." + param.getChunkNumber();
+        File tempFile = buildUploadFile(tempFileName);
+        //为了防止win路径有时会抛异常,增加一个处理
+        try {
+            param.getFile().transferTo(tempFile);
+        } catch (Exception e) {
+            writeMultipartFileToFile(param, tempFile);
+        }
+        LargeFile largeFile = new LargeFile();
+        largeFile.setFileKey(param.getIdentifier());
+        largeFile.setName(tempFileName);
+        largeFile.setPath(filePath + fileName);
+        largeFile.setShardIndex(param.getChunkNumber());
+        largeFile.setShardSize(param.getChunkSize());
+        largeFile.setSize(Integer.valueOf(param.getCurrentChunkSize()));
+        largeFile.setShardTotal(param.getTotalChunks());
+        largeFile.setSuffix(param.getObjectType());
+        iLargeFileService.save(largeFile);
+        return largeFile;
+    }
+
+
+    public void writeMultipartFileToFile(MultipartFileParam param, File tempFile) throws IOException {
+        byte[] data = param.getFile().getBytes(); // 获取二进制数据
+        FileOutputStream outputStream = new FileOutputStream(tempFile);
+        try {
+            outputStream.write(data); // 将二进制数据写入到文件中
+        } finally {
+            outputStream.close(); // 关闭输出流
+        }
+    }
+
+    /**
+     * file 转 MultipartFile
+     **/
+    public static MultipartFile getMultipartFile(File file) {
+        DiskFileItem item = new DiskFileItem("file",
+                MediaType.MULTIPART_FORM_DATA_VALUE,
+                true,
+                file.getName(), (int) file.length(), file.getParentFile());
+        try {
+            OutputStream os = item.getOutputStream();
+            os.write(FileUtils.readFileToByteArray(file));
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return new CommonsMultipartFile(item);
+    }
+
+    /**
+     * 构建上传目录和文件
+     */
+    private File buildUploadFile(String name) {
+        String fileName = name;
+        String fullDir = buildUploadDir();
+        return new File(fullDir, fileName);
+    }
+
+    /**
+     * 构建上传完整目录
+     */
+    private String buildUploadDir() {
+        String fullDir = getSysLocalFileUrl() + "largeFile/";
+        File dir = new File(fullDir);
+        if (!dir.exists()) {
+            dir.mkdirs();
+        }
+        return fullDir;
+    }
+
+    /**
+     * md5校验
+     */
+    private boolean checkMd5(InputStream is, String md5) {
+        String check = "";
+        try {
+            check = DigestUtils.md5DigestAsHex(is);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        if (!check.equalsIgnoreCase(md5)) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * @author fengxinglie
+     * 合并分页
+     */
+    private void merge(LargeFile largeFile, String basePath) throws FileNotFoundException, InterruptedException {
+        //合并分片开始
+        String path = largeFile.getPath(); //获取到的路径 没有.1 .2 这样的东西
+        //截取视频所在的路径
+        path = path.replace(basePath, "");
+        Integer shardTotal = largeFile.getShardTotal();
+        File newFile = new File(basePath + path);
+        FileOutputStream outputStream = new FileOutputStream(newFile, true); // 文件追加写入
+        FileInputStream fileInputStream = null; //分片文件
+        byte[] byt = new byte[10 * 1024 * 1024];
+        int len;
+        try {
+            for (int i = 0; i < shardTotal; i++) {
+                // 读取第i个分片
+                fileInputStream = new FileInputStream(new File(basePath + path + "." + (i + 1))); // course\6sfSqfOwzmik4A4icMYuUe.mp4.1
+                while ((len = fileInputStream.read(byt)) != -1) {
+                    outputStream.write(byt, 0, len);
+                }
+            }
+        } catch (IOException e) {
+        } finally {
+            try {
+                if (fileInputStream != null) {
+                    fileInputStream.close();
+                }
+                outputStream.close();
+            } catch (Exception e) {
 //				log.error("IO流关闭", e);
-			}
-		}
-		//告诉java虚拟机去回收垃圾 至于什么时候回收 这个取决于 虚拟机的决定
-		System.gc();
-		//等待100毫秒 等待垃圾回收去 回收完垃圾
-		Thread.sleep(100);
-		for (int i = 0; i < shardTotal; i++) {
-			String filePath = basePath + path + "." + (i + 1);
-			File file = new File(filePath);
-			boolean result = file.delete();
+            }
+        }
+        //告诉java虚拟机去回收垃圾 至于什么时候回收 这个取决于 虚拟机的决定
+        System.gc();
+        //等待100毫秒 等待垃圾回收去 回收完垃圾
+        Thread.sleep(100);
+        for (int i = 0; i < shardTotal; i++) {
+            String filePath = basePath + path + "." + (i + 1);
+            File file = new File(filePath);
+            boolean result = file.delete();
 //			log.info("删除{},{}", filePath, result ? "成功" : "失败");
-		}
+        }
 //		log.info("删除分片结束");
-	}
-
-	/**
-	 * 文件重命名
-	 *
-	 * @param toBeRenamed   将要修改名字的文件
-	 * @param toFileNewName 新的名字
-	 * @return
-	 */
-	private static boolean renameFile(File toBeRenamed, String toFileNewName) {
-		//检查要重命名的文件是否存在,是否是文件
-		if (!toBeRenamed.exists() || toBeRenamed.isDirectory()) {
-			return false;
-		}
-		String p = toBeRenamed.getParent();
-		File newFile = new File(p + File.separatorChar + toFileNewName);
-		//修改文件名
-		return toBeRenamed.renameTo(newFile);
-	}
-
-
-	/**
-	 * 在MappedByteBuffer释放后再对它进行读操作的话就会引发jvm crash,在并发情况下很容易发生
-	 * 正在释放时另一个线程正开始读取,于是crash就发生了。所以为了系统稳定性释放前一般需要检 查是否还有线程在读或写
-	 *
-	 * @param mappedByteBuffer
-	 */
-	private static void freeMappedByteBuffer(final MappedByteBuffer mappedByteBuffer) {
-		try {
-			if (mappedByteBuffer == null) {
-				return;
-			}
-			mappedByteBuffer.force();
-			AccessController.doPrivileged(new PrivilegedAction<Object>() {
-				@Override
-				public Object run() {
-					try {
-						Method getCleanerMethod = mappedByteBuffer.getClass().getMethod("cleaner", new Class[0]);
-						//可以访问private的权限
-						getCleanerMethod.setAccessible(true);
-						//在具有指定参数的 方法对象上调用此 方法对象表示的底层方法
-						sun.misc.Cleaner cleaner = (sun.misc.Cleaner) getCleanerMethod.invoke(mappedByteBuffer,
-								new Object[0]);
-						cleaner.clean();
-					} catch (Exception e) {
+    }
+
+    /**
+     * 文件重命名
+     *
+     * @param toBeRenamed   将要修改名字的文件
+     * @param toFileNewName 新的名字
+     * @return
+     */
+    private static boolean renameFile(File toBeRenamed, String toFileNewName) {
+        //检查要重命名的文件是否存在,是否是文件
+        if (!toBeRenamed.exists() || toBeRenamed.isDirectory()) {
+            return false;
+        }
+        String p = toBeRenamed.getParent();
+        File newFile = new File(p + File.separatorChar + toFileNewName);
+        //修改文件名
+        return toBeRenamed.renameTo(newFile);
+    }
+
+
+    /**
+     * 在MappedByteBuffer释放后再对它进行读操作的话就会引发jvm crash,在并发情况下很容易发生
+     * 正在释放时另一个线程正开始读取,于是crash就发生了。所以为了系统稳定性释放前一般需要检 查是否还有线程在读或写
+     *
+     * @param mappedByteBuffer
+     */
+    private static void freeMappedByteBuffer(final MappedByteBuffer mappedByteBuffer) {
+        try {
+            if (mappedByteBuffer == null) {
+                return;
+            }
+            mappedByteBuffer.force();
+            AccessController.doPrivileged(new PrivilegedAction<Object>() {
+                @Override
+                public Object run() {
+                    try {
+                        Method getCleanerMethod = mappedByteBuffer.getClass().getMethod("cleaner", new Class[0]);
+                        //可以访问private的权限
+                        getCleanerMethod.setAccessible(true);
+                        //在具有指定参数的 方法对象上调用此 方法对象表示的底层方法
+                        sun.misc.Cleaner cleaner = (sun.misc.Cleaner) getCleanerMethod.invoke(mappedByteBuffer,
+                                new Object[0]);
+                        cleaner.clean();
+                    } catch (Exception e) {
 //						log.error("clean MappedByteBuffer error!!!", e);
-					}
-					return null;
-				}
-			});
-		} catch (Exception e) {
-			e.printStackTrace();
-		}
-	}
-
-	private static String getFileName(MultipartFileParam param) {
-		String extension;
-		if (ObjectUtil.isNotEmpty(param.getFile())) {
-			String filename = param.getFile().getOriginalFilename();
-			extension = filename.substring(filename.lastIndexOf("."));
-		} else {
-			extension = param.getFilename().substring(param.getFilename().lastIndexOf("."));
-		}
-		return param.getIdentifier() + extension;
-	}
+                    }
+                    return null;
+                }
+            });
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    private static String getFileName(MultipartFileParam param) {
+        String extension;
+        if (ObjectUtil.isNotEmpty(param.getFile())) {
+            String filename = param.getFile().getOriginalFilename();
+            extension = filename.substring(filename.lastIndexOf("."));
+        } else {
+            extension = param.getFilename().substring(param.getFilename().lastIndexOf("."));
+        }
+        return param.getIdentifier() + extension;
+    }
 
 
 }

+ 13 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/ProjectInfo.java

@@ -154,4 +154,17 @@ public class ProjectInfo extends BaseEntity {
      * 是否正在自动组卷中  0否  1是
      */
     private Integer isArchivesAuto;
+
+
+    /**
+     * wbs私有树引用wbs模板类型--征拆
+     */
+    @ApiModelProperty(value = "wbs私有树引用wbs模板类型--征拆")
+    private Long referenceWbsTemplateIdLar;
+
+    /**
+     * wbs私有树引用wbs模板id--征拆
+     */
+    @ApiModelProperty(value = "wbs私有树引用wbs模板id--征拆")
+    private String referenceWbsTemplateTypeLar;
 }

+ 6 - 0
blade-service-api/blade-system-api/src/main/java/org/springblade/system/vo/CheckedTreeVO.java

@@ -31,4 +31,10 @@ public class CheckedTreeVO implements Serializable {
 
     private List<String> apiScope;
 
+    // 内控系统
+    private List<String> hacMenu;
+
+    // 征拆系统
+    private List<String> larMenu;
+
 }

+ 6 - 0
blade-service-api/blade-system-api/src/main/java/org/springblade/system/vo/GrantTreeVO.java

@@ -26,6 +26,12 @@ public class GrantTreeVO implements Serializable {
     //档案菜单
     private List<TreeNodeVO> archivesMenu;
 
+    // 内控系统
+    private List<TreeNodeVO> hacMenu;
+
+    //征拆系统
+    private List<TreeNodeVO> larMenu;
+
     //数据
     private List<TreeNodeVO> dataScope;
 

+ 6 - 0
blade-service-api/blade-system-api/src/main/java/org/springblade/system/vo/GrantVO.java

@@ -27,6 +27,12 @@ public class GrantVO implements Serializable {
     @ApiModelProperty(value = "menuArchivesIds集合-档案")
     private List<String> menuArchivesIds;
 
+    @ApiModelProperty(value = "menuArchivesIds集合-内控")
+    private List<String> menuHacIds;
+
+    @ApiModelProperty(value = "menuArchivesIds集合-征拆")
+    private List<String> menularIds;
+
     @ApiModelProperty(value = "topMenuIds集合")
     private List<Long> topMenuIds;
 

+ 0 - 1
blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchiveExaminingReportController.java

@@ -39,7 +39,6 @@ import java.util.List;
 public class ArchiveExaminingReportController {
     private final IArchiveExaminingReportService archiveExaminingReportService;
 
-    private final NewIOSSClient iossClient;
     private final EVisaClient eVisaClient;
 
     @GetMapping("test")

+ 28 - 4
blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchivesAutoController.java

@@ -25,12 +25,14 @@ import lombok.AllArgsConstructor;
 
 import javax.validation.Valid;
 
+import lombok.SneakyThrows;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang.StringUtils;
 import org.apache.http.message.BasicNameValuePair;
 import org.springblade.archive.service.IArchiveAutoPdfService;
 import org.springblade.archive.utils.CallBgrsjk;
 import org.springblade.business.entity.ArchiveFile;
+import org.springblade.common.constant.CommonConstant;
 import org.springblade.common.utils.CommonUtil;
 import org.springblade.core.mp.support.Condition;
 import org.springblade.core.mp.support.Query;
@@ -42,6 +44,7 @@ import org.springblade.manager.entity.ProjectInfo;
 import org.springblade.manager.feign.ArchiveTreeContractClient;
 import org.springblade.manager.feign.ContractClient;
 import org.springblade.manager.feign.ProjectClient;
+import org.springblade.system.cache.ParamCache;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.bind.annotation.RequestParam;
@@ -51,6 +54,7 @@ import org.springblade.archive.vo.ArchivesAutoVO;
 import org.springblade.archive.wrapper.ArchivesAutoWrapper;
 import org.springblade.archive.service.IArchivesAutoService;
 import org.springblade.core.boot.ctrl.BladeController;
+import org.springframework.web.multipart.MultipartFile;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -564,13 +568,33 @@ public class ArchivesAutoController extends BladeController {
 		if(map.get("data") == null) {
 			return R.data(null);
 		}
-		JSONObject  jsonObject1 = JSONObject.parseObject(map.get("data").toString());
-		Map<String,Object> map1 = (Map<String,Object>)jsonObject1;
-		if(map1.get("token") != null) {
-			String value3 = CallBgrsjk.callgetdata("Bearer " + map1.get("token"),list);
+		JSONObject jsonObject1 = JSONObject.parseObject(map.get("data").toString());
+		Map<String, Object> map1 = (Map<String, Object>) jsonObject1;
+		if (map1.get("token") != null) {
+			String value3 = CallBgrsjk.callgetdata("Bearer " + map1.get("token"), list);
 			JSONObject jsonObject3 = JSONObject.parseObject(value3);
 			return R.data(jsonObject3);
 		}
 		return R.data(null);
 	}
+
+	/**
+	 * 语音搜索
+	 *
+	 * @param file 文件
+	 */
+	@SneakyThrows
+	@PostMapping("/search-info")
+	@ApiOperationSupport(order = 9)
+	@ApiOperation(value = "语音搜索", notes = "语音搜索")
+	@ApiImplicitParams(value = {
+			@ApiImplicitParam(name = "file", value = "文件源", required = true)
+	})
+	public R putFileAttach(@RequestParam("file") MultipartFile file) {
+
+		String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
+
+
+		return R.success("上传成功");
+	}
 }

+ 42 - 102
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TaskServiceImpl.java

@@ -137,12 +137,6 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
      */
     @Override
     public TaskApprovalVO queryBusinessDataTask(TaskApprovalVO taskApprovalVO) {
-        /*int foreachNumber = 0;
-        do {
-            //判断锁是否存在
-            if (!DistributedRedisLock.getLockStatus(taskApprovalVO.getFormDataId())) {
-                //如果不存在,直接获取并上锁,由于这个查询方法是任务方面使用,所以解锁需要在对应数据使用结束后
-                DistributedRedisLock.acquire(taskApprovalVO.getFormDataId(), 20);*/
         switch (taskApprovalVO.getApprovalType()) {
             case 1:
                 //填报数据
@@ -154,26 +148,8 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
                 //日志资料
                 return this.queryTheLogFileBusinessData(taskApprovalVO.getFormDataId());
             default:
-                //未找到数据,解锁
-                DistributedRedisLock.release(taskApprovalVO.getFormDataId());
                 return null;
         }
-            /*} else {
-                try {
-                    if (foreachNumber < 10) {
-                        //如果存在锁,则等待解锁
-                        TimeUnit.MILLISECONDS.sleep(5);
-                        foreachNumber++;
-                    } else {
-                        break;
-                    }
-                } catch (Exception e) {
-                    e.printStackTrace();
-                }
-            }
-        } while (true);
-        //能走到这说明找不到文件或者超过锁定次数,解锁并返回
-        DistributedRedisLock.release(taskApprovalVO.getFormDataId());*/
     }
 
     @Override
@@ -479,66 +455,46 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
         this.taskParallelService.update(Wrappers.<TaskParallel>lambdaUpdate()
                 .set(TaskParallel::getEVisaContent, "当前等待电签的批次较多,请等待几分钟后刷新页面查看........")
                 .in(TaskParallel::getParallelProcessInstanceId, taskIds));
-        //保存批次
-        TaskBatch taskBatch = new TaskBatch(null, JSONObject.toJSONString(taskApprovalVOS));
-        taskBatch.setCreateUser(userId);
-        taskBatch.setNickName(nickName);
-        taskBatch.setCreateTime(new Date());
 
-        this.taskBatchService.save(taskBatch);
-        String taskBatchId = taskBatch.getId().toString();
-
-        // 电签
-        Boolean istrue = true;
+        List<TaskBatch> tabskList = new ArrayList<>();
         for (TaskApprovalVO taskApprovalVO : taskApprovalVOS) {
-            Boolean aBoolean = RedisTemplate.hasKey("sign-" + taskApprovalVO.getFormDataId());
-            if (aBoolean) {
-                istrue = false;
-                break;
-            }
-        }
-
-        // 添加到 线程中
-        if (istrue) {
-            CompletableFuture<Void> runAsync = CompletableFuture.runAsync(() -> {
-                try {
-                    this.checkIsExsitTaskBatch(taskApprovalVOS, taskBatchId, userId, nickName);
-                } catch (FileNotFoundException e) {
-                    e.printStackTrace();
-                }
-            }, executor);
+            //保存批次
+            TaskBatch taskBatch = new TaskBatch(null, JSONObject.toJSONString(taskApprovalVO));
+            taskBatch.setCreateUser(userId);
+            taskBatch.setNickName(nickName);
+            taskBatch.setCreateTime(new Date());
+            tabskList.add(taskBatch);
         }
+        this.taskBatchService.saveBatch(tabskList);
     }
 
 
-    @Scheduled(cron = "0 */5 * * * ?")
+    @Scheduled(cron = "0 */2 * * * ?")
     public void SignInfo() {
         //执行代码
         logger.debug("扫描开始");
         List<TaskBatch> maps = taskBatchService.getBaseMapper().selectList(Wrappers.<TaskBatch>lambdaQuery().eq(TaskBatch::getIsDeleted, 0));
         if (maps != null && maps.size() >= 1) {
-
             for (TaskBatch dataInfo : maps) {
                 String jsonData = dataInfo.getJsonData();
-                List<TaskApprovalVO> list = JSONArray.parseArray(jsonData, TaskApprovalVO.class);
+                TaskApprovalVO taskApprovalVO = JSON.parseObject(jsonData, TaskApprovalVO.class);
                 String taskBatchId = dataInfo.getId().toString();
                 Long userId = dataInfo.getCreateUser();
                 String nickName = dataInfo.getNickName();
 
                 Boolean istrue = true;
-                for (TaskApprovalVO taskApprovalVO : list) {
-                    Boolean aBoolean = RedisTemplate.hasKey("sign-" + taskApprovalVO.getFormDataId());
-                    if (aBoolean) {
-                        istrue = false;
-                        break;
-                    }
+                Boolean aBoolean = RedisTemplate.hasKey("sign-" + taskApprovalVO.getFormDataId());
+                if (aBoolean) {
+                    istrue = false;
                 }
-
-                // 添加到 线程中
                 if (istrue) {
+                    int wtask = executor.getQueue().size();
+                    if (wtask >= 200) {
+                        break;
+                    }
                     CompletableFuture<Void> runAsync = CompletableFuture.runAsync(() -> {
                         try {
-                            this.checkIsExsitTaskBatch(list, taskBatchId, userId, nickName);
+                            this.checkIsExsitTaskBatch(taskApprovalVO, taskBatchId, userId, nickName);
                         } catch (FileNotFoundException e) {
                             e.printStackTrace();
                         }
@@ -549,35 +505,33 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
         }
     }
 
-    private void checkIsExsitTaskBatch(List<TaskApprovalVO> taskApprovalVOS, String batchId, Long userId, String nickName) throws FileNotFoundException {
-        boolean isContinue = true;
-        while (isContinue) {
-            logger.info("【任务审核】当前批次开始电签。批次ID:" + batchId);
-            //执行电签
-            for (TaskApprovalVO taskApprovalVO : taskApprovalVOS) {
-                taskApprovalVO.setUserId(userId);
-                taskApprovalVO.setNickName(nickName);
-                RedisTemplate.opsForValue().set("sign-" + taskApprovalVO.getFormDataId(), "1", 150, TimeUnit.SECONDS);
-
-                String pdfUrlEVisa = this.completeApprovalTask(taskApprovalVO);
-                //TODO ============== 电签成功,修改试验状态,关联工程部位信息pdf(只有电签成功,才修改) liuYc 2023-03-16 ==============
-                if ("OK".equals(taskApprovalVO.getFlag()) && StringUtils.isNotEmpty(pdfUrlEVisa)) {
-                    //已审批
-                    this.iTrialSelfInspectionRecordService.updateTrialSelfInspectionRecordStatus(pdfUrlEVisa, taskApprovalVO);
-                }
-                if (!"OK".equals(taskApprovalVO.getFlag())) {
-                    //已废除
-                    this.iTrialSelfInspectionRecordService.updateTrialSelfInspectionRecordStatusFC(taskApprovalVO);
-                }
-            }
+    private void checkIsExsitTaskBatch(TaskApprovalVO taskApprovalVO, String batchId, Long userId, String nickName) throws FileNotFoundException {
+        logger.info("【任务审核】当前批次开始电签。批次ID:" + batchId);
+        //执行电签
+        System.out.println("排队数量" + executor.getQueue().size());
+        System.out.println("活跃数量" + executor.getActiveCount());
+        System.out.println("总共数量" + executor.getTaskCount());
+        System.out.println("完成数量" + executor.getCompletedTaskCount());
+        taskApprovalVO.setUserId(userId);
+        taskApprovalVO.setNickName(nickName);
+        RedisTemplate.opsForValue().set("sign-" + taskApprovalVO.getFormDataId(), "1", 60, TimeUnit.SECONDS);
+
+        String pdfUrlEVisa = this.completeApprovalTask(taskApprovalVO);
+        //TODO ============== 电签成功,修改试验状态,关联工程部位信息pdf(只有电签成功,才修改) liuYc 2023-03-16 ==============
+        if ("OK".equals(taskApprovalVO.getFlag()) && StringUtils.isNotEmpty(pdfUrlEVisa)) {
+            //已审批
+            this.iTrialSelfInspectionRecordService.updateTrialSelfInspectionRecordStatus(pdfUrlEVisa, taskApprovalVO);
+            //executor删除掉对应批次
+            this.taskBatchService.deletedById(batchId);
+        }
 
+        if (!"OK".equals(taskApprovalVO.getFlag())) {
+            //已废除
+            this.iTrialSelfInspectionRecordService.updateTrialSelfInspectionRecordStatusFC(taskApprovalVO);
             //executor删除掉对应批次
             this.taskBatchService.deletedById(batchId);
-            for (TaskApprovalVO taskApprovalVO : taskApprovalVOS) {
-                RedisTemplate.delete("sign-" + taskApprovalVO.getFormDataId());
-            }
-            isContinue = false;
         }
+        RedisTemplate.delete("sign-" + taskApprovalVO.getFormDataId());
     }
 
     // 电签主流程业务
@@ -594,7 +548,7 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
         //获取当前分支信息
         TaskParallel currentLink = this.taskParallelService.getOne(Wrappers.<TaskParallel>lambdaQuery().eq(TaskParallel::getParallelProcessInstanceId, parallelProcessInstanceId).eq(TaskParallel::getIsDeleted, 0));
         if (currentLink == null) {
-            return "";
+            return "无当前分支信息";
         }
         //获取主流程
         Task masterTask = this.getOne(Wrappers.<Task>lambdaQuery().eq(Task::getIsDeleted, 0).eq(Task::getProcessInstanceId, currentLink.getProcessInstanceId()));
@@ -656,7 +610,6 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
                 } else {
                     //只更新PDF路径
                     this.updateBusinessDataByFormDataId(masterTask, 1, eVisaStatus.contains("@@@@") ? eVisaStatus.split("@@@@")[1] : null);
-
                     return eVisaStatus.contains("@@@@") ? eVisaStatus.split("@@@@")[1] : null;
                 }
             } else if ("eVisaError".equals(eVisaStatus) || eVisaStatus.contains("eVisaError")) {
@@ -673,9 +626,6 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
                         .eq(TaskParallel::getParallelProcessInstanceId, parallelProcessInstanceId)
                 );
 
-                //解锁
-                DistributedRedisLock.release(masterTask.getFormDataId());
-
             } else {
                 //notPfxOrFile,没有证书或证书文件过期等
                 //修改
@@ -685,9 +635,6 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
                         .set(TaskParallel::getUpdateTime, new Date())
                         .eq(TaskParallel::getParallelProcessInstanceId, parallelProcessInstanceId)
                 );
-
-                //解锁
-                DistributedRedisLock.release(masterTask.getFormDataId());
             }
         } else {
             //废除,遵循只要某一个分支流程废除,则主流程废除、其它分支流程均自动结束
@@ -737,7 +684,6 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
 
             //任务废除通知
             this.abolishMessage(masterTask, currentLink, comment);
-
         }
         return "";
     }
@@ -1005,8 +951,6 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
                 .set(ContractLog::getAuditUserIdAndName, null)
                 .set(ContractLog::getBatch, null)
                 .in(ContractLog::getId, Arrays.asList(formDataId.split(","))));
-        //解锁
-        DistributedRedisLock.release(formDataId);
     }
 
     /**
@@ -1019,8 +963,6 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
                 .set(InformationQuery::getReportNumber, null)
                 .set(InformationQuery::getAuditUserIdAndName, null)
                 .in(InformationQuery::getId, Arrays.asList(formDataId.split(","))));
-        //解锁
-        DistributedRedisLock.release(formDataId);
     }
 
     /**
@@ -1033,8 +975,6 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
         wrapper.set(ArchiveFile::getStatus, status)
                 .set(ArchiveFile::getEVisaFile, newFileUrl);
         this.archiveFileService.update(wrapper.in(ArchiveFile::getId, Arrays.asList(formDataId.split(","))));
-        //解锁
-        DistributedRedisLock.release(formDataId);
     }
 
 }

+ 4 - 1
blade-service/blade-control/src/main/java/org/springblade/control/mapper/DictInfoMapper.xml

@@ -24,7 +24,10 @@
     <select id="getDictInfo" resultMap="dictInfoResultMap">
         select *
         from c_dict_info
-        where is_deleted = 0
+        where code = #{param1}
+          and parent_id > 0
+          and is_deleted = 0
+        order by sort
     </select>
 
     <select id="selectUserTabPage" resultMap="dictInfoResultMap">

+ 0 - 8
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExcelTabController.java

@@ -1216,14 +1216,6 @@ public class ExcelTabController extends BladeController {
                                 exctabCell.setExctabId(excelId);
 
 
-                               /* if(inputText.indexOf("质检工程师")>=0 && inputText.indexOf("专业监理工程师")>=0 && inputText.indexOf("检查意见")>=0){
-                                    inputText = "专业监理工程师_签字";
-                                }else if(inputText.indexOf("质检工程师")>=0  && inputText.indexOf("检查意见")>=0){
-                                    inputText = "质检工程师_签字";
-                                }else if(inputText.indexOf("外观质量")>=0  && inputText.indexOf("评述")>=0 && inputText.indexOf("外观")>=0){
-                                    inputText = "外观评述";
-                                }*/
-
                                 exctabCell.setTextInfo(inputText);
                                 if (inputText.contains("日期") || inputText.contains("年") || inputText.contains("月") || inputText.contains("日")) {
                                     //日期

+ 2 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ProjectInfoMapper.java

@@ -24,6 +24,8 @@ public interface ProjectInfoMapper extends BaseMapper<ProjectInfo> {
 
     void updateTemplateInfoTrial(String projectId, String referencePrivateWbsProjectId, String type);
 
+    void updateTemplateInfoLar(String projectId, String referencePrivateWbsProjectId, String type);
+
     ProjectInfo selectOneAndWbsTypeById(Long id);
 
 }

+ 15 - 2
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ProjectInfoMapper.xml

@@ -36,6 +36,8 @@
         <result column="reference_log_wbs_template_id" property="referenceLogWbsTemplateId"/>
         <result column="is_open_random_number" property="isOpenRandomNumber"/>
         <result column="remark_type" property="remarkType"/>
+        <result column="reference_wbs_template_id_lar" property="referenceWbsTemplateIdLar"/>
+        <result column="reference_wbs_template_type_lar" property="referenceWbsTemplateTypeLar"/>
     </resultMap>
 
     <resultMap id="singPfxManagementResultMap" type="org.springblade.manager.vo.SingPfxManagementVO">
@@ -133,13 +135,24 @@
           AND status = 1
     </update>
 
+    <update id="updateTemplateInfoLar">
+        UPDATE m_project_info
+        SET reference_wbs_template_id_lar   = #{referencePrivateWbsProjectId},
+            reference_wbs_template_type_lar = #{type}
+        WHERE id = #{projectId}
+          AND is_deleted = 0
+          AND status = 1
+    </update>
+
     <select id="selectProjectInfoPage" resultMap="projectInfoResultMap">
-        select * from m_project_info where is_deleted = 0
+        select *
+        from m_project_info
+        where is_deleted = 0
     </select>
 
     <select id="selectOneAndWbsTypeById" resultType="org.springblade.manager.entity.ProjectInfo">
         SELECT *,
-        (select wbs_type from m_wbs_info )
+               (select wbs_type from m_wbs_info)
         FROM m_project_info
         WHERE id = #{id}
     </select>

+ 1 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreePrivateMapper.xml

@@ -349,7 +349,7 @@
         <if test="wbsType != null and wbsType != '' and wbsType != -1">
             AND d.wbs_type = #{wbsType}
         </if>
-        <if test="wbsId != null and wbsId != '' and wbsType != -1">
+        <if test="wbsId != null and wbsId != '' and wbsType !=-1">
             AND d.wbs_id = #{wbsId}
         </if>
         AND d.type = 1

+ 3 - 3
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ExcelTabServiceImpl.java

@@ -1637,16 +1637,16 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
 
         //获取当前填报节点sort
         WbsTreeContract wbsTreeContract = wbsTreeContractService.getBaseMapper().selectOne(Wrappers.<WbsTreeContract>lambdaQuery().eq(WbsTreeContract::getPKeyId, nodeId));
-
+        System.out.println("wbsTreeContract==" + wbsTreeContract);
         //获取顺序
         int sort = 0;
         if (ObjectUtil.isNotEmpty(wbsTreeContract)) {
             if (wbsTreeContract.getSort() != null) {
                 sort = wbsTreeContract.getSort();
+                contractId = wbsTreeContract.getContractId();
             }
         }
-
-        String sql = "update u_information_query set pdf_url ='" + bladeFile.getLink() + "' ,sort = " + sort + " where classify='" + classify + "' and  wbs_id='" + nodeId + "' and contract_id ='" + contractId + "' ";
+        String sql = "update u_information_query set pdf_url ='" + bladeFile.getLink() + "' , sort = " + sort + " where classify='" + classify + "' and  wbs_id='" + nodeId + "' and contract_id ='" + contractId + "' ";
         jdbcTemplate.execute(sql);
     }
 

+ 8 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeServiceImpl.java

@@ -897,6 +897,10 @@ public class WbsTreeServiceImpl extends BaseServiceImpl<WbsTreeMapper, WbsTree>
                             projectInfoMapper.updateTemplateInfoTrial(pawDTO.getProjectId(), pawDTO.getWbsId(), "public");
                         }
 
+                        if (pawDTO.getWbsType() == 5) {
+                            projectInfoMapper.updateTemplateInfoLar(pawDTO.getProjectId(), pawDTO.getWbsId(), "public");
+                        }
+
                     } else if (pawDTO.getReferenceType().equals("private")) {
                         List<List<WbsTreePrivate>> partition1 = Lists.partition(insertData2, 1000);
                         for (List<WbsTreePrivate> addList : partition1) {
@@ -913,6 +917,10 @@ public class WbsTreeServiceImpl extends BaseServiceImpl<WbsTreeMapper, WbsTree>
                         if (pawDTO.getWbsType() == 2) {
                             projectInfoMapper.updateTemplateInfoTrial(pawDTO.getProjectId(), pawDTO.getPrimaryKeyId(), "private");
                         }
+
+                        if (pawDTO.getWbsType() == 5) {
+                            projectInfoMapper.updateTemplateInfoLar(pawDTO.getProjectId(), pawDTO.getWbsId(), "private");
+                        }
                     }
                     if (saveIds.size() >= 1000) {
                         bladeRedis.set("submit-wbs-project:" + pawDTO.getProjectId(), "1");

+ 22 - 0
blade-service/blade-system/src/main/java/org/springblade/system/controller/MenuController.java

@@ -228,6 +228,8 @@ public class MenuController extends BladeController {
         List<TreeNodeVO> treeMenu = new ArrayList<>(); //后管
         List<TreeNodeVO> treeUserMenu = new ArrayList<>(); //客户端
         List<TreeNodeVO> treeMenuArchives = new ArrayList<>(); //档案
+        List<TreeNodeVO> treeMenuHac = new ArrayList<>(); //内控系统
+        List<TreeNodeVO> treeMenuLar = new ArrayList<>(); //征拆系统
         //获取所有菜单
         List<TreeNodeVO> treeNodesAll = menuService.grantTree(user);
         //获取AuthClient
@@ -254,6 +256,18 @@ public class MenuController extends BladeController {
                             treeMenuArchives.add(treeNode);
                         }
                     }
+                    if (("hac").equals(authClient.getClientId())) {
+                        //档案
+                        if (treeNode.getSysId().equals(authClient.getId())) {
+                            treeMenuHac.add(treeNode);
+                        }
+                    }
+                    if (("lar").equals(authClient.getClientId())) {
+                        //档案
+                        if (treeNode.getSysId().equals(authClient.getId())) {
+                            treeMenuLar.add(treeNode);
+                        }
+                    }
                     //TODO 其他菜单权限
                 }
             }
@@ -265,6 +279,10 @@ public class MenuController extends BladeController {
         vo.setUsermenu(treeUserMenu);
         //档案
         vo.setArchivesMenu(treeMenuArchives);
+        //内控系统
+        vo.setHacMenu(treeMenuHac);
+        //征拆
+        vo.setLarMenu(treeMenuLar);
         //数据源
         vo.setDataScope(menuService.grantDataScopeTree(user));
         //接口
@@ -298,6 +316,10 @@ public class MenuController extends BladeController {
 
         //接口
         vo.setApiScope(menuService.apiScopeTreeKeys(roleIds));
+        // 内控系统
+        vo.setHacMenu(menuService.apiScopeTreeKeys(roleIds));
+        //征拆系统
+        vo.setLarMenu(menuService.apiScopeTreeKeys(roleIds));
 
         //表单
         List<WbsTableOwnerRole> wbsTableOwnerRoles = roleMapper.selectRoleAndTableOwnerListByRoleId(Long.valueOf(roleIds));

+ 1 - 1
blade-service/blade-system/src/main/java/org/springblade/system/controller/RoleController.java

@@ -187,7 +187,7 @@ public class RoleController extends BladeController {
     public R grant(@RequestBody GrantVO grantVO) {
         CacheUtil.clear(SYS_CACHE);
         CacheUtil.clear(SYS_CACHE, Boolean.FALSE);
-        boolean temp = roleService.grant(grantVO.getRoleIds(), grantVO.getMenuIds(), grantVO.getMenuClientIds(), grantVO.getDataScopeIds(), grantVO.getApiScopeIds(), grantVO.getTableOwners(), grantVO.getMenuArchivesIds());
+        boolean temp = roleService.grant(grantVO.getRoleIds(), grantVO.getMenuIds(), grantVO.getMenuClientIds(), grantVO.getDataScopeIds(), grantVO.getApiScopeIds(), grantVO.getTableOwners(), grantVO.getMenuArchivesIds(), grantVO.getMenuHacIds(), grantVO.getMenularIds());
         return R.status(temp);
     }
 

+ 1 - 2
blade-service/blade-system/src/main/java/org/springblade/system/mapper/MenuMapper.xml

@@ -131,10 +131,9 @@
         from blade_menu a,
              blade_client b
         where a.is_deleted = 0
-          and a.category = 1
           and a.sys_id = b.id
           and b.client_id = #{sysType}
-          and a.is_show_button = 1
+          and (a.category = 1 or (a.is_show_button = 1 and a.category = 2))
     </select>
 
     <select id="roleMenu" resultMap="menuResultMap">

+ 1 - 1
blade-service/blade-system/src/main/java/org/springblade/system/service/IRoleService.java

@@ -64,7 +64,7 @@ public interface IRoleService extends IService<Role> {
      * @param apiScopeIds   接口权限id集合
      * @return 是否成功
      */
-    boolean grant(@NotEmpty List<Long> roleIds, List<String> menuIds, List<String> menuClientIds, List<Long> dataScopeIds, List<Long> apiScopeIds, List<Long> tableOwners, List<String> menuArchivesIds);
+    boolean grant(@NotEmpty List<Long> roleIds, List<String> menuIds, List<String> menuClientIds, List<Long> dataScopeIds, List<Long> apiScopeIds, List<Long> tableOwners, List<String> menuArchivesIds, List<String> menuHacIds, List<String> menuLarIds);
 
     /**
      * 获取角色ID

+ 23 - 4
blade-service/blade-system/src/main/java/org/springblade/system/service/impl/RoleServiceImpl.java

@@ -87,11 +87,11 @@ public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IR
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public boolean grant(@NotEmpty List<Long> roleIds, List<String> menuIds, List<String> menuClientIds, List<Long> dataScopeIds, List<Long> apiScopeIds, List<Long> tableOwners, List<String> menuArchivesIds) {
-        return grantRoleMenu(roleIds, menuIds, menuClientIds, menuArchivesIds) && grantDataScope(roleIds, dataScopeIds) && grantApiScope(roleIds, apiScopeIds) && submitRoleAndTableOwner(roleIds, tableOwners);
+    public boolean grant(@NotEmpty List<Long> roleIds, List<String> menuIds, List<String> menuClientIds, List<Long> dataScopeIds, List<Long> apiScopeIds, List<Long> tableOwners, List<String> menuArchivesIds, List<String> menuHacIds, List<String> menuLarIds) {
+        return grantRoleMenu(roleIds, menuIds, menuClientIds, menuArchivesIds, menuHacIds, menuLarIds) && grantDataScope(roleIds, dataScopeIds) && grantApiScope(roleIds, apiScopeIds) && submitRoleAndTableOwner(roleIds, tableOwners);
     }
 
-    private boolean grantRoleMenu(List<Long> roleIds, List<String> menuIds, List<String> menuClientIds, List<String> menuArchivesIds) {
+    private boolean grantRoleMenu(List<Long> roleIds, List<String> menuIds, List<String> menuClientIds, List<String> menuArchivesIds, List<String> menuHacIds, List<String> menuLarIds) {
         // 防止越权配置超管角色
         Long administratorCount = baseMapper.selectCount(Wrappers.<Role>query().lambda().eq(Role::getRoleAlias, RoleConstant.ADMINISTRATOR).in(Role::getId, roleIds));
         if (!AuthUtil.isAdministrator() && administratorCount > 0L) {
@@ -133,6 +133,24 @@ public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IR
             roleMenus.add(roleMenu);
         }));
 
+        // 组装配置-内控
+        roleIds.forEach(roleId -> menuHacIds.forEach(menuIdC -> {
+            RoleMenu roleMenu = new RoleMenu();
+            roleMenu.setRoleId(roleId);
+            roleMenu.setMenuId(Long.valueOf(menuIdC.split("---")[0]));
+            roleMenu.setStatus(menuIdC.split("---")[1]);
+            roleMenus.add(roleMenu);
+        }));
+
+        // 组装配置-征拆
+        roleIds.forEach(roleId -> menuLarIds.forEach(menuIdC -> {
+            RoleMenu roleMenu = new RoleMenu();
+            roleMenu.setRoleId(roleId);
+            roleMenu.setMenuId(Long.valueOf(menuIdC.split("---")[0]));
+            roleMenu.setStatus(menuIdC.split("---")[1]);
+            roleMenus.add(roleMenu);
+        }));
+
         // 新增配置
         roleMenuService.saveBatch(roleMenus);
 
@@ -140,7 +158,8 @@ public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IR
         recursionRoleMenu(roleIds, menuIds);
         recursionRoleMenu(roleIds, menuClientIds);
         recursionRoleMenu(roleIds, menuArchivesIds);
-
+        recursionRoleMenu(roleIds, menuHacIds); //内控
+        recursionRoleMenu(roleIds, menuLarIds); //征拆
         return true;
     }