diff --git a/jeecg-module-main/src/main/java/org/jeecg/modules/kc/ktgl/controller/KcKetangbiaoController.java b/jeecg-module-main/src/main/java/org/jeecg/modules/kc/ktgl/controller/KcKetangbiaoController.java index 425c5d03..531b7368 100644 --- a/jeecg-module-main/src/main/java/org/jeecg/modules/kc/ktgl/controller/KcKetangbiaoController.java +++ b/jeecg-module-main/src/main/java/org/jeecg/modules/kc/ktgl/controller/KcKetangbiaoController.java @@ -241,6 +241,48 @@ public class KcKetangbiaoController extends JeecgController getBizPath(String rwbh, String xqxn, String wjlx, String kkdw, String kcmc, String skjs) { + Result r = new Result<>(); + if(StringUtils.isNotBlank(rwbh) && StringUtils.isNotBlank(xqxn) && StringUtils.isNotBlank(wjlx)) { + //根据任务编号查询80%数据 + QueryWrapper qw = new QueryWrapper<>(); + qw.last("limit 1"); + KcKetangbiao ketangbiao = kcKetangbiaoService.getOne(qw); + String sb = xqxn + "/" + + ketangbiao.getKkdw() + "/" + + ketangbiao.getKcmc() + "/" + + ketangbiao.getSkjs() + "/" + + wjlx; + r.setResult(sb); + }else{ + if(StringUtils.isNotBlank(xqxn) && StringUtils.isNotBlank(wjlx) && StringUtils.isNotBlank(kkdw) && StringUtils.isNotBlank(kcmc) && StringUtils.isNotBlank(skjs)){ + String sb = xqxn + "/" + + kkdw + "/" + + kcmc + "/" + + skjs + "/" + + wjlx; + r.setResult(sb); + }else{ + r.setSuccess(false); + r.setMessage("缺少关键参数"); + } + } + //rwbh + //xqxn + //学期学年不能为空 + //kkdw + //开课单位不能为空 + //kcmc + //课程名称不能为空 + //skjs + //授课教师不能为空 + //wjlx + //文件类型不能为空 + + return r; + } + /** * 添加 diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/CommonController.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/CommonController.java index e603b0b9..0983927d 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/CommonController.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/CommonController.java @@ -1,8 +1,16 @@ package org.jeecg.modules.system.controller; +import cn.hutool.core.io.FastByteArrayOutputStream; +import cn.hutool.core.io.FileUtil; +import cn.hutool.core.io.IoUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; +import lombok.Data; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.fileupload.FileItem; +import org.apache.commons.fileupload.disk.DiskFileItemFactory; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; import org.jeecg.common.api.vo.Result; import org.jeecg.common.constant.CommonConstant; import org.jeecg.common.constant.SymbolConstant; @@ -13,6 +21,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.http.server.ServletServerHttpRequest; import org.springframework.util.AntPathMatcher; @@ -20,6 +29,7 @@ import org.springframework.util.FileCopyUtils; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartHttpServletRequest; +import org.springframework.web.multipart.commons.CommonsMultipartFile; import org.springframework.web.servlet.HandlerMapping; import org.springframework.web.servlet.ModelAndView; @@ -27,7 +37,9 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.*; import java.net.URLDecoder; -import java.util.Map; +import java.nio.file.Files; +import java.util.*; +import java.util.stream.Collectors; /** *

@@ -77,7 +89,7 @@ public class CommonController { //LOWCOD-2580 sys/common/upload接口存在任意文件上传漏洞 if (oConvertUtils.isNotEmpty(bizPath)) { - if(bizPath.contains(SymbolConstant.SPOT_SINGLE_SLASH) || bizPath.contains(SymbolConstant.SPOT_DOUBLE_BACKSLASH)){ + if (bizPath.contains(SymbolConstant.SPOT_SINGLE_SLASH) || bizPath.contains(SymbolConstant.SPOT_DOUBLE_BACKSLASH)) { throw new JeecgBootException("上传目录bizPath,格式非法!"); } } @@ -85,6 +97,25 @@ public class CommonController { MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; // 获取上传文件对象 MultipartFile file = multipartRequest.getFile("file"); + + savePath = upload(bizPath, file); + if(oConvertUtils.isNotEmpty(savePath)){ + result.setMessage(savePath); + result.setSuccess(true); + }else { + result.setMessage("上传失败!"); + result.setSuccess(false); + } + return result; + } + /** + * 文件上传统一方法 + * @param request + * @param response + * @return + */ + public String upload(String bizPath, MultipartFile file) throws Exception { + String savePath = ""; if(oConvertUtils.isEmpty(bizPath)){ if(CommonConstant.UPLOAD_TYPE_OSS.equals(uploadType)){ //未指定目录,则用阿里云默认目录 upload @@ -122,14 +153,7 @@ public class CommonController { savePath = CommonUtils.upload(file, bizPath, uploadType); //update-end-author:taoyan date:20200814 for:文件上传改造 } - if(oConvertUtils.isNotEmpty(savePath)){ - result.setMessage(savePath); - result.setSuccess(true); - }else { - result.setMessage("上传失败!"); - result.setSuccess(false); - } - return result; + return savePath; } /** @@ -139,21 +163,35 @@ public class CommonController { * @return */ private String uploadLocal(MultipartFile mf,String bizPath){ + return uploadLocal(mf,null,bizPath); + } + + /** + * 本地文件上传 + * @param mf 文件 + * @param bizPath 自定义路径 + * @return + */ + private String uploadLocal(MultipartFile mf,String _fileName,String bizPath){ try { String ctxPath = uploadpath; - String fileName = null; + String fileName = _fileName; File file = new File(ctxPath + File.separator + bizPath + File.separator ); if (!file.exists()) { // 创建文件根目录 file.mkdirs(); } // 获取文件名 - String orgName = mf.getOriginalFilename(); - orgName = CommonUtils.getFileName(orgName); - if(orgName.indexOf(SymbolConstant.SPOT)!=-1){ - fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.lastIndexOf(".")); - }else{ - fileName = orgName+ "_" + System.currentTimeMillis(); + if(fileName == null){ + String orgName = mf.getOriginalFilename(); + if (orgName != null) { + orgName = CommonUtils.getFileName(orgName); + if(orgName.contains(SymbolConstant.SPOT)){ + fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.lastIndexOf(".")); + }else{ + fileName = orgName+ "_" + System.currentTimeMillis(); + } + } } String savePath = file.getPath() + File.separator + fileName; File savefile = new File(savePath); @@ -223,6 +261,185 @@ public class CommonController { // return result; // } + @Data + public static class SectionUploadData{ + private Integer chunkCount; + private String fileMd5; + private String biz; + private String fileName; + } + + //切片上传 + @PostMapping(value = "/sectionUpload/init") + public Result sectionUploadInit(@RequestBody SectionUploadData sectionUploadData) throws Exception { + log.info("初始化文件!"); + //创建文件 + Integer chunkCount = sectionUploadData.getChunkCount(); + String fileMd5 = sectionUploadData.getFileMd5(); + String fileName = sectionUploadData.getFileName(); + String bizPath = sectionUploadData.getBiz(); + if (oConvertUtils.isNotEmpty(bizPath)) { + if(bizPath.contains(SymbolConstant.SPOT_SINGLE_SLASH) || bizPath.contains(SymbolConstant.SPOT_DOUBLE_BACKSLASH)){ + throw new JeecgBootException("上传目录bizPath,格式非法!"); + } + } + + //创建一个空文件夹,里面有个文件信息 + String ctxPath = uploadpath; + File file = new File(ctxPath + File.separator + bizPath + File.separator + fileMd5 ); + if (!file.exists()) { + // 创建文件根目录 + file.mkdirs(); + } + + File fileInfo = new File(ctxPath + File.separator + bizPath + File.separator + fileMd5 + File.separator + "file.info" ); + FileUtil.writeUtf8String("fileMd5:" + fileMd5 + "\nchunkCount:" + chunkCount + "\nfileName:" + fileName,fileInfo); + return Result.OK("init ok"); + } + + @PostMapping(value = "/sectionUpload/upload") + public Result sectionUploadUpload(HttpServletRequest request, HttpServletResponse response) { + log.info("上传文件!"); + String bizPath = request.getParameter("biz"); + String fileMd5 = request.getParameter("fileMd5"); + String partNumber = request.getParameter("partNumber"); + + //LOWCOD-2580 sys/common/upload接口存在任意文件上传漏洞 + if (oConvertUtils.isNotEmpty(bizPath)) { + if(bizPath.contains(SymbolConstant.SPOT_SINGLE_SLASH) || bizPath.contains(SymbolConstant.SPOT_DOUBLE_BACKSLASH)){ + throw new JeecgBootException("上传目录bizPath,格式非法!"); + } + } + + MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; + // 获取上传文件对象 + MultipartFile file = multipartRequest.getFile("file"); + + String savePath = this.uploadLocal(file, partNumber, bizPath + File.separator + fileMd5); + + if(StringUtils.isBlank(savePath)){ + return Result.error("upload error"); + } + + return Result.OK("upload ok"); + } + @PostMapping(value = "/sectionUpload/end") + public Result sectionUploadEnd(@RequestBody SectionUploadData sectionUploadData){ + log.info("合并文件!"); + Result result = new Result<>(); + Integer chunkCount = sectionUploadData.getChunkCount(); + String fileMd5 = sectionUploadData.getFileMd5(); + String fileName = sectionUploadData.getFileName(); + String orgName = fileName; + String bizPath = sectionUploadData.getBiz(); + + if (oConvertUtils.isNotEmpty(bizPath)) { + if(bizPath.contains(SymbolConstant.SPOT_SINGLE_SLASH) || bizPath.contains(SymbolConstant.SPOT_DOUBLE_BACKSLASH)){ + throw new JeecgBootException("上传目录bizPath,格式非法!"); + } + } + + //创建一个空文件夹,里面有个文件信息 + String ctxPath = uploadpath; + String folderPath = ctxPath + File.separator + bizPath + File.separator + fileMd5; + File fileFolder = new File(folderPath); + + + //savePath = this.uploadLocal(file,bizPath) + + List allFileNameList = FileUtil.listFileNames(fileFolder.getPath()); + List fileNameList = allFileNameList.stream().filter(x -> !StringUtils.equals("file.info",x)) + .sorted(Comparator.comparing(Integer::parseInt)) + .collect(Collectors.toList()); + + if (orgName != null) { + orgName = CommonUtils.getFileName(orgName); + if(orgName.contains(SymbolConstant.SPOT)){ + fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.lastIndexOf(".")); + }else{ + fileName = orgName+ "_" + System.currentTimeMillis(); + } + } + + + File outFile = FileUtil.newFile(ctxPath + File.separator + bizPath + File.separator + fileName); + + +// FastByteArrayOutputStream ais = IoUtil.w + try { + Vector streams = new Vector<>(); + fileNameList.forEach(sectionFileName -> { + InputStream is = FileUtil.getInputStream(folderPath + File.separator + sectionFileName); + streams.add(is); + }); + + Enumeration enumerations = streams.elements(); + + SequenceInputStream sis = new SequenceInputStream(enumerations); + + BufferedOutputStream bos = new BufferedOutputStream(Files.newOutputStream(outFile.toPath())); + + byte[] bys = new byte[1024]; + int len = 0; + while((len = sis.read(bys)) != -1){ + bos.write(bys, 0, len); + } + IoUtil.close(sis); + IoUtil.close(bos); + streams.forEach(IoUtil::close); + + //删除临时文件 + FileUtil.del(fileFolder); + + //本地上传不做处理, + if(!CommonConstant.UPLOAD_TYPE_LOCAL.equals(uploadType)){ + String savePath = upload(bizPath, getMultipartFile(outFile)); + if(oConvertUtils.isNotEmpty(savePath)){ + result.setMessage(savePath); + result.setSuccess(true); + }else { + result.setMessage("上传失败!"); + result.setSuccess(false); + } + }else { + //本地上传不做处理,直接返回地址即可 + result.setSuccess(true); + result.setMessage(bizPath + "/" + fileName);//地址 + } + return result; + + }catch (Exception e){ + log.error(e.getMessage(), e); + result.setSuccess(false); + result.setMessage(e.getMessage());//地址 + return result; + } + } + + + /** + * file转MultipartFile + * @param file File对象 + * @return MultipartFile 对象 + */ + public static MultipartFile getMultipartFile(File file) { + FileItem item = new DiskFileItemFactory().createItem("file" + , MediaType.MULTIPART_FORM_DATA_VALUE + , true + , file.getName()); + try (InputStream input = Files.newInputStream(file.toPath()); + OutputStream os = item.getOutputStream()) { + // 流转移 + IOUtils.copy(input, os); + } catch (Exception e) { + throw new IllegalArgumentException("Invalid file: " + e, e); + } + + return new CommonsMultipartFile(item); + } + + //切片上传END + /** * 预览图片&下载文件 * 请求地址:http://localhost:8080/common/static/{user/20190119/e1fe9925bc315c60addea1b98eb1cb1349547719_1547866868179.jpg}