package com.artfess.file.controller; import com.artfess.base.annotation.ApiGroup; import com.artfess.base.constants.ApiGroupConsts; import com.artfess.base.context.BaseContext; import com.artfess.base.controller.BaseController; import com.artfess.base.enums.ResponseErrorEnums; import com.artfess.base.exception.BaseException; import com.artfess.base.exception.NotFoundException; import com.artfess.base.feign.UCFeignService; import com.artfess.base.feign.WorkflowFeignService; import com.artfess.base.groovy.GroovyScriptEngine; import com.artfess.base.handler.MultiTenantHandler; import com.artfess.base.handler.MultiTenantIgnoreResult; import com.artfess.base.model.CommonResult; import com.artfess.base.query.PageList; import com.artfess.base.query.QueryField; import com.artfess.base.query.QueryFilter; import com.artfess.base.query.QueryOP; import com.artfess.base.util.Base64; import com.artfess.base.util.BeanUtils; import com.artfess.base.util.FileUtil; import com.artfess.base.util.JsonUtil; import com.artfess.base.util.StringUtil; import com.artfess.base.util.UniqueIdUtil; import com.artfess.base.util.time.DateUtil; import com.artfess.file.config.UploadResult; import com.artfess.file.extend.DetailTablePolicy; import com.artfess.file.extend.InstanceFlowOpinions; import com.artfess.file.model.DefaultFile; import com.artfess.file.model.FileZone; import com.artfess.file.persistence.manager.CatalogManager; import com.artfess.file.persistence.manager.FileManager; import com.artfess.file.persistence.manager.FileZoneManager; import com.artfess.file.util.AppFileUtil; import com.artfess.file.util.HtmlUtil; import com.artfess.file.util.SignaturePictureRenderPolicy; import com.artfess.file.util.UploadM3u8; import com.artfess.file.vo.FileReqVo; import com.artfess.file.vo.MultipartCompleteParam; import com.artfess.file.vo.MultipartInitParam; import com.artfess.file.vo.MultipartInitRespVo; import com.artfess.sysConfig.util.SysPropertyUtil; import com.artfess.uc.api.model.IUser; import com.artfess.uc.api.service.IUserService; import com.deepoove.poi.XWPFTemplate; import com.deepoove.poi.config.Configure; import com.deepoove.poi.config.Configure.ELMode; import com.deepoove.poi.data.DocxRenderData; import com.deepoove.poi.template.MetaTemplate; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.util.DigestUtils; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartHttpServletRequest; import javax.activation.MimetypesFileTypeMap; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.RandomAccessFile; import java.net.URLEncoder; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.concurrent.atomic.AtomicBoolean; @RestController @RequestMapping("/file/v1") @Api(tags = "附件管理") @ApiGroup(group = {ApiGroupConsts.GROUP_SYSTEM}) @SuppressWarnings({"unchecked", "rawtypes"}) public class FileController extends BaseController { private Logger logger = LoggerFactory.getLogger(FileController.class); @Resource FileManager fileManager; @Resource IUserService userService; @Resource CatalogManager catalogManager; @Resource FileZoneManager fileZonedManager; @Resource BaseContext baseContext; @Resource WorkflowFeignService workflowFeignService; @Resource GroovyScriptEngine groovyScriptEngine; @Resource UCFeignService ucFeignService; @RequestMapping(value = "list", method = RequestMethod.POST, produces = {"application/json; charset=utf-8"}) @ApiOperation(value = "附件列表(分页条件查询)数据", httpMethod = "POST", notes = "附件列表(分页条件查询)数据") public PageList list( @ApiParam(name = "queryFilter", value = "通用查询对象") @RequestBody QueryFilter queryFilter) { List listQueryField = queryFilter.getQuerys(); List listId = new ArrayList<>(); QueryField query = new QueryField(); String xbTypeId = ""; for (QueryField queryField : listQueryField) { if ("xbTypeId".equals(queryField.getProperty())) { xbTypeId = queryField.getValue() + ""; query.setProperty(queryField.getProperty()); query.setRelation(queryField.getRelation()); listQueryField.remove(queryField); break; } } if (StringUtil.isNotEmpty(xbTypeId)) { List ids = catalogManager.getDepartmentList(xbTypeId, listId); ids.add(xbTypeId); query.setValue(ids); query.setOperation(QueryOP.IN); listQueryField.add(query); queryFilter.setQuerys(listQueryField); } return fileManager.query(queryFilter); } @PostMapping(value = "getFileInfo", produces = {"application/json; charset=utf-8"}) @ApiOperation(value = "根据附件类型和业务id获得附件对象", notes = "获得附件对象") public DefaultFile getFileInfo(@RequestBody FileReqVo fileReqVo) { DefaultFile file = fileManager.getFileInfo(fileReqVo); return file; } @RequestMapping(value = "fileGet", method = RequestMethod.GET, produces = {"application/json; charset=utf-8"}) @ApiOperation(value = "获得附件对象", httpMethod = "GET", notes = "获得附件对象") public DefaultFile edit(@ApiParam(name = "id", value = "主键") @RequestParam String id) { DefaultFile file = null; if (StringUtil.isNotEmpty(id)) { file = fileManager.get(id); } return file; } @RequestMapping(value = "remove", method = RequestMethod.POST, produces = {"application/json; charset=utf-8"}) @ApiOperation(value = "批量删除附件", httpMethod = "POST", notes = "批量删除附件") public CommonResult remove(@ApiParam(name = "ids", value = "附件ID!多个ID用,分割") @RequestBody String ids) throws Exception { String[] aryIds = null; if (StringUtil.isNotEmpty(ids)) { aryIds = ids.split(","); } fileManager.delSysFileByIds(aryIds); return new CommonResult(true, "删除附件成功", null); } @RequestMapping(value = "uploadFileForConfig", method = RequestMethod.POST, produces = {"application/json; charset=utf-8"}) @ApiOperation(value = "批量附件上传操作", httpMethod = "POST", notes = "批量附件上传操作") public UploadResult uploadForConfig(@ApiParam(name = "bizCode", value = "附件上传编码", required = true) @RequestParam String bizCode, @ApiParam(name = "bizId", value = "业务ID", required = false) @RequestParam String bizId, @ApiParam(name = "bizType", value = "业务分类,业务内部的类别", required = false) @RequestParam String bizType, @ApiParam(name = "files", value = "上传的文件流") @RequestBody List files) throws Exception { DefaultFile file = new DefaultFile(); String account = baseContext.getCurrentUserAccout(); return fileManager.UploadFileForConfig(file, files, bizCode, bizId, bizType, userService.getUserByAccount(account)); } @RequestMapping(value = "fileUpload", method = RequestMethod.POST, produces = {"application/json; charset=utf-8"}) @ApiOperation(value = "附件上传操作", httpMethod = "POST", notes = "附件上传操作,minio参数:file: {\"storeType\":\"minio\"}") public UploadResult fileUpload(@ApiParam(name = "params", value = "格式限定") @RequestParam Map params, @ApiParam(name = "files", value = "上传的文件流") @RequestBody List files, @ApiParam(name = "flowKey", value = "流程key") @RequestParam Optional flowKey) throws Exception { DefaultFile file = new DefaultFile(); if (params.containsKey("file")) { file = JsonUtil.toBean(params.getOrDefault("file", "{}").toString(), DefaultFile.class); } String account = baseContext.getCurrentUserAccout(); return fileManager.uploadFile(file, files, params.getOrDefault("fileFormates", "").toString(), userService.getUserByAccount(account), flowKey.orElse("")); } @RequestMapping(value = "upload", method = RequestMethod.POST, produces = {"application/json; charset=utf-8"}) @ApiOperation(value = "附件上传操作", httpMethod = "POST", notes = "附件上传操作") public UploadResult upload(MultipartHttpServletRequest request, @ApiParam(name = "fileFormates", value = "格式要求,多个用逗号隔开") @RequestParam Optional fileFormates, @ApiParam(name = "flowKey", value = "流程key") @RequestParam Optional flowKey, @ApiParam(name = "fileId", value = "文件id") @RequestParam(required = false) String fileId) throws Exception { IUser user = null; String account = baseContext.getCurrentUserAccout(); if (StringUtil.isNotEmpty(account)) { user = userService.getUserByAccount(account); } Map fileMaps = request.getFileMap(); Iterator it = fileMaps.values().iterator(); List files = new ArrayList(); while (it.hasNext()) { files.add(it.next()); } DefaultFile file = new DefaultFile(); if (StringUtil.isNotEmpty(fileId)) { file = fileManager.get(fileId); //设文件名称为null,保存时不检查名称 file.setFileName(null); } return fileManager.uploadFile(file, files, fileFormates.orElse(""), user, flowKey.orElse("")); } @RequestMapping(value = "downloadFile", method = RequestMethod.GET, produces = {"application/json; charset=utf-8"}) @ApiOperation(value = "附件下载", httpMethod = "GET", notes = "附件下载") public void downloadFile(HttpServletRequest request, HttpServletResponse response, @ApiParam(name = "fileId", value = "附件ID") @RequestParam String fileId) throws Exception { // response.reset(); response.setContentType("APPLICATION/OCTET-STREAM"); DefaultFile file = null; try (MultiTenantIgnoreResult setThreadLocalIgnore = MultiTenantHandler.setThreadLocalIgnore()) { file = fileManager.get(fileId); } if (BeanUtils.isEmpty(file)) { throw new NotFoundException(String.format("未找到fileId为: %s 的文件", fileId)); } String fileName = file.getFileName() + "." + file.getExtensionName(); String filedisplay = URLEncoder.encode(fileName, "utf-8"); response.setHeader("Access-Control-Expose-Headers", "Content-Disposition"); response.addHeader("Content-Disposition", "attachment;filename=" + filedisplay); response.addHeader("filename", filedisplay); response.setHeader("Access-Control-Allow-Origin", "*"); String type = new MimetypesFileTypeMap().getContentType(new File(file.getFilePath())); response.setContentType(type); fileManager.downloadFile(fileId, response.getOutputStream()); } @RequestMapping(value = "getLogoFile", method = RequestMethod.GET, produces = { "application/json; charset=utf-8"}) @ApiOperation(value = "获取租户logo文件", httpMethod = "GET", notes = "根据租户id获取租户logo文件") public void getLogoFile(HttpServletRequest request, HttpServletResponse response, @ApiParam(name = "tenantId", value = "租户id") @RequestParam String tenantId, @ApiParam(name = "logoType", value = "logo类型:manage(管理端)、front(应用端)") @RequestParam String logoType) throws Exception { response.setContentType("APPLICATION/OCTET-STREAM"); DefaultFile file = null; JsonNode tenantNode = ucFeignService.getTenantById(tenantId); String logoTypeField = "manageLogo"; if ("front".equals(logoType)) { logoTypeField = "frontLogo"; } ArrayNode logoNode = (ArrayNode) JsonUtil.toJsonNode(tenantNode.get(logoTypeField).asText()); String fileId = logoNode.get(0).get("id").asText(); file = fileManager.get(fileId); if (BeanUtils.isEmpty(file)) { throw new NotFoundException(String.format("未找到fileId为: %s 的文件", fileId)); } String fileName = file.getFileName() + "." + file.getExtensionName(); String filedisplay = URLEncoder.encode(fileName, "utf-8"); response.addHeader("Content-Disposition", "attachment;filename=" + filedisplay); response.addHeader("filename", filedisplay); response.setHeader("Access-Control-Allow-Origin", "*"); String type = new MimetypesFileTypeMap().getContentType(new File(file.getFilePath())); response.setContentType(type); fileManager.downloadFile(fileId, response.getOutputStream()); } @RequestMapping(value = "getFileType", method = RequestMethod.POST, produces = { "application/json; charset=utf-8"}) @ApiOperation(value = "根据附件id取得附件类型。", httpMethod = "POST", notes = "根据附件id取得附件类型。") public String getFileType(@ApiParam(name = "fileId", value = "附件id") @RequestBody String fileId) throws IOException { DefaultFile DefaultFile = null; String type = "doc"; if (StringUtil.isNotEmpty(fileId)) { DefaultFile = fileManager.get(fileId); type = DefaultFile.getExtensionName().toLowerCase(); } return type; } @RequestMapping(value = "setXbTypeId", method = RequestMethod.POST, produces = { "application/json; charset=utf-8"}) @ApiOperation(value = "修改附件分类。", httpMethod = "POST", notes = "修改附件分类。") public CommonResult setXbTypeId(@ApiParam(name = "fileId", value = "附件id") @RequestBody List fileId, @ApiParam(name = "xbTypeId", value = "分类ID") @RequestParam String xbTypeId, @ApiParam(name = "type", value = "分类名称") @RequestParam String type) throws Exception { fileManager.setXbTypeId(fileId, xbTypeId, type); return new CommonResult(true, "设置附件分类成功", null); } @RequestMapping(value = "updateFileExtraProp", method = RequestMethod.POST, produces = { "application/json; charset=utf-8"}) @ApiOperation(value = "更新附件的属性成功", httpMethod = "POST", notes = "更新附件的属性成功(包含扩展属性、流程实例ID、节点名称、流程标题、附件来源、所属分类)") public CommonResult updateFileExtraProp( @ApiParam(name = "files", value = "附件列表") @RequestBody List files) throws Exception { fileManager.updateFileExtraProp(files); return new CommonResult(true, "更新附件的属性成功", null); } @RequestMapping(value = "preview", method = RequestMethod.GET, produces = {"application/json; charset=utf-8"}) @ApiOperation(value = "附件预览", httpMethod = "GET", notes = "附件预览") public void preview(HttpServletRequest request, HttpServletResponse response, @ApiParam(name = "fileId", value = "附件ID") @RequestParam String fileId) throws Exception { // response.reset(); try (MultiTenantIgnoreResult setThreadLocalIgnore = MultiTenantHandler.setThreadLocalIgnore()) { response.setContentType("text/html; charset=UTF-8"); response.setContentType("image/jpeg"); DefaultFile file = null; file = fileManager.get(fileId); if (BeanUtils.isEmpty(file)) { return; } String fileName = file.getFileName() + "." + file.getExtensionName(); String filedisplay = fileName; String agent = request.getHeader("USER-AGENT"); if (agent != null && agent.indexOf("MSIE") == -1 && agent.indexOf("Trident") == -1) { filedisplay = "=?UTF-8?B?" + (new String(Base64.getBase64(filedisplay))) + "?="; } else { filedisplay = URLEncoder.encode(filedisplay, "utf-8"); } response.addHeader("filename", filedisplay); response.setHeader("Access-Control-Allow-Origin", "*"); fileManager.downloadFile(fileId, response.getOutputStream()); } catch (Exception e) { logger.error("预览附件失败"); } } @RequestMapping(value = "wordPrint", method = RequestMethod.POST, produces = {"application/json; charset=utf-8"}) @ApiOperation(value = "word模板打印", httpMethod = "POST", notes = "word模板打印") public String wordPrint(@ApiParam(name = "objectNode", value = "Json对象") @RequestBody ObjectNode objectNode) throws Exception { String boData = objectNode.get("boData").toString(); String fileId = objectNode.get("fileId").asText(); String subject = objectNode.get("subject").asText(); ArrayNode flowOpinions = (ArrayNode) objectNode.get("flowOpinions"); String scriptStr = objectNode.get("scriptStr").asText(); DefaultFile defaultFile = fileManager.get(fileId); DefaultFile model = new DefaultFile(); model.setId(UniqueIdUtil.getSuid()); String outputFilePath = AppFileUtil .createFilePath("print" + File.separator + baseContext.getCurrentUserAccout(), model.getId() + "." + defaultFile.getExtensionName()); String saveOutputFilePath = this.printFile(boData, defaultFile, outputFilePath, flowOpinions, scriptStr, model.getId()); // 新增打印记录 try { if (flowOpinions.size() > 0) { String defId = objectNode.get("defId").asText(); String nodeId = objectNode.get("nodeId").asText(); ObjectNode opinion = (ObjectNode) flowOpinions.get(0); ObjectNode record = JsonUtil.getMapper().createObjectNode(); record.put("procInstId", opinion.get("procInstId").asText());// procInstId record.put("nodeId", nodeId); record.put("procDefId", defId); record.put("formKey", objectNode.get("formKey").asText()); record.put("templateId", fileId); record.put("templateName", defaultFile.getFileName()); record.put("fileId", model.getId()); workflowFeignService.addPrintLog(record); } } catch (Exception e) { System.out.println("新增打印记录失败:" + e.getMessage()); } model.setFileName(subject); model.setStoreType(AppFileUtil.getSaveType("")); model.setFilePath(outputFilePath.replace(AppFileUtil.getAttachPath() + File.separator, "")); model.setExtensionName(defaultFile.getExtensionName()); model.setIsDel((short) 0); model.setCreateTime(DateUtil.getCurrentDate()); if (!model.getStoreType().equals(DefaultFile.SAVE_TYPE_FOLDER)) { fileManager.uploadFile(model, new FileInputStream(saveOutputFilePath)); } else { fileManager.create(model); } return model.getId(); } private String printFile(String boData, DefaultFile defaultFile, String outputFilePath, ArrayNode flowOpinions, String scriptStr, String fileId) throws Exception { Map boMap = new HashMap(); Map twiceMap = new HashMap(); AtomicBoolean isSubHtml = new AtomicBoolean(false); // 配置 Configure config = Configure.newBuilder().setElMode(ELMode.SPEL_MODE).setValidErrorHandler(new Configure.ClearHandler()).build(); JsonUtil.toMap(boData).values().forEach(item -> { ((Map) item).forEach((key, val) -> { Object printObj = val;//模板支持Sping表达式之后1对1子表套打有问题 if (key.toString().startsWith("sub_")) { if (HtmlUtil.isHtml(printObj.toString())) { isSubHtml.set(true); } if (val instanceof List && ((List) val).size() == 1) { Map subMapKey = (Map) ((List) val).get(0); printObj = subMapKey; } config.customPolicy(key.toString(), new DetailTablePolicy()); } boMap.put(key, printObj); if (HtmlUtil.isHtml(printObj.toString())) {//如果是富文本,则套打子文档 handRichtext(key.toString(), val.toString(), boMap); } else if (BeanUtils.isNotEmpty(val)) {//判断是否签章和图片,如果是则进行特殊套打 HtmlUtil.printPicture(key.toString(), printObj.toString(), boMap, twiceMap); } }); }); config.customPolicy("flowOpinions", new InstanceFlowOpinions()); boMap.put("flowOpinions", flowOpinions); String filePath = defaultFile.getFilePath(); String fullPath = StringUtil.trimSufffix(AppFileUtil.getAttachPath(), File.separator) + File.separator + filePath.replace("/", File.separator); outputFilePath = StringUtil.trimSufffix(AppFileUtil.getAttachPath(), File.separator) + outputFilePath.replace("/", File.separator); String[] paths = outputFilePath.split(fileId); if (paths.length > 1) { if (!FileUtil.isExistFile(paths[0])) { FileUtil.createFolder(paths[0], false); } } // 在生成word前先执行脚本,用于替换打印的值(比如实际值为1或者2,想显示的值为男与女,用java 脚本进行判断处理) if (StringUtil.isNotEmpty(scriptStr)) { Map params = new HashMap(); params.put("boMap", boMap); params.putAll(boMap); groovyScriptEngine.executeString(scriptStr, params); } //如果是ftp存储,需要先从ftp下载文件到磁盘目录 if (!new File(fullPath).exists()) { fileManager.downloadFileToPath(defaultFile, fullPath); } XWPFTemplate template = XWPFTemplate.compile(fullPath, config); //处理模板中存在富文本标识,但是富文本值为空的情况 List templates = template.getElementTemplates(); for (MetaTemplate metaTemplate : templates) { String code = metaTemplate.variable(); if (code.startsWith("{{+")) { code = code.replaceAll("\\{", ""); code = code.replaceAll("\\+", ""); code = code.replaceAll("\\}", ""); if (BeanUtils.isEmpty(boMap.get(code))) { handRichtext(code, "", boMap); } } } template.render(boMap); FileOutputStream out = new FileOutputStream(outputFilePath); template.write(out); out.flush(); out.close(); template.close(); if (isSubHtml.get()) {//如果子表里面有富文本 再次套打 Configure subConfig = Configure.newBuilder().setElMode(ELMode.SPEL_MODE).build(); XWPFTemplate template2 = XWPFTemplate.compile(outputFilePath, subConfig).render(boMap); FileOutputStream out2 = new FileOutputStream(outputFilePath); template2.write(out2); out2.flush(); out2.close(); template2.close(); } if (!twiceMap.isEmpty()) { //签章图片用#作为标示符(仅在二次套打中使用) Configure twiceConfig = Configure.newBuilder().setElMode(ELMode.SPEL_MODE).addPlugin('#', new SignaturePictureRenderPolicy()).build(); XWPFTemplate template2 = XWPFTemplate.compile(outputFilePath, twiceConfig).render(twiceMap); FileOutputStream out2 = new FileOutputStream(outputFilePath); template2.write(out2); out2.flush(); out2.close(); template2.close(); } return outputFilePath; } /** * 富文本套打处理 * * @param key * @param boMap */ private void handRichtext(String key, String text, Map boMap) { if (boMap.get(key) instanceof List) { List subList = (List) boMap.get(key); subList.forEach(subMap -> { subMap.forEach((subKey, subValue) -> { if (HtmlUtil.isHtml(subValue.toString())) { File docxFile = HtmlUtil.getRichtextToDocx(subValue.toString()); subMap.put(subKey, new DocxRenderData(docxFile)); if (docxFile != null && docxFile.exists()) { docxFile.delete(); } } }); }); } else if (boMap.get(key) instanceof Map) { Map subMap = (Map) boMap.get(key); subMap.forEach((subKey, subValue) -> { if (HtmlUtil.isHtml(subValue.toString())) { File docxFile = HtmlUtil.getRichtextToDocx(subValue.toString()); subMap.put(subKey, new DocxRenderData(docxFile)); if (docxFile != null && docxFile.exists()) { docxFile.delete(); } } }); } else { File docxFile = HtmlUtil.getRichtextToDocx(text); boMap.put(key, new DocxRenderData(docxFile)); //删除临时docx文件 if (docxFile != null && docxFile.exists()) { docxFile.delete(); } } } @RequestMapping(value = "getFileBytesById", method = RequestMethod.GET, produces = { "application/json; charset=utf-8"}) @ApiOperation(value = "附件下载", httpMethod = "GET", notes = "附件下载") public byte[] getFileBytesById(@ApiParam(name = "fileId", value = "附件ID") @RequestParam String fileId) throws Exception { return fileManager.getFileBytesById(fileId); } @RequestMapping(value = "/importSignature", method = RequestMethod.POST, produces = {"application/json; charset=utf-8"}) @ApiOperation(value = "批量导入签章", httpMethod = "POST", notes = "批量导入签章") public CommonResult importSignature(@ApiParam(name = "file", value = "导入的压缩文件(.zip或.rar)", required = true) @RequestBody MultipartFile file, @ApiParam(name = "repeatConver", value = "当用户已存在签章时是否覆盖", required = false) @RequestParam Optional repeatConver) throws Exception { return fileManager.importSignature(file, repeatConver.orElse(true)); } @ApiOperation(value = "分片初始化", httpMethod = "POST", notes = "分片上传,分片大小为10兆") @PostMapping("init") public CommonResult initMultiPartUpload(@RequestBody MultipartInitParam requestParam) { MultipartInitRespVo multipartInitBO = fileManager.initMultiPartUpload(requestParam); if (Objects.nonNull(multipartInitBO)) { return CommonResult.success(multipartInitBO, null); } else { throw new BaseException("分片初始化失败!"); } } @ApiOperation(value = "分片上传", httpMethod = "POST", notes = "由uploadId和chunk查到minio生成的分片url, 上传文件part到minio") @PostMapping("/chunkUpload") public CommonResult chunkUpload(@RequestPart("file") MultipartFile file, @RequestParam("uploadId") String uploadId, @RequestParam("chunk") String chunk) { boolean status = fileManager.chunkUpload(file, uploadId, chunk); return CommonResult.success(status, null); } @ApiOperation(value = "完成上传", httpMethod = "POST", notes = "当所有分片上传接口返回200后,调用此方法,合并分片(minio文件服务器合并),完成上传。") @PostMapping("completeUpload") public CommonResult completeMultiPartUpload(@RequestBody MultipartCompleteParam param) { UploadResult uploadResult = fileManager.mergeMultipartUpload(param); return CommonResult.success(uploadResult, null); } @ApiOperation(value = "测试视屏转M3U8") @GetMapping("uploadVideoToM3U8") public CommonResult uploadVideoToM3U8(String fileId) { UploadM3u8 uploadM3u8 = new UploadM3u8(); DefaultFile defaultFile = fileManager.get(fileId); String s = uploadM3u8.uploadVideoToM3U8(defaultFile); return CommonResult.success(s, null); } }