package org.jeecg.modules.doc.controller; import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.xkcoding.http.util.StringUtil; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.collections.map.HashedMap; import org.apache.shiro.SecurityUtils; import org.jeecg.common.api.vo.Result; import org.jeecg.common.aspect.annotation.AutoLog; import org.jeecg.common.constant.CacheConstant; import org.jeecg.common.system.vo.LoginUser; import org.jeecg.common.util.DateUtils; import org.jeecg.common.util.IPUtils; import org.jeecg.common.util.RedisUtil; import org.jeecg.modules.doc.api.JeecgSystemClient; import org.jeecg.modules.doc.component.DocFileDealComp; import org.jeecg.modules.doc.component.PathFileUtil; import org.jeecg.modules.doc.component.PathPermissionComp; import org.jeecg.modules.doc.component.UfopConfig; import org.jeecg.modules.doc.constant.Constant; import org.jeecg.modules.doc.dto.*; import org.jeecg.modules.doc.entity.*; import org.jeecg.modules.doc.service.*; import org.jeecg.modules.doc.vo.CompareFileVo; import org.jeecg.modules.doc.vo.DocTree; import org.jeecg.modules.doc.exception.QiwenException; import org.jeecg.modules.doc.vo.QiwenFile; import org.jetbrains.annotations.NotNull; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.FileCopyUtils; import org.springframework.web.bind.annotation.*; import lombok.extern.slf4j.Slf4j; import javax.print.Doc; import javax.servlet.http.HttpServletRequest; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.*; import java.util.stream.Collectors; @RestController @RequestMapping("/document") @Api("文档管理") @ApiOperation("文件管理") @Slf4j public class LbDocController { @Autowired private UfopConfig ufopConfig; @Autowired private ILbDocService lbDocService; @Autowired private DocFileDealComp fileDealComp; @Autowired private IDocFilePathService filePathService; @Autowired private IDocFileService docFileService; @Autowired private PathPermissionComp pathPermissionComp; @Autowired private IUserStorageFlowService userStorageFlowService; @Autowired private JeecgSystemClient jeecgSystemClient; @Autowired private IDocOperationHisService operationHisService; @Autowired private RedisUtil redisUtil; @ApiOperation( "本地目录树") @GetMapping(value = "/docTree") public List queryPageList(DocTree docTree) { System.out.println("开始:: " + System.currentTimeMillis()); if (docTree.getPath() == null || "".equals(docTree.getPath())){ docTree.setPath(ufopConfig.getReleasePath()); docTree.setKey("0-0"); } docTree = lbDocService.genDocTree( docTree ); System.out.println("结束::" + System.currentTimeMillis()); return docTree.getChildren(); } @AutoLog(value = "初始化同步本地目录") @ApiOperation("初始化同步本地目录") @GetMapping("/init") public void initDoc() { System.out.println("开始初始化:::" + System.currentTimeMillis()); List pathList = filePathService.list( new LambdaQueryWrapper() // .likeRight(DocFilePath::getFilePath,"/工作文件区/01 公共区域") // .likeRight(DocFilePath::getFilePath,"/工作文件区/02 3D视觉事业部") // .likeRight(DocFilePath::getFilePath,"/工作文件区/03 研发二部") // .likeRight(DocFilePath::getFilePath,"/工作文件区/04 研发三部") // .likeRight(DocFilePath::getFilePath,"/工作文件区/05 开发一部") // .likeRight(DocFilePath::getFilePath,"/工作文件区/06 开发二部") // .likeRight(DocFilePath::getFilePath,"/工作文件区/07 开发三部") // .likeRight(DocFilePath::getFilePath,"/工作文件区/08 工业设计部") // .likeRight(DocFilePath::getFilePath,"/工作文件区/09 研发管理部") // .likeRight(DocFilePath::getFilePath,"/工作文件区/10 兰浦公司") .likeRight(DocFilePath::getFilePath,"/档案资料区") ); Map paths = new HashMap<>(); pathList.stream().forEach(item -> { // if (item.getFileName().contains("20171201技术体系文件标准化管理制度V1")) { // System.out.println("["+item.getFilePath()+item.getFileName()+(item.getExtendName().isEmpty()?"":item.getExtendName())+item.getIsDir()+"]"); // } paths.put(item.getFilePath()+item.getFileName()+(item.getExtendName().isEmpty()?"":item.getExtendName())+item.getIsDir(), item.getPathId()); }); System.out.println("当前已有:" + paths.size()); String releasePath = ufopConfig.getReleasePath(); //filePathService.initDocFilePath(); lbDocService.initDoc(paths, releasePath, null); System.out.println("初始化完成:::" + System.currentTimeMillis()); } @AutoLog(value = "初始化同步本地目录结构") @ApiOperation("初始化同步本地目录结构") @GetMapping("/initDir") public void initDir() { System.out.println("开始初始化:::" + System.currentTimeMillis()); List pathList = filePathService.list(new LambdaQueryWrapper().eq(DocFilePath::getIsDir, 1)); // String releasePath = ufopConfig.getReleasePath(); // // Map paths = new HashMap<>(); // pathList.stream().forEach(item -> { // paths.put(item.getFilePath()+item.getFileName()+(item.getExtendName().isEmpty()?"":item.getExtendName())+item.getIsDir(), item.getPathId()); // }); // // System.out.println("当前已有:" + paths.size()); // List filePaths = new ArrayList<>(); // // lbDocService.initDir(paths,filePaths,releasePath, null); // System.out.println("文件夹有:" + filePaths.size()); // filePathService.saveOrUpdateBatch(filePaths); // System.out.println("初始化完成:::" + System.currentTimeMillis()); // // filePaths = null; // pathList = filePathService.list(); Map dirMap = new HashMap<>(); pathList.stream().forEach(item -> { if (item.isDirectory()) { if (item.getFilePath().endsWith("/")) { dirMap.put(item.getFilePath()+item.getFileName(), item.getPathId()); } else { dirMap.put(item.getFilePath()+"/"+item.getFileName(), item.getPathId()); } } }); System.out.println("文件夹map准备完成::" + System.currentTimeMillis()); List newList = new ArrayList<>(); pathList.stream().forEach(item -> { if ( item.getParentId() == null || !item.getParentId().equals(dirMap.get(item.getFilePath()))) { item.setParentId(dirMap.get(item.getFilePath())); newList.add(item); } }); System.out.println("文件夹排序完成::" + System.currentTimeMillis()); System.out.println("发现有问题目录:" + newList.size() +"个"); filePathService.saveOrUpdateBatch(newList); System.out.println("更新完成::" + System.currentTimeMillis()); } // @AutoLog(value = "检测文件是否损坏") // @ApiOperation("检测文件是否损坏") // @GetMapping("/checkFile") // public void checkFile() { // String filePath ="//192.168.0.9/研发技术文档"; // // lbDocService.checkFile(filePath); // } // // // // @AutoLog(value = "检测文件是否损坏") // @ApiOperation("检测文件是否损坏") // @GetMapping("/checkFileIsExist") // public void checkFileIsExist() { // List list = docFileService.list(); // String dir = "//192.168.0.9/研发技术文档"; // List upids = new ArrayList<>(); // list.forEach(file -> { // String fileurl = file.getFileUrl().replace("upload", dir); // File ff = new File(fileurl); // // if(!ff.exists()) { // file.setFileStatus(0); // upids.add(file); // // System.out.println(file.getFileId()); // } // }); // System.out.println("待更新个数:"+upids.size()); // docFileService.updateBatchById(upids); // System.out.println("完成++++"); // // } @AutoLog(value = "获取同步目标文件个数") @ApiOperation("获取同步目标文件个数") @GetMapping("/initDocSize") public void initDocSize() { Map map = new HashedMap(); map.put("dsize", 0L); map.put("fsize", 0L); String releasePath = ufopConfig.getReleasePath(); lbDocService.initDocSize(map,releasePath,null); System.out.println("文件总数:" + map.get("fsize")); System.out.println("文件夹总数:" + map.get("dsize")); System.out.println("总个数:" +(map.get("fsize")+map.get("dsize"))); } /** * 获取完整目录树 * @return */ @ApiOperation(value = "获取目录结构树", notes = "左侧目录树") @GetMapping("/getFileTree") public Map getFileTree() { System.out.println("获取目录树::" + LocalDateTime.now().toString()); // 获取访问集合 Set visits = pathPermissionComp.getVisible(); Map map = new HashMap<>(); // 查询有访问权限的文件列表 List pathList = filePathService.listDirTree(null, visits); // 查询有访问权限的文件下的子文件 LambdaQueryWrapper subQueryWrapper = new LambdaQueryWrapper<>(); subQueryWrapper.eq(DocFilePath::getIsDir, Constant.IS_DIR) .eq(DocFilePath::getDeleteFlag, Constant.DEL_FALSE) .and(i -> { i.apply("{0} = {1}",1,2); // 无具体意义,方便后边拼接 pathList.stream().forEach(path -> { i.or().likeRight(DocFilePath::getFilePath,new QiwenFile(path.getFilePath(),path.getFileName(),true).getPath()); }); }); List subList = filePathService.list(subQueryWrapper); System.out.println("查询完成::" + LocalDateTime.now()); pathList.addAll(subList); DocTree resultTreeNode = getResultTreeNode(pathList); map.put("success", true); map.put("result", resultTreeNode); System.out.println("获取完成:::" + LocalDateTime.now()); return map; } /** * 异步获取目录树 * @param parent 父级目录 * @return */ @ApiOperation(value = "异步获取目录结构树", notes = "异步获取左侧目录树") @GetMapping("/getAsyncTree") public Map getAsyncTree(DocTreeDTO parent ){ Map map = new HashMap<>(); // 访问、下载、管理权限包 Map> pathPermission = pathPermissionComp.getPathPermission(); // 拥有访问权限的文件id集合 Map visits = pathPermission.get(Constant.VISIT); //DocTree parent = new DocTree(); DocTree tree = getDocTree(parent, visits, map); map.put("success", true); map.put("result", tree); return map; } /** * 根据传过来的上级方件组织异步树的下级文件列表 * @param parent 上级文件 * @param visits 可访问文件列表 * @param map 返回前端对象 * @return */ @NotNull private DocTree getDocTree(DocTreeDTO parent, Map visits, Map map) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); if (parent.getPathId() == null) { queryWrapper.isNull(DocFilePath::getParentId); parent.setTitle("全部文件"); parent.setPath(QiwenFile.separator); parent.setId(0L); parent.setKey("0"); parent.setPathId("1"); parent.setTargetId("1"); } else if ("1".equals(parent.getPathId())) { queryWrapper.isNull(DocFilePath::getParentId); } else { queryWrapper.eq(DocFilePath::getParentId, parent.getPathId()); } queryWrapper.eq(DocFilePath::getDeleteFlag, Constant.DEL_FALSE) .eq(DocFilePath::getIsDir, Constant.IS_DIR); // 注释掉后同时查询文件夹和文件 queryWrapper.orderByAsc(DocFilePath::getFileName); List trees = new ArrayList<>(); List list = filePathService.list(queryWrapper); // 当前查询结果中可访问的文件集合 list = list.stream().filter( i -> visits.get(i.getPathId())!=null || fileDealComp.isParentsOrChild(visits,i, true) ).collect(Collectors.toList()); String[] fileIds = new String[list.size()]; for (int i=0; i< list.size(); i++) { fileIds[i] = list.get(i).getPathId(); trees.add(new DocTree(list.get(i), parent.getKey()+ "-" + i)); } setIsLeaf(trees, fileIds); DocTree tree = new DocTree(parent); tree.getChildren().addAll(trees); // 点击收藏列表递归查询,直到找到目标文件 if (!tree.getPathId().equals(parent.getTargetId()) ) { for (DocTree i: tree.getChildren() ) { if (i.getPathId().equals(parent.getTargetId())||parent.getPath().startsWith(i.getPath()+QiwenFile.separator)) { DocTreeDTO docTreeDTO = new DocTreeDTO(i); docTreeDTO.setTargetId(parent.getTargetId()); docTreeDTO.setPath(parent.getPath()); DocTree docTree = this.getDocTree(docTreeDTO, visits, map); i.setChildren(docTree.getChildren()); } } } else { map.put("target", tree); } return tree; } /** * 判断是否子节点 * @param trees * @param fileIds */ private void setIsLeaf(List trees, String[] fileIds) { List> subCount = fileIds.length>0? filePathService.querySubCount(fileIds): new ArrayList<>(); Map subMap = subCount.stream().collect(Collectors.toMap(i->i.get("parentId").toString(), i-> new Integer( i.get("num").toString()))); trees.stream().forEach(t -> { if (subMap.get(t.getPathId())!=null &&subMap.get(t.getPathId())>0) { t.setLeaf(false); } else { t.setLeaf(true); } }); } @NotNull private DocTree getResultTreeNode(List pathList) { DocTree resultTreeNode = new DocTree(); resultTreeNode.setTitle("全部文件"); resultTreeNode.setPath(QiwenFile.separator); resultTreeNode.setId(0L); resultTreeNode.setKey("0"); resultTreeNode.setPathId("1"); long id = 1; for (int i = 0; i < pathList.size(); i++){ DocFilePath userFile = pathList.get(i); QiwenFile qiwenFile = new QiwenFile(userFile.getFilePath(), userFile.getFileName(), false); String filePath = qiwenFile.getPath(); Queue queue = new LinkedList<>(); String[] strArr = filePath.split(QiwenFile.separator); for (int j = 0; j < strArr.length; j++){ if (!"".equals(strArr[j]) && strArr[j] != null){ queue.add(strArr[j]); } } if (queue.size() == 0){ continue; } resultTreeNode = fileDealComp.insertTreeNode(resultTreeNode, id++, QiwenFile.separator, queue, userFile.getPathId()); } System.out.println("组织树完成::" + LocalDateTime.now()); fileDealComp.sortByKey(resultTreeNode); fileDealComp.checkLeaf(resultTreeNode); return resultTreeNode; } @ApiOperation(value = "获取目录结构树列表", notes = "用于分配文件夹权限") @GetMapping("/queryTreeList") public Result> queryTreeList(DocFilePath docFilePath) { Result> result = new Result<>(); List pathList = filePathService.listDirTree(docFilePath,null); List ids = pathList.stream().map(DocFilePath::getPathId).collect(Collectors.toList()); Map map = new HashMap<>(); DocTree resultTreeNode = getResultTreeNode(pathList); map.put("treeList", resultTreeNode.getChildren()); map.put("ids",ids); result.setSuccess(true); result.setResult(map); return result; } @ApiOperation(value = "获取异步目录结构树列表", notes = "用于分配文件夹权限") @GetMapping("/queryAsyncTreeList") public Result> queryAsyncTreeList(DocTreeDTO parent) { Result> result = new Result<>(); LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); if (parent.getFileName()!=null && parent.getFileName().trim().length()>0) { queryWrapper.like(DocFilePath::getFileName, parent.getTitle()); } else { if (parent.getPathId() == null) { queryWrapper.isNull(DocFilePath::getParentId); parent.setTitle("全部文件"); parent.setPath(QiwenFile.separator); parent.setId(0L); parent.setKey("0"); parent.setPathId("1"); } else { queryWrapper.eq(DocFilePath::getParentId, parent.getPathId()); } } queryWrapper.eq(DocFilePath::getDeleteFlag, Constant.DEL_FALSE) .eq(DocFilePath::getIsDir, Constant.IS_DIR); queryWrapper.orderByDesc(DocFilePath::getIsDir).orderByAsc(DocFilePath::getFileName); List trees = new ArrayList<>(); List list = filePathService.list(queryWrapper); String[] fileIds = new String[list.size()]; for (int i=0; i< list.size(); i++) { fileIds[i] = list.get(i).getPathId(); trees.add(new DocTree(list.get(i), parent.getKey()+ "-" + i)); } setIsLeaf(trees,fileIds); List ids = list.stream().map(DocFilePath::getPathId).collect(Collectors.toList()); Map map = new HashMap<>(); //DocTree resultTreeNode = getResultTreeNode(pathList); map.put("treeList", trees); map.put("ids",ids); result.setSuccess(true); result.setResult(map); return result; } /** * 点击目录树节点,查询前端主界面文件列表内容 * @param path * @return */ @ApiOperation("根据路径查询文件列表") @GetMapping("/listFile") public Map queryFileList(String path, String pathId) { QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.lambda().eq(DocFilePath::getFilePath,path) .eq(DocFilePath::getDeleteFlag,Constant.DEL_FALSE) .orderByDesc(DocFilePath::getIsDir); // .orderBy(DocFilePath::getFileName + 0) queryWrapper.orderByAsc("((file_name + 0) > 0) desc, (file_name + 0) asc,file_name"); //.orderByAsc(DocFilePath::getFileName); // boolean create = filePathService.selectPermissionByPath(pathId); Map listFileResult = getListFileResult(queryWrapper, pathId); // listFileResult.put("create", create); return listFileResult; } /** * 根据传递过来的sql条件,查询文件夹下的子目录 或 文件搜索 * TODO 待返回当前点击节点的权限,用于判断新建文件夹和上传文件及上传文件夹权限 * TODO 需要查询子文件没有权限但下级子文件有权限的文件夹显示问题。全局文件搜索不需要此操作。 * @param queryWrapper * @return */ @NotNull private Map getListFileResult(QueryWrapper queryWrapper, String pathId) { Map result = new HashMap<>(); List filePaths = filePathService.list(queryWrapper); // 访问、下载、管理权限包 Map> pathPermission = pathPermissionComp.getPathPermission(); // 拥有访问权限的文件id集合 Map visits = pathPermission.get(Constant.VISIT); // 拥有下载权限的文件id集合 Map downloads = pathPermission.get(Constant.DOWNLOAD); // 拥有管理权限的文件id集合 Map manages = pathPermission.get(Constant.MANAGE); // 当前查询结果中可访问的文件集合 filePaths = filePaths.stream().filter( i -> visits.get(i.getPathId())!=null || fileDealComp.isParentsOrChild(visits,i, true) ).collect(Collectors.toList()); Set downloadSet = filePaths.stream().filter( i -> downloads.get(i.getPathId()) != null || fileDealComp.isParentsOrChild(downloads,i, false) ).map(DocFilePath::getPathId).collect(Collectors.toSet()); Set manageSet = filePaths.stream().filter( i -> manages.get(i.getPathId()) != null || fileDealComp.isParentsOrChild(manages,i, false) ).map(DocFilePath::getPathId).collect(Collectors.toSet()); // 是文件需要查询文件大小 Set fileIds = filePaths.stream() .filter(docFilePath -> docFilePath.getFileId()!=null&&!"".equals(docFilePath.getFileId())) .map(docFilePath -> docFilePath.getFileId()) .collect(Collectors.toSet()); if (fileIds.size()>0) { // 查询文件大小 List files = docFileService.list(new LambdaQueryWrapper().in(DocFile::getFileId,fileIds)); Map sizeMap = files.stream().collect(Collectors.toMap(DocFile::getFileId,DocFile::getFileSize)); filePaths.stream().forEach(p -> p.setFileSize(sizeMap.get(p.getFileId()))); } result.put("create", filePathService.selectPermissionByPath(pathId, manages)); result.put("upload", filePathService.selectPermissionByPath(pathId, downloads)); result.put("success", true); result.put("result", filePaths); result.put("downloadPrem", downloadSet); result.put("managePrem", manageSet); return result; } @ApiOperation("根据名称模糊搜索文件列表") @GetMapping("/searchFile") public Map searchFileList(String name) { QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.lambda().like(DocFilePath::getFileName,name) .eq(DocFilePath::getDeleteFlag,Constant.DEL_FALSE) .orderByDesc(DocFilePath::getIsDir); //.orderByAsc(DocFilePath::getFileName); queryWrapper.orderByAsc("((file_name + 0) > 0) desc, (file_name + 0) asc,file_name"); return getListFileResult(queryWrapper, null); } @ApiOperation("创建文件") @PostMapping("createFile") public Result createFile(@RequestBody DocFilePath docFilePath, HttpServletRequest request) { LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); boolean isDirExist = fileDealComp.isDirExist(docFilePath.getFileName(), docFilePath.getFilePath(), docFilePath.getIsDir()); if (isDirExist) { return Result.error("同名文件已存在"); } DocFilePath parent = fileDealComp.getParent(docFilePath.getFilePath()); DocFilePath filePath = PathFileUtil.getDir(docFilePath.getFilePath(), docFilePath.getFileName(), parent); filePathService.save(filePath); operationHisService.saveHis(loginUser,docFilePath,Constant.OPERATION_CREATE); return Result.OK(); } @ApiOperation("创建文件") @PostMapping("test") public Result test(@RequestBody DocFilePath docFilePath, HttpServletRequest request) { LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); // boolean isDirExist = fileDealComp.isDirExist(docFilePath.getFileName(), docFilePath.getFilePath(), docFilePath.getIsDir()); // // if (isDirExist) { // return Result.error("同名文件已存在"); // } // DocFilePath parent = fileDealComp.getParent(docFilePath.getFilePath()); // DocFilePath filePath = PathFileUtil.getDir(docFilePath.getFilePath(), docFilePath.getFileName(), parent); // filePathService.save(filePath); // // operationHisService.saveHis(loginUser,docFilePath,Constant.OPERATION_CREATE); return Result.OK(); } @ApiOperation(value = "修改文件", notes = "支持普通文本类文件的修改", tags = {"file"}) @RequestMapping(value = "/update", method = RequestMethod.POST) public Result updateFile(@RequestBody UpdateFileDTO updateFileDTO) { LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); //JwtUser sessionUserBean = SessionUtil.getSession(); // 获取路径文件 DocFilePath userFile = filePathService.getById(updateFileDTO.getUserFileId()); // 获取目标文件 DocFile fileBean = docFileService.getById(userFile.getFileId()); // 目标文件被引用数 Long pointCount = docFileService.getFilePointCount(userFile.getFileId()); String fileUrl = fileBean.getFileUrl(); if (pointCount > 1) { fileUrl = fileDealComp.copyFile(fileBean, userFile); } String content = updateFileDTO.getFileContent(); ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(content.getBytes()); try { long fileSize = byteArrayInputStream.available(); fileDealComp.saveFileInputStream( fileUrl, byteArrayInputStream); String md5Str = fileDealComp.getIdentifierByFile(fileUrl, 0); docFileService.updateFileDetail(userFile.getPathId(), md5Str, fileSize, loginUser.getId()); } catch (Exception e) { throw new QiwenException(999999, "修改文件异常"); } finally { try { byteArrayInputStream.close(); } catch (IOException e) { e.printStackTrace(); } } operationHisService.saveHis(loginUser, userFile, Constant.OPERATION_UPDATE); return Result.OK("修改文件成功"); } @ApiOperation(value = "批量删除文件", notes = "批量删除文件", tags = {"file"}) @RequestMapping(value = "/batchdeletefile", method = RequestMethod.POST) public Result deleteImageByIds(@RequestBody BatchDeleteFileDTO batchDeleteFileDto) { System.out.println("批量删除文件:::" + LocalDateTime.now().toString()); LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); List userFiles = JSON.parseArray(batchDeleteFileDto.getFiles(), DocFilePath.class); DigestUtils.md5Hex("data"); for (DocFilePath userFile : userFiles) { filePathService.deleteUserFile(userFile.getPathId(),loginUser.getId()); operationHisService.saveHis(loginUser,userFile,Constant.OPERATION_DELETE); //fileDealComp.deleteESByUserFileId(userFile.getPathId()); } // 删除reids中缓存的 CacheConstant.DOC_FILE_PATH_CACHE 下的所有key redisUtil.removeAll(CacheConstant.DOC_FILE_PATH_CACHE); return Result.OK("批量删除文件成功"); } @ApiOperation(value = "删除文件", notes = "可以删除文件或者目录", tags = {"file"}) @RequestMapping(value = "/deletefile", method = RequestMethod.POST) public Result deleteFile(@RequestBody DeleteFileDTO deleteFileDto) { System.out.println("删除文件:::" + LocalDateTime.now().toString()); LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); DocFilePath byId = filePathService.getById(deleteFileDto.getUserFileId()); filePathService.deleteUserFile(deleteFileDto.getUserFileId(), loginUser.getId()); //fileDealComp.deleteESByUserFileId(deleteFileDto.getUserFileId()); System.out.println("删除完成:::" + LocalDateTime.now().toString()); operationHisService.saveHis(loginUser,byId,Constant.OPERATION_DELETE); // 删除reids中缓存的 CacheConstant.DOC_FILE_PATH_CACHE 下的所有key redisUtil.removeAll(CacheConstant.DOC_FILE_PATH_CACHE); return Result.OK(); } @ApiOperation(value = "文件重命名", notes = "文件重命名", tags = {"file"}) @RequestMapping(value = "/renamefile", method = RequestMethod.POST) public Result renameFile(@RequestBody RenameFileDTO renameFileDto) { LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); //JwtUser sessionUserBean = SessionUtil.getSession(); DocFilePath userFile = filePathService.getById(renameFileDto.getUserFileId()); List userFiles = filePathService.selectUserFileByNameAndPath(renameFileDto.getFileName(), userFile.getFilePath(), loginUser.getId()); if (userFiles != null && !userFiles.isEmpty()) { return Result.error("同名文件已存在", null); } LambdaUpdateWrapper lambdaUpdateWrapper = new LambdaUpdateWrapper<>(); lambdaUpdateWrapper.set(DocFilePath::getFileName, renameFileDto.getFileName()) .set(DocFilePath::getUpdateTime, DateUtils.getDate()) .eq(DocFilePath::getPathId, renameFileDto.getUserFileId()); filePathService.update(lambdaUpdateWrapper); if (Constant.IS_DIR == userFile.getIsDir()) { List list = filePathService.selectUserFileByLikeRightFilePath(new QiwenFile(userFile.getFilePath(), userFile.getFileName(), true).getPath()); for (DocFilePath newUserFile : list) { newUserFile.setFilePath(newUserFile.getFilePath().replaceFirst(new QiwenFile(userFile.getFilePath(), userFile.getFileName(), userFile.getIsDir() == Constant.IS_DIR).getPath().replace("(","\\(").replace(")","\\)"), new QiwenFile(userFile.getFilePath(), renameFileDto.getFileName(), userFile.getIsDir() == Constant.IS_DIR).getPath())); filePathService.updateById(newUserFile); } } // fileDealComp.uploadESByUserFileId(renameFileDto.getUserFileId()); operationHisService.saveHis(loginUser, userFile, Constant.OPERATION_RENAME); return Result.OK(); } @ApiOperation(value = "解压文件", notes = "解压文件。", tags = {"file"}) @RequestMapping(value = "/unzipfile", method = RequestMethod.POST) public Result unzipFile(@RequestBody UnzipFileDTO unzipFileDto) { LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); try { DocFilePath byId = filePathService.getById(unzipFileDto.getUserFileId()); docFileService.unzipFile(unzipFileDto.getUserFileId(), unzipFileDto.getUnzipMode(), unzipFileDto.getFilePath()); operationHisService.saveHis(loginUser, byId, Constant.OPERATION_UNZIP); } catch (QiwenException e) { return Result.error(e.getMessage(),null); } return Result.OK(); } @ApiOperation(value = "文件复制", notes = "可以复制文件或者目录", tags = {"file"}) @RequestMapping(value = "/copyfile", method = RequestMethod.POST) public Result copyFile(@RequestBody CopyFileDTO copyFileDTO) { LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); //JwtUser sessionUserBean = SessionUtil.getSession(); String userFileId = copyFileDTO.getUserFileId(); DocFilePath userFile = filePathService.getById(userFileId); String oldfilePath = userFile.getFilePath(); String newfilePath = copyFileDTO.getFilePath(); String fileName = userFile.getFileName(); if (userFile.getIsDir() == Constant.IS_DIR) { QiwenFile qiwenFile = new QiwenFile(oldfilePath, fileName, true); if (newfilePath.startsWith(qiwenFile.getPath() + QiwenFile.separator) || newfilePath.equals(qiwenFile.getPath())) { return Result.error("原路径与目标路径冲突,不能复制",null); } } filePathService.userFileCopy(userFileId, newfilePath); fileDealComp.deleteRepeatSubDirFile(newfilePath); operationHisService.saveHis(loginUser, userFile, Constant.OPERATION_COPY); return Result.OK(); } @ApiOperation(value = "批量复制文件", notes = "可以同时选择复制多个文件或者目录", tags = {"file"}) @RequestMapping(value = "/batchcopyfile", method = RequestMethod.POST) public Result batchCopyFile(@RequestBody BatchMoveFileDTO batchMoveFileDto) { LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); //JwtUser sessionUserBean = SessionUtil.getSession(); String files = batchMoveFileDto.getFiles(); String newfilePath = batchMoveFileDto.getFilePath(); List fileList = JSON.parseArray(files, DocFilePath.class); for (DocFilePath userFile : fileList) { if (StringUtil.isEmpty(userFile.getExtendName())) { QiwenFile qiwenFile = new QiwenFile(userFile.getFilePath(), userFile.getFileName(), true); if (newfilePath.startsWith(qiwenFile.getPath() + QiwenFile.separator) || newfilePath.equals(qiwenFile.getPath())) { return Result.error("原路径与目标路径冲突,不能复制",null); } } filePathService.userFileCopy(userFile.getPathId(), newfilePath); operationHisService.saveHis(loginUser, userFile, Constant.OPERATION_COPY); } return Result.OK("批量复制文件成功"); } @ApiOperation(value = "文件移动", notes = "可以移动文件或者目录", tags = {"file"}) @RequestMapping(value = "/movefile", method = RequestMethod.POST) public Result moveFile(@RequestBody MoveFileDTO moveFileDto) { LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); //JwtUser sessionUserBean = SessionUtil.getSession(); DocFilePath userFile = filePathService.getById(moveFileDto.getUserFileId()); String oldfilePath = userFile.getFilePath(); String newfilePath = moveFileDto.getFilePath(); String fileName = userFile.getFileName(); String extendName = userFile.getExtendName(); if (StringUtil.isEmpty(extendName)) { QiwenFile qiwenFile = new QiwenFile(oldfilePath, fileName, true); if (newfilePath.startsWith(qiwenFile.getPath() + QiwenFile.separator) || newfilePath.equals(qiwenFile.getPath())) { return Result.error("原路径与目标路径冲突,不能移动",null); } } try { filePathService.updateFilepathByUserFileId(moveFileDto.getUserFileId(), newfilePath); fileDealComp.deleteRepeatSubDirFile(newfilePath); } catch (Exception e) { e.printStackTrace(); } operationHisService.saveHis(loginUser, userFile, Constant.OPERATION_MOVE); return Result.OK(); } @ApiOperation(value = "批量移动文件", notes = "可以同时选择移动多个文件或者目录", tags = {"file"}) @RequestMapping(value = "/batchmovefile", method = RequestMethod.POST) public Result batchMoveFile(@RequestBody BatchMoveFileDTO batchMoveFileDto) { LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); //JwtUser sessionUserBean = SessionUtil.getSession(); String files = batchMoveFileDto.getFiles(); String newfilePath = batchMoveFileDto.getFilePath(); List fileList = JSON.parseArray(files, DocFilePath.class); for (DocFilePath userFile : fileList) { if (StringUtil.isEmpty(userFile.getExtendName())) { QiwenFile qiwenFile = new QiwenFile(userFile.getFilePath(), userFile.getFileName(), true); if (newfilePath.startsWith(qiwenFile.getPath() + QiwenFile.separator) || newfilePath.equals(qiwenFile.getPath())) { return Result.error("原路径与目标路径冲突,不能移动",null); } } filePathService.updateFilepathByUserFileId(userFile.getPathId(), newfilePath); operationHisService.saveHis(loginUser, userFile, Constant.OPERATION_MOVE); } return Result.OK("批量移动文件成功"); } @ApiOperation(value = "查询限额", notes = "获取个人下载限额及使用情况", tags = {"file"}) @GetMapping("/loadFlow") public Result loadFlow() { LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); LambdaQueryWrapper qw = new LambdaQueryWrapper<>(); qw.eq(UserStorageFlow::getUserId, loginUser.getId()); UserStorageFlow userStorageFlow = userStorageFlowService.getOne(qw); if (userStorageFlow != null && userStorageFlow.getFlow() != null) { // 用户单独设置过限额 } else { // 未单独设置限额的取所有角色限额最大值 Result> roles = jeecgSystemClient.queryUserRole(loginUser.getId()); if (roles.getResult() == null || roles.getResult().size()<=0) {return Result.error("未设置限额", null);} qw = new LambdaQueryWrapper<>(); qw.in(UserStorageFlow::getRoleId, roles.getResult()); qw.isNotNull(UserStorageFlow::getFlow); qw.orderByDesc(UserStorageFlow::getFlow).last("limit 1"); UserStorageFlow one = userStorageFlowService.getOne(qw); if (userStorageFlow == null) { userStorageFlow = new UserStorageFlow(); userStorageFlow.setUserId(loginUser.getId()); userStorageFlow.setSurplusFlow(0L); userStorageFlowService.save(userStorageFlow); } if (one != null) { userStorageFlow.setFlow(one.getFlow()); } } if (userStorageFlow.getSurplusFlow() == null) { userStorageFlow.setSurplusFlow(0L); } return Result.OK(userStorageFlow); } @ApiOperation(value = "文件夹内文件总大小", notes = "查询文件夹内文件总大小", tags = {"file"}) @GetMapping("/getSubFileSize") public Result querySubFileSize(DocFilePath docFilePath) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); QiwenFile qiwenFile = new QiwenFile(docFilePath.getFilePath(),docFilePath.getFileName(),docFilePath.isDirectory()); queryWrapper.likeRight(DocFilePath::getFilePath,qiwenFile.getPath()); queryWrapper.isNotNull(DocFilePath::getFileId); List docFilePaths = filePathService.list(queryWrapper); BigDecimal total = queryTotalSize(docFilePaths); return Result.OK(total); } /** * 查询传入文件列表的总大小 * @param docFilePaths * @return */ private BigDecimal queryTotalSize(List docFilePaths) { // 所有文件id集合 List fileIds = docFilePaths.stream().map(DocFilePath::getFileId).collect(Collectors.toList()); // 查询出文件大小之和 QueryWrapper fileQueryWrapper = new QueryWrapper<>(); fileQueryWrapper.select("IFNULL(sum(file_size),0) as totalSize"); fileQueryWrapper.lambda().in(DocFile::getFileId, fileIds); Map map = docFileService.getMap(fileQueryWrapper); BigDecimal total = (BigDecimal) map.get("totalSize"); return total; } @ApiOperation(value = "多选文件总大小", notes = "多选文件大小总和", tags = {"file"}) @GetMapping("/getBatchFileSize") public Result queryBatchFileSize(BatchDownloadFileDTO batchDownloadFileDTO) { // 查询出所有选择的文件 LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); String[] ids = batchDownloadFileDTO.getUserFileIds().split(","); queryWrapper.in(DocFilePath::getPathId,ids); List batchFiles = filePathService.list(queryWrapper); // 查询出选择的文件夹内的子文件 LambdaQueryWrapper subQueryWrapper = new LambdaQueryWrapper<>(); subQueryWrapper.isNotNull(DocFilePath::getFileId); subQueryWrapper.and( i -> { i.apply("{0} = {1}", 1,2); for (DocFilePath d: batchFiles) { if (d.isDirectory()) { QiwenFile qiwenFile = new QiwenFile(d.getFilePath(),d.getFileName(),d.isDirectory()); i.or().likeRight(DocFilePath::getFilePath,qiwenFile.getPath()); } } }); List docFilePaths = filePathService.list(subQueryWrapper); docFilePaths.addAll(batchFiles); // 所有文件id集合 BigDecimal total = queryTotalSize(docFilePaths); return Result.OK(total); } // @ApiOperation(value = "查询文件详情", notes = "查询文件详情", tags = {"file"}) // @RequestMapping(value = "/detail", method = RequestMethod.GET) // @ResponseBody // public RestResult queryFileDetail( // @Parameter(description = "用户文件Id", required = true) String userFileId){ // FileDetailVO vo = fileService.getFileDetail(userFileId); // return RestResult.success().data(vo); // } @GetMapping("/heapSize") public Result getHeap() { double maxHeapSize = Runtime.getRuntime().maxMemory(); String sizeInReadableForm; double kbSize = maxHeapSize / 1024; double mbSize = kbSize / 1024; double gbSize = mbSize / 1024; if (gbSize > 0) { sizeInReadableForm = gbSize + " GB"; } else if (mbSize > 0) { sizeInReadableForm = mbSize + " MB"; } else { sizeInReadableForm = kbSize + " KB"; } return Result.OK(maxHeapSize); } @ApiOperation( value = "文件对比", notes = "文件对比") @PostMapping("/compareFile") public Result compareFile( UploadFileDTO uploadFileDto) { CompareFileVo compareFileVo = lbDocService.compareFile( uploadFileDto); return Result.OK(compareFileVo); } }