package com.doc.biz.controller; import com.aspose.pdf.Document; import com.aspose.pdf.SaveFormat; import com.doc.biz.domain.*; import com.doc.biz.service.*; import com.doc.biz.vo.DocumentVO; import com.doc.biz.vo.UserVO; import com.doc.common.annotation.Log; import com.doc.common.constant.Constants; import com.doc.common.core.controller.BaseController; import com.doc.common.core.domain.AjaxResult; import com.doc.common.core.domain.entity.SysUser; import com.doc.common.core.page.TableDataInfo; import com.doc.common.enums.BusinessType; import com.doc.common.enums.EventLevel; import com.doc.common.utils.SecurityUtils; import com.doc.common.utils.StringUtils; import com.doc.common.utils.bean.BeanUtils; import com.doc.common.utils.file.FileUtils; import com.doc.common.utils.poi.ExcelUtil; import com.doc.system.service.ISysUserService; import io.swagger.annotations.*; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpHeaders; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import org.yaml.snakeyaml.util.UriEncoder; import javax.annotation.Resource; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import java.io.InputStream; import java.util.*; /** * 文件基本信息表Controller * * @author wukai * @date 2023-08-15 */ @Api(tags = "文件基本信息表") @RestController @RequestMapping("/biz/info") @Slf4j public class DocInfoController extends BaseController { @Resource private IDocInfoService docInfoService; @Resource private IMongoService mongoService; @Resource private IDocDirService dirService; @Resource private IDocFavoriteService favoriteService; @Resource private IDocRecentService recentService; @Resource private IElasticSearchService elasticSearchService; @Resource private IDocInfoDelService delService; @Resource private IDocActorUserService actorUserService; @Resource private IDocDirUserService dirUserService; @Resource private ISysUserService userService; /** * 文件上传 * * @param file 文件 * @return 上传结果 */ @ApiOperation("文件上传-单文件") @Log(title = "文件基本信息表", businessType = BusinessType.INSERT, eventLevel = EventLevel.MIDDLE) @PostMapping("/upload") public AjaxResult uploadFile(@ApiParam(value = "文件", required = true) @RequestPart(value = "file") MultipartFile file, @ApiParam(value = "空间ID", required = true) @RequestParam Long spaceId, @ApiParam(value = "目录ID", required = true) @RequestParam Long dirId) { try { DocumentVO vo = mongoService.uploadFile(file); docInfoService.upload(vo, spaceId, dirId); return success(); } catch (Exception e) { log.error("文件上传失败:", e); return error(e.getMessage()); } } /** * 多文件上传 * * @param files 文件列表 * @return 返回 */ @ApiOperation("文件上传-多文件") @PostMapping("/uploadFiles") @Log(title = "文件基本信息表", businessType = BusinessType.INSERT, eventLevel = EventLevel.MIDDLE) public AjaxResult uploadFile(@ApiParam(value = "文件", required = true) @RequestPart(value = "files") List files, @ApiParam(value = "空间ID", required = true) @RequestParam Long spaceId, @ApiParam(value = "目录ID", required = true) @RequestParam Long dirId) { try { mongoService.uploadFiles(files).forEach(vo -> { docInfoService.upload(vo, spaceId, dirId); }); return success(); } catch (Exception e) { e.printStackTrace(); return error(e.getMessage()); } } /** * 新建文件 */ @ApiOperation("新建文件") @GetMapping("/create") @ApiImplicitParams({ @ApiImplicitParam(name = "type", value = "文件类型 \"word\":word文档 \"excel\":excel文件 \"ppt\":ppt文件 \"txt\":文本文件", required = true, dataTypeClass = Long.class), @ApiImplicitParam(name = "spaceId", value = "空间ID", required = true, dataTypeClass = Long.class), @ApiImplicitParam(name = "dirId", value = "目录ID", required = true, dataTypeClass = String.class), @ApiImplicitParam(name = "name", value = "文件名", required = true, dataTypeClass = String.class) }) @Log(title = "文件基本信息表", businessType = BusinessType.INSERT, eventLevel = EventLevel.MIDDLE) public AjaxResult create(Long spaceId, Long dirId, String type, String name) { try { String filePath = ""; String fileName = ""; switch (type) { case "word": filePath = "file/new.docx"; fileName = StringUtils.isNotEmpty(name) ? name + ".docx" : "新建word文档.docx"; break; case "excel": filePath = "file/new.xlsx"; fileName = StringUtils.isNotEmpty(name) ? name + ".xlsx" : "新建Excel文档.xlsx"; break; case "ppt": filePath = "file/new.pptx"; fileName = StringUtils.isNotEmpty(name) ? name + ".pptx" : "新建ppt文档.pptx"; break; case "txt": filePath = "file/new.txt"; fileName = StringUtils.isNotEmpty(name) ? name + ".txt" : "新建文本文档.txt"; break; } InputStream is = this.getClass().getResourceAsStream("/" + filePath); MultipartFile multipartFile = FileUtils.getMultipartFile(is, fileName); DocumentVO vo = mongoService.uploadFile(multipartFile); DocInfo docInfo = docInfoService.upload(vo, spaceId, dirId); return success(docInfo); } catch (Exception e) { log.error("新建文件出错啦:{}", e.getMessage()); return error("新建文件出错"); } } /** * 文件移动 */ @ApiOperation("文件移动") @GetMapping("/move") @Log(title = "文件基本信息表", businessType = BusinessType.UPDATE, eventLevel = EventLevel.MIDDLE) @ApiImplicitParams({@ApiImplicitParam(name = "docId", value = "文件ID", required = true, dataTypeClass = Long.class), @ApiImplicitParam(name = "spaceId", value = "空间ID", required = true, dataTypeClass = Long.class), @ApiImplicitParam(name = "dirId", value = "新目录ID", required = true, dataTypeClass = Long.class)}) public AjaxResult move(Long docId, Long dirId) { DocInfo info = docInfoService.selectDocInfoByDocId(docId); if (info == null) { return error("该文件已失效!"); } info.setDirId(dirId); info.setUpdateBy(SecurityUtils.getUsername()); docInfoService.updateDocInfo(info); return success(); } /** * 复制文件 */ @ApiOperation("文件复制") @GetMapping("/copy") @Log(title = "文件基本信息表", businessType = BusinessType.INSERT, eventLevel = EventLevel.MIDDLE) @ApiImplicitParams({@ApiImplicitParam(name = "docId", value = "文件ID", required = true, dataTypeClass = Long.class), @ApiImplicitParam(name = "spaceId", value = "空间ID", required = true, dataTypeClass = Long.class), @ApiImplicitParam(name = "dirId", value = "新目录ID", required = true, dataTypeClass = Long.class)}) public AjaxResult copy(Long docId, Long spaceId, Long dirId) { DocInfo info = docInfoService.selectDocInfoByDocId(docId); if (info == null) { return error("该文件已失效!"); } String ext = info.getFileType(); if (StringUtils.isNotEmpty(ext)) { //因为数据库存的是带 . 的,所以要先截取掉这个 . ext = ext.substring(1); if (Arrays.asList(Constants.ALLOW_EDIT).contains(ext)) { //判断是否 onlyoffice允许的可编辑文件格式,如果是,则需要复制一份,如果不是就不管 DocumentVO vo = mongoService.copy(info.getFileId()); info.setFileId(vo.getFileId()); } } info.setDocId(null); info.setSpaceId(spaceId); info.setDirId(dirId); info.setFileName(info.getFileName()); docInfoService.insertDocInfo(info); return success(info); } /** * 重命名 */ @ApiOperation("文件重命名") @GetMapping("/rename") @Log(title = "文件基本信息表", businessType = BusinessType.UPDATE, eventLevel = EventLevel.MIDDLE) @ApiImplicitParams({@ApiImplicitParam(name = "docId", value = "文件ID", required = true, dataTypeClass = Long.class), @ApiImplicitParam(name = "name", value = "新文件名", required = true, dataTypeClass = Long.class)}) public AjaxResult rename(Long docId, String name) { DocInfo info = new DocInfo(); info.setDocId(docId); info.setFileName(name); info.setUpdateBy(SecurityUtils.getUsername()); return success(docInfoService.updateDocInfo(info)); } /** * 查询文件基本信息表列表 */ // @ApiOperation("文件列表") //@PreAuthorize("@ss.hasPermi('biz:info:list')") @GetMapping("/list") public TableDataInfo list(DocInfo docInfo) { startPage(); List list = docInfoService.selectDocInfoList(docInfo); return getDataTable(list); } /** * 查询所有已失效的文件,就是mysql中有,mongo中没有的 */ @GetMapping("/lose") public AjaxResult list() { List docInfoList = docInfoService.selectLoseList(); return AjaxResult.success(docInfoList); } @GetMapping("/content/{docId}") @ApiOperation("根据ID查询文本内容") public AjaxResult content(@ApiParam(value = "文件ID", required = true) @PathVariable Long docId) { EsDocInfo info = elasticSearchService.getEsDocInfo(docId); return AjaxResult.success(info); } /** * 文件搜索 */ @ApiOperation("文件搜索") //@PreAuthorize("@ss.hasPermi('biz:info:list')") @GetMapping("/search") public TableDataInfo search(@ApiParam(value = "搜索关键字", required = true) @RequestParam String keyword, @ApiParam(value = "空间类型(1.公共 2.部门 3.个人 不传该参数则为全部)") String type) { Map temp = dirService.selectDirByUser(SecurityUtils.getUserId(), type); List dirList = (List) temp.get("dir"); List spaceList = (List) temp.get("space"); Map dirMap = new HashMap<>(16); Map spaceMap = new HashMap<>(16); List dirIds = new ArrayList<>(); dirList.forEach(dir -> { dirIds.add(dir.getDirId()); dirMap.put(dir.getDirId(), dir); }); DocInfo docInfo = new DocInfo(); spaceList.forEach(space -> { if (type != null && type.equals(space.getSpaceType())) { docInfo.setSpaceId(space.getSpaceId()); } spaceMap.put(space.getSpaceId(), space); }); docInfo.setFileName(keyword); if (dirIds.size() > 0) { Map map = new HashMap<>(4); map.put("dirIds", dirIds); docInfo.setParams(map); } startPage(); List list = docInfoService.selectDocInfoList(docInfo); list.forEach(info -> { info.setDir(dirMap.get(info.getDirId())); info.setSpace(spaceMap.get(info.getSpaceId())); }); return getDataTable(list); } /** * 查询文件基本信息表列表 */ @ApiOperation("根据目录ID查询文件列表") //@PreAuthorize("@ss.hasPermi('biz:info:list')") @GetMapping("/list/{dirId}") public TableDataInfo list4dir(@PathVariable("dirId") Long dirId) { startPage(); DocInfo docInfo = new DocInfo(); docInfo.setDirId(dirId); List list = docInfoService.selectDocInfoList(docInfo); return getDataTable(list); } /** * 导出文件基本信息表列表 */ // @ApiOperation("导出文件基本信息表列表") //@PreAuthorize("@ss.hasPermi('biz:info:export')") @Log(title = "文件基本信息表", businessType = BusinessType.EXPORT) @PostMapping("/export") public void export(HttpServletResponse response, DocInfo docInfo) { List list = docInfoService.selectDocInfoList(docInfo); ExcelUtil util = new ExcelUtil(DocInfo.class); util.exportExcel(response, list, "文件基本信息表数据"); } /** * 获取文件基本信息表详细信息 */ @ApiOperation("文件详细信息") //@PreAuthorize("@ss.hasPermi('biz:info:query')") @GetMapping(value = "/{docId}") public AjaxResult getInfo(@PathVariable("docId") Long docId) { return success(docInfoService.selectDocInfoByDocId(docId)); } /** * 新增文件基本信息表 */ // @ApiOperation("新增文件基本信息表") //@PreAuthorize("@ss.hasPermi('biz:info:add')") @Log(title = "文件基本信息表", businessType = BusinessType.INSERT, eventLevel = EventLevel.MIDDLE) @PostMapping public AjaxResult add(@RequestBody DocInfo docInfo) { return toAjax(docInfoService.insertDocInfo(docInfo)); } /** * 修改文件基本信息表 */ // @ApiOperation("修改文件基本信息表") //@PreAuthorize("@ss.hasPermi('biz:info:edit')") @Log(title = "文件基本信息表", businessType = BusinessType.UPDATE, eventLevel = EventLevel.MIDDLE) @PutMapping public AjaxResult edit(@RequestBody DocInfo docInfo) { docInfo.setUpdateBy(SecurityUtils.getUsername()); return toAjax(docInfoService.updateDocInfo(docInfo)); } /** * 删除文件基本信息表 */ @ApiOperation("文件删除") //@PreAuthorize("@ss.hasPermi('biz:info:remove')") @Log(title = "文件基本信息表", businessType = BusinessType.DELETE, eventLevel = EventLevel.MIDDLE) @DeleteMapping("/{docIds}") public AjaxResult remove(@PathVariable Long[] docIds) { List list = new ArrayList<>(); for (Long docId : docIds) { DocInfo info = docInfoService.selectDocInfoByDocId(docId); list.add(info); } int i = docInfoService.deleteDocInfoByDocIds(docIds); list.forEach(info -> { DocInfoDel del = new DocInfoDel(); del.setRemark(getUsername()); BeanUtils.copyProperties(info, del); delService.insertDocInfoDel(del); /**取消删除mongo try { //删除mongo记录 mongoService.removeFile(info.getFileId()); } catch (Exception ignored) { }*/ try { //删除es记录 elasticSearchService.delete(info.getDocId()); } catch (Exception ignored) { } //删除收藏记录 favoriteService.delete("N", info.getDocId()); //删除最近记录 recentService.delete("N", info.getDocId()); }); return toAjax(i); } /** * 文件下载 */ @ApiOperation("文件预览") @GetMapping("/access/{docId}") public ResponseEntity access(@PathVariable(name = "docId") Long docId) { DocInfo info = docInfoService.selectDocInfoByDocId(docId); //插入最近文件 DocRecent recent = new DocRecent(); recent.setIsFolder("N"); recent.setOwner(SecurityUtils.getUserId()); recent.setRelaId(info.getDocId()); recentService.insertDocRecent(recent); return mongoService.download(info.getFileId(), false); } @ApiOperation("使用该文档的人员") @GetMapping("/users/{docId}") public AjaxResult users(@PathVariable(name = "docId") Long docId) { DocInfo info = docInfoService.selectDocInfoByDocId(docId); List voList = new ArrayList<>(); String yes = "Y"; if (yes.equals(info.getIsActor())) { actorUserService.selectDocActorUserListByDocId(docId).forEach(u -> { UserVO vo = new UserVO(); vo.setUserId(u.getUserId()); vo.setUserName(u.getName()); SysUser user = userService.selectUserById(u.getUserId()); vo.setDeptName(user.getDept().getDeptName()); voList.add(vo); }); } else { DocDirUser dirUser = new DocDirUser(); dirUser.setDirId(info.getDirId()); dirUserService.selectDocDirUserList(dirUser).forEach(u -> { UserVO vo = new UserVO(); vo.setUserId(u.getUserId()); vo.setUserName(u.getUserName()); SysUser user = userService.selectUserById(u.getUserId()); vo.setDeptName(user.getDept().getDeptName()); voList.add(vo); }); ; // dirService. //TODO // } } return success(voList); } /** * 文件下载 */ @ApiOperation("文件下载") @GetMapping("/download/{docId}") public ResponseEntity download(@PathVariable(name = "docId") Long docId) { DocInfo info = docInfoService.selectDocInfoByDocId(docId); return mongoService.download(info.getFileId(), true); } @ApiOperation("pdf转word") @Log(title = "PDF转WORD", businessType = BusinessType.INSERT, eventLevel = EventLevel.MIDDLE) @PostMapping("/pdf2word") public void pdf2word(@ApiParam(value = "文件", required = true) @RequestPart(value = "file") MultipartFile file, HttpServletResponse response) { try (Document doc = new Document(file.getInputStream());) { write(doc, file.getOriginalFilename(), response); } catch (Exception e) { logger.error("Pdf 转 Word 失败{}", e.getMessage()); e.printStackTrace(); } } /** * 写入文件流 * * @param doc doc * @param fileName 文件流 * @param response res */ private void write(Document doc, String fileName, HttpServletResponse response) { try (ServletOutputStream os = response.getOutputStream();) { //doc是将要被转化的word文档 String disposition = "attachment; filename=\"" + UriEncoder.encode(fileName) + "\""; response.addHeader(HttpHeaders.CONTENT_DISPOSITION, disposition); response.addHeader(HttpHeaders.CONTENT_TYPE, "application/octet-stream"); response.setContentType("application/octet-stream"); //全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF, EPUB, XPS, SWF 相互转换 doc.save(os, SaveFormat.DocX); os.flush(); } catch (Exception e) { logger.error("Pdf 转 Word 失败{}", e.getMessage()); e.printStackTrace(); } } @ApiOperation("pdf转word") @Log(title = "PDF转WORD", businessType = BusinessType.INSERT, eventLevel = EventLevel.MIDDLE) @GetMapping("/pdf2word/{fileId}") public void pdf2word(@PathVariable(name = "fileId") String fileId, HttpServletResponse response) { DocumentVO vo = mongoService.downloadFile(fileId); try (Document doc = new Document(vo.getData())) { write(doc, vo.getFileName(), response); } catch (Exception e) { logger.error("Pdf 转 Word 失败{}", e.getMessage()); e.printStackTrace(); } } }