feat: 在线编辑文件改为文件服务器存储

This commit is contained in:
2024-10-09 11:16:12 +08:00
parent dd13201ce3
commit 481579bbb1
15 changed files with 218 additions and 1139 deletions
+5 -1
View File
@@ -305,4 +305,8 @@ update process_model_node set sort = 3 where process_key = 'process-annual-init'
update process_model_node set sort = 4 where process_key = 'process-annual-init' and xml_node_id = 'fgbmjlsp';
update process_model_node set sort = 5 where process_key = 'process-annual-init' and xml_node_id = 'gjjlsp';
update process_model_node set sort = 6 where process_key = 'process-annual-init' and xml_node_id = 'zjsp';
update process_model_node set sort = 7 where process_key = 'process-annual-init' and xml_node_id = 'sqrsp';
update process_model_node set sort = 7 where process_key = 'process-annual-init' and xml_node_id = 'sqrsp';
-- 文件表新增字段
ALTER TABLE `oss_file`
ADD COLUMN `onl_id` varchar(36) NULL COMMENT 'onlyOffice关联Id 每次在线编辑生成一个 历史版本均用' AFTER `bind_id`;
@@ -84,16 +84,12 @@ public class OSSFileController {
OSSFile file = ossFileService.getById(id);
LambdaQueryWrapper<OSSFile> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(OSSFile::getBindId, id);
OSSFile pdfFile = ossFileService.getOne(queryWrapper);
if (file == null) {
return Result.error("未找到对应实体");
}
else {
result.setResult(file);
result.setSuccess(true);
if (pdfFile != null) {
file.setPdfId(pdfFile.getId());
}
}
return result;
}
@@ -62,6 +62,9 @@ public class OSSFile extends JeroEntity {
@ApiModelProperty(value = "docx文件对应的pdf文件 使用此字段绑定docx的版本")
private String bindId;
@ApiModelProperty(value = "onlyOffice关联Id 每次在线编辑生成一个")
private String onlId;
@TableField(exist = false)
@ApiModelProperty(value = "PDF版本对应的文件Id")
private String pdfId;
@@ -6,6 +6,7 @@ import com.jero.modules.oss.entity.OSSFile;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
@@ -33,4 +34,5 @@ public interface IOSSFileService extends IService<OSSFile> {
Result<OSSFile> commonUpload(MultipartFile file, String bizPath);
void downloadAndViewWithWaterMark(String id, HttpServletResponse response);
}
@@ -1,5 +1,6 @@
package com.jero.modules.oss.service.impl;
import cn.hutool.core.io.FileUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jero.common.api.vo.Result;
@@ -8,6 +9,7 @@ import com.jero.common.constant.enums.LanguageEnum;
import com.jero.common.exception.JeroBootException;
import com.jero.common.system.vo.LoginUser;
import com.jero.common.util.CommonUtils;
import com.jero.common.util.IntekeyUtils;
import com.jero.common.util.MinioUtil;
import com.jero.common.util.oConvertUtils;
import com.jero.common.util.obs.ObsBootUtil;
@@ -16,16 +18,25 @@ import com.jero.modules.oss.entity.OSSFile;
import com.jero.modules.oss.mapper.OSSFileMapper;
import com.jero.modules.oss.service.IOSSFileService;
import com.jero.modules.system.util.MyStringUtils;
import com.jero.modules.system.util.SysWaterMarkUtil;
import me.zhyd.oauth.utils.UuidUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.entity.ContentType;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.*;
@Service("ossFileService")
@@ -49,6 +60,11 @@ public class OSSFileServiceImpl extends ServiceImpl<OSSFileMapper, OSSFile> impl
@Value(value = "${jero.splitUrl}")
private String splitUrl;
@Resource
private SysWaterMarkUtil sysWaterMarkUtil;
private static final String FILE_VIEW_ERROR = "预览文件失败";
@Override
public void upload(MultipartFile multipartFile) throws IOException {
String fileName = multipartFile.getOriginalFilename();
@@ -405,4 +421,94 @@ public class OSSFileServiceImpl extends ServiceImpl<OSSFileMapper, OSSFile> impl
}
return result;
}
@Override
public void downloadAndViewWithWaterMark(@PathVariable String id, HttpServletResponse response) {
// 查询数据表数据是否存在
LambdaQueryWrapper<OSSFile> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(OSSFile::getId, id);
OSSFile ossFile = this.getOne(queryWrapper);
if (null == ossFile) {
throw new JeroBootException("文件不存在..");
}
String fileUrl = ossFile.getUrl();
// minio 下载
// 通过MinioUtil查询时 只需要桶后面的路径
String minioUrl = MinioUtil.getMinioUrl();
// Linux/unix 系统下文件路径分隔符为"/" 获取minio与存储桶的路径
minioUrl = minioUrl + MinioUtil.getBucketName() + "/";
String url = fileUrl.replace(minioUrl, "");
// 文件名称
String fileName = ossFile.getFileName();
response.addHeader("Content-Disposition", "attachment;fileName=" + new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));
// 设置强制下载不打开
response.setContentType("application/force-download");
// 然后在您的controller方法中:
InputStream watermarkedInputStream = null;
if (CommonConstant.UPLOAD_TYPE_MINIO.equals(uploadType)) {
try (InputStream inputStream = MinioUtil.getMinioFile(MinioUtil.getBucketName(), url);
OutputStream outputStream = response.getOutputStream()
) {
byte[] buf = new byte[1024];
int len;
if (inputStream == null) {
return;
}
while ((len = inputStream.read(buf)) > 0) {
outputStream.write(buf, 0, len);
}
response.flushBuffer();
} catch (Exception e) {
log.error(e.getMessage());
response.setStatus(404);
}
}else if(CommonConstant.UPLOAD_TYPE_OBS.equals(uploadType)) {
// 华为云 下载
if ("pdf".equalsIgnoreCase(FileUtil.extName(fileName))) {
try (InputStream originalInputStream = ObsBootUtil.getOssFile(fileUrl);
OutputStream outputStream = response.getOutputStream()) {
if (originalInputStream == null) {
return;
}
MultipartFile mFile = new MockMultipartFile(fileName, fileName,
ContentType.APPLICATION_OCTET_STREAM.toString(), originalInputStream);
InputStream inputStream = IntekeyUtils.getInputStreamByDecryptFile(mFile);
watermarkedInputStream = sysWaterMarkUtil.addWatermarkToPdf(inputStream);
byte[] buf = new byte[1024];
int len;
while ((len = watermarkedInputStream.read(buf)) > 0) {
outputStream.write(buf, 0, len);
}
response.flushBuffer();
} catch (Exception e) {
log.error("error:",e);
response.setStatus(404);
}finally {
try {
if (watermarkedInputStream != null){
watermarkedInputStream.close();
}
} catch (IOException e) {
log.error(e.getMessage());
}
}
} else {
try (InputStream inputStream = ObsBootUtil.getOssFile(fileUrl);
OutputStream outputStream = response.getOutputStream()
) {
byte[] buf = new byte[1024];
int len;
while ((len = inputStream.read(buf)) > 0) {
outputStream.write(buf, 0, len);
}
response.flushBuffer();
} catch (Exception e) {
log.error(FILE_VIEW_ERROR + e.getMessage());
response.setStatus(404);
}
}
}
}
}
@@ -11,7 +11,6 @@ import com.jero.modules.onlyoffice.utils.OnlyOfficePdfUtil;
import com.jero.modules.oss.entity.OSSFile;
import com.jero.modules.oss.service.IOSSFileService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
@@ -1,19 +1,12 @@
package com.jero.modules.onlyoffice.controller;
import cn.hutool.http.HttpUtil;
import cn.hutool.core.io.IoUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jero.common.api.vo.Result;
import com.jero.common.exception.JeroBootException;
import com.jero.common.system.query.QueryGenerator;
import com.jero.modules.onlyoffice.entity.OnlineFileLog;
import com.jero.common.util.obs.ObsBootUtil;
import com.jero.modules.onlyoffice.entity.ProcessFile;
import com.jero.modules.onlyoffice.mapper.OnlineFileLogDao;
import com.jero.modules.onlyoffice.mapper.ProcessFileMapper;
import com.jero.modules.onlyoffice.service.IProcessFileService;
import com.jero.modules.onlyoffice.service.LawsUserInfoService;
import com.jero.modules.oss.entity.OSSFile;
import com.jero.modules.oss.service.IOSSFileService;
import com.sini.com.spire.doc.Document;
import com.sini.com.spire.doc.documents.PageNumberStyle;
@@ -21,17 +14,15 @@ import com.sini.com.spire.doc.documents.PageOrientation;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.text.SimpleDateFormat;
@@ -50,270 +41,35 @@ public class OnlyOfficeController {
@Resource
private IProcessFileService ProcessFileService;
@Resource
private LawsUserInfoService lawsUserInfoService;
@Resource
private ProcessFileMapper ProcessFileMapper;
@Resource
private IOSSFileService ossFileService;
@Resource
private OnlineFileLogDao onlineFileLogDao;
@Value("#{'${onlyoffice.replaceUrl:}'.split(',')}")
private List<String> replaceUrlList;
@Value("#{'${onlyoffice.toUrl:}'}")
private String toUrl;
@Value("${file.path}")
private String filePath;//文件存储路径
@ApiOperation(value = "分页查询")
@GetMapping("/pageList")
public Result<IPage<ProcessFile>> pageList(HttpServletRequest req, ProcessFile processModelHis,
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
QueryWrapper<ProcessFile> queryWrapper = QueryGenerator.initQueryWrapper(processModelHis, req.getParameterMap());
Page<ProcessFile> page = new Page<>(pageNo, pageSize);
IPage<ProcessFile> pageList = ProcessFileService.page(page, queryWrapper);
return Result.OK(pageList);
}
/**
* 删除
*/
@ApiOperation(value = "删除")
@PostMapping("/delete")
public Result<String> delete(@RequestBody Map<String, String> map) {
String id = map.get("id");
if (StringUtils.isBlank(id)) {
return Result.error("参数不识别!");
}
boolean ok = ProcessFileService.removeById(id);
if (ok) {
return Result.OK("删除成功!");
}
return Result.OK();
}
/**
* 批量删除
*/
@ApiOperation(value = "批量删除")
@PostMapping("/deleteBatch")
public Result<String> deleteBatch(@RequestBody Map<String, String> map) {
String ids = map.get("ids");
if (StringUtils.isBlank(ids)) {
return Result.error("参数不识别!");
} else {
this.ProcessFileService.removeByIds(Arrays.asList(ids.split(",")));
return Result.OK("删除成功!");
}
}
/**
* 根据Id获取文件信息
* id是saveEditFile接口返回的id 也是bus_process_model_his表的id
*/
@ApiOperation(value = "根据Id获取文件信息")
@GetMapping("/queryById")
public Result<Map<String, String>> queryById(String id) {
if (StringUtils.isBlank(id)) {
return Result.error("id不能为空!");
}
HashMap<String, String> map = new HashMap<>();
ProcessFile his = ProcessFileService.getById(id);
if (his == null) {
log.error("在线编辑queryById:{}", id);
throw new JeroBootException("获取在线编辑文件记录错误,请检查");
}
map.put("fileName", his.getFileName());
map.put("editFilePath", his.getEditFilePath());
map.put("id", his.getId());
return Result.OK(map);
}
@ApiOperation(value = "|onlyOffice接收文件")
@PostMapping("/receiveFile")
public void receiveFile(HttpServletRequest request, HttpServletResponse response, String fileNm, String standNo, String fileId, String standName, String key) {
public void receiveFile(HttpServletRequest request, String fileId) {
log.info("**********进入receiveFile接收文档接口************");
log.info("**********fileNm************" + fileNm + "=======");
log.info("**********standNo************" + standNo + "=======");
log.info("**********fileId************" + fileId + "=======");
log.info("**********standName************" + standName + "=======");
log.info("**********key************" + key + "=======");
try {
PrintWriter writer = response.getWriter();
String body = "";
try {
Scanner scanner = new Scanner(request.getInputStream());
scanner.useDelimiter("\\A");
body = scanner.hasNext() ? scanner.next() : "";
scanner.close();
} catch (Exception ex) {
writer.write("get request.getInputStream error:" + ex.getMessage());
return;
request.setAttribute("biz", "onlyOffice");
Result<OSSFile> result = ossFileService.outUpload(request);
// 将文件名字改成和原始文件一样
OSSFile file = ossFileService.getById(fileId);
if (result.isSuccess()) {
OSSFile ossFile = result.getResult();
ossFile.setFileName(file.getFileName());
ossFile.setStandardId(file.getStandardId());
ossFile.setStandardNo(file.getStandardNo());
ossFile.setStandardFileType(file.getStandardFileType());
ossFile.setOnlId(file.getOnlId());
ossFileService.updateById(ossFile);
}
if (body.isEmpty()) {
writer.write("empty request.getInputStream");
return;
}
net.sf.json.JSONObject jsonObj = net.sf.json.JSONObject.fromObject(body);
log.info("**********onlyoffice接收文档接口获得结果body************" + body);
int status = (Integer) jsonObj.get("status");
int saved = 0;
if (status == 2 || status == 3 || status == 6)//MustSave, Corrupted
{
String downloadUri = (String) jsonObj.get("url");
try {
log.info("**********onlyoffice接收文档接口获得downloadUri************" + downloadUri);
if (StringUtils.isNotEmpty(downloadUri)) {
for (String replaceUrl : replaceUrlList) {
downloadUri = downloadUri.replace(replaceUrl, toUrl);
}
ProcessFile modelHis = ProcessFileService.getById(fileId);
String editFilePath = modelHis.getEditFilePath();
// String saveFileUrl = standEditFilePath + editFilePath;
// TODO
String saveFileUrl = editFilePath;
log.info("**********onlyoffice文档下载路径************" + downloadUri);
log.info("**********onlyoffice文档保存本地路径************" + saveFileUrl);
HttpUtil.downloadFileFromUrl(downloadUri, saveFileUrl);
File file = new File(saveFileUrl);
downloadNetFile(downloadUri, file);
// 更新在线编辑当前节点编辑状态
ProcessFileService.modelHisOneUpdStatusById(fileId);
Object keyObj = jsonObj.get("key");
if (keyObj != null) {
key = keyObj.toString();
log.info("**********key************" + key + "=======");
}
lawsUserInfoService.selectOnlineFile(fileId, standName, key);
}
} catch (Exception ex) {
saved = 1;
log.info("**********onlyoffice接收文档接口异常************" + ex.getMessage());
log.error(ex.getMessage(), ex);
}
} else if (status == 4) {
log.info("**********onlyoffice接收文档接口开始修改文件状态状态4************");
log.info("**********onlyoffice接收文档接口修改文件状态成功状态4************");
}
log.info("onlyoffice编辑完成--------------");
writer.write("{\"error\":" + saved + "}");
} catch (IOException e) {
log.info("**********onlyoffice接收文档接口异常************" + e.getMessage());
log.error(e.getMessage(), e);
} catch (Exception e) {
log.error("**********onlyoffice接收文档接口异常************" + e.getMessage());
}
}
@ApiOperation(value = "|onlyOffice接收文件")
@PostMapping("/receiveFileBefore")
public void receiveFileBefore(HttpServletRequest request, HttpServletResponse response, String key, String fileNm, String standNo, String pid, String taskId, String standName) {
log.info("**********进入receiveFileBefore接收文档接口************");
log.info("**********fileNm************" + fileNm + "=======");
log.info("**********standNo************" + standNo + "=======");
log.info("**********pid************" + pid + "=======");
log.info("**********taskId************" + taskId + "=======");
log.info("**********standName************" + standName + "=======");
log.info("**********key************" + key + "=======");
try {
PrintWriter writer = response.getWriter();
String body = "";
try {
Scanner scanner = new Scanner(request.getInputStream());
scanner.useDelimiter("\\A");
body = scanner.hasNext() ? scanner.next() : "";
scanner.close();
} catch (Exception ex) {
writer.write("get request.getInputStream error:" + ex.getMessage());
return;
}
if (body.isEmpty()) {
writer.write("empty request.getInputStream");
return;
}
net.sf.json.JSONObject jsonObj = net.sf.json.JSONObject.fromObject(body);
log.info("**********onlyoffice接收文档接口获得结果body************" + body);
int status = (Integer) jsonObj.get("status");
int saved = 0;
if (status == 2 || status == 3 || status == 6)//MustSave, Corrupted
{
String downloadUri = (String) jsonObj.get("url");
try {
log.info("**********onlyoffice接收文档接口获得downloadUri************" + downloadUri);
if (StringUtils.isNotEmpty(downloadUri)) {
// TODO
String saveFileUrl = standNo + "/" + fileNm;
File file = new File(saveFileUrl);
downloadNetFile(downloadUri, file);
// 更新在线编辑当前节点编辑状态
ProcessFileService.modelHisOneUpdStatus(pid, taskId);
QueryWrapper<ProcessFile> objectQueryWrapper = new QueryWrapper<>();
objectQueryWrapper.eq("P_ID", pid);
objectQueryWrapper.eq("TASK_ID", taskId);
ProcessFile ProcessFile = ProcessFileMapper.selectOne(objectQueryWrapper);
if (ProcessFile != null) {
Object keyObj = jsonObj.get("key");
if (keyObj != null) {
key = keyObj.toString();
log.info("**********key************" + key + "=======");
}
lawsUserInfoService.selectOnlineFile(ProcessFile.getId(), standName, key);
}
}
} catch (Exception ex) {
saved = 1;
log.info("**********onlyoffice接收文档接口异常************" + ex.getMessage());
log.error(ex.getMessage(), ex);
}
} else if (status == 4) {
log.info("**********onlyoffice接收文档接口开始修改文件状态状态4************");
log.info("**********onlyoffice接收文档接口修改文件状态成功状态4************");
}
log.info("onlyoffice编辑完成--------------");
writer.write("{\"error\":" + saved + "}");
} catch (IOException e) {
log.info("**********onlyoffice接收文档接口异常************" + e.getMessage());
log.error(e.getMessage(), e);
}
}
public void downloadNetFile(String downloadUrl, File file) {
try {
FileOutputStream fileOutputStream = new FileOutputStream(file);
URL url = new URL(downloadUrl);
URLConnection connection = url.openConnection();
InputStream inputStream = connection.getInputStream();
int length = 0;
byte[] bytes = new byte[1024];
while ((length = inputStream.read(bytes)) != -1) {
fileOutputStream.write(bytes, 0, length);
}
fileOutputStream.close();
inputStream.close();
} catch (IOException e) {
log.error("download error ! url :{}", downloadUrl);
log.error(e.getMessage(), e);
}
}
@GetMapping("/processEditFile")
public ProcessFile processEditFile(String id) {
return ProcessFileService.processEditFile(id);
@@ -321,42 +77,37 @@ public class OnlyOfficeController {
@ApiOperation(value = "|model| 传入 模板文档名称(不带后缀)默认 docx")
@GetMapping("/saveEditFile")
public Result<ProcessFile> saveEditFile(String model) {
public Result<String> saveEditFile(String model) {
return Result.OK(ProcessFileService.saveEditFile(model));
}
@ApiOperation(value = "传入ossFileId获取在线编辑文件相关信息")
@GetMapping("/saveEditFileWithOss")
public Result<ProcessFile> saveEditFileWithOss(String ossFileId) {
return Result.OK(ProcessFileService.saveEditFileWithOss(ossFileId));
}
@ApiOperation(value = "根据传入的标准编号返回对应的在线编辑文件信息")
@GetMapping("/findEditFileByStandardNo")
public Result<ProcessFile> findEditFileByStandardNo(String standardNo) {
public Result<String> findEditFileByStandardNo(String standardNo) {
return Result.OK(ProcessFileService.findEditFileByStandardNo(standardNo));
}
@ApiOperation(value = "根据路径下载文件")
@GetMapping("/downLoadFile")
public void downLoadFile(@RequestParam(name = "path") String path, HttpServletResponse response) {
ProcessFileService.downLoadFile(path, response);
}
@ApiOperation(value = "根据路径下载文件(罗马数字页码)")
@GetMapping("/downLoadFileRoma")
public void downLoadFileRoma(@RequestParam(name = "path") String path, HttpServletResponse response) {
InputStream is = null;
OutputStream os = null;
public void downLoadFileRoma(@RequestParam(name = "id") String fileId, HttpServletResponse response) {
OSSFile file = ossFileService.getById(fileId);
if (file == null) {
log.error("文件不存在");
throw new RuntimeException("文件不存在");
}
response.reset();
try {
// 从文件服务器下载指定文件
try (InputStream inputStream = ObsBootUtil.getOssFile(file.getUrl());
OutputStream outputStream = response.getOutputStream()
) {
// 编码文件名
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
response.setHeader("Content-Disposition", "attachment;filename=file.docx");
response.setContentType("application/octet-stream");
// 加载文档
Document doc = new Document(filePath + path);
Document doc = new Document(inputStream);
int i = 0;
try {
doc.getSections().get(0).getPageSetup().setPageNumberStyle(PageNumberStyle.Roman_Upper);
@@ -371,85 +122,42 @@ public class OnlyOfficeController {
log.info("设置纵向页面,循环次数为:{}", i + 1);
}
String downloadDocxFileTempUrl = filePath + "/downloadDocxFileTemp";
File downloadDocxFileTempUrlFile = new File(downloadDocxFileTempUrl);
// 创建临时文件,系统会在适当的时候自动删除
File tempFile = File.createTempFile(UUID.randomUUID().toString(), ".docx");
if (!downloadDocxFileTempUrlFile.exists()) {
boolean mkdirs = downloadDocxFileTempUrlFile.mkdirs();
if (!mkdirs) {
log.info("创建临时文件目录失败:{}", downloadDocxFileTempUrl);
}
// 将文档保存到临时文件
doc.saveToFile(tempFile.getAbsolutePath());
// 使用流将临时文件写入到 response 输出流
try (InputStream is = Files.newInputStream(tempFile.toPath());
OutputStream os = response.getOutputStream()) {
IoUtil.copy(is, os);
os.flush();
}
String newFileName = UUID.randomUUID().toString().replace("-", "") + ".docx";
String newFileUrl = downloadDocxFileTempUrl + "/" + newFileName;
//保存文档
doc.saveToFile(newFileUrl);
File newFile = new File(newFileUrl);
is = Files.newInputStream(newFile.toPath());
os = response.getOutputStream();
IOUtils.copy(is, os);
os.flush();
is.close();
if (newFile.delete()) {
log.info("在线编辑下载-临时文件删除成功: " + newFileUrl);
} else {
log.info("在线编辑下载-临时文件删除失败: " + newFileUrl);
}
} catch (IOException e) {
log.error(e.getMessage(), e);
} finally {
IOUtils.closeQuietly(is);
IOUtils.closeQuietly(os);
} catch (Exception e) {
log.error(e.getMessage());
response.setStatus(404);
}
}
@GetMapping("/processModelHisOneUpdStatus")
public ProcessFile modelHisOneUpdStatus(String pid, String taskId) {
return ProcessFileService.modelHisOneUpdStatus(pid, taskId);
}
@GetMapping("/processModelHisOneCount")
public ProcessFile modelHisOneCount(String pid) {
return ProcessFileService.modelHisOneCount(pid);
}
@GetMapping("/processModelHisOne")
public ProcessFile modelHisOne(String pid, String taskId) {
return ProcessFileService.modelHisOne(pid, taskId);
}
@GetMapping("/processModelHisList")
public List<ProcessFile> evaluationHisList(String pid) {
return ProcessFileService.modelHisList(pid);
}
@PostMapping("/selectOnlineFile")
public OnlineFileLog selectOnlineFile(@RequestParam("onlineFileId") String onlineFileId) {
return ProcessFileService.selectOnlineFile(onlineFileId);
}
@ApiOperation(value = "根据在线文件Id查询所有onlyoffice历史文件")
@GetMapping("/getAllOnlyOfficeHisFileById")
public Result<List<Map<String, String>>> getAllOnlyOfficeHisFileById(String fileId, String fileName) {
OSSFile file = ossFileService.getById(fileId);
List<Map<String, String>> fileList = new ArrayList<>();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
LambdaQueryWrapper<OnlineFileLog> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(OnlineFileLog::getHisId, fileId);
wrapper.eq(OnlineFileLog::getValidFlag, "0");
wrapper.orderByDesc(OnlineFileLog::getCreateTime);
List<OnlineFileLog> onlineFileLogList = onlineFileLogDao.selectList(wrapper);
if (!onlineFileLogList.isEmpty()) {
for (OnlineFileLog onlineFileLog : onlineFileLogList) {
LambdaQueryWrapper<OSSFile> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(OSSFile::getOnlId, file.getOnlId());
wrapper.orderByDesc(OSSFile::getCreateTime);
wrapper.last("limit 10");
List<OSSFile> ossFileList = ossFileService.list(wrapper);
if (!ossFileList.isEmpty()) {
for (OSSFile ossFile : ossFileList) {
Map<String, String> map = new HashMap<>();
map.put("id", onlineFileLog.getId());
map.put("filePath", onlineFileLog.getFilePath());
map.put("id", ossFile.getId());
map.put("fileName", fileName);
map.put("attFileId", onlineFileLog.getAttFileId());
map.put("createTime", sdf.format(onlineFileLog.getCreateTime()));
map.put("fileKey", onlineFileLog.getFileKey());
map.put("createTime", sdf.format(ossFile.getCreateTime()));
fileList.add(map);
}
return Result.OK(fileList);
@@ -1,55 +0,0 @@
package com.jero.modules.onlyoffice.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
@Data
@TableName("online_file_log")
@ApiModel(value = "OnlineFileLog对象", description = "在线编辑日志表")
public class OnlineFileLog {
@ApiModelProperty(value = "主键")
@TableId(type = IdType.ASSIGN_ID)
private String id;
private String hisId;
private String attFileId;
private String fileName;
private String oldFileName;
private String fileSuffix;
private String filePath;
private Integer count;
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
@TableField(exist = false)
private byte[] bytes;
@ApiModelProperty(value = "是否有效")
private String validFlag;
@ApiModelProperty(value = "文件key")
private String fileKey;
}
@@ -1,8 +0,0 @@
package com.jero.modules.onlyoffice.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.jero.modules.onlyoffice.entity.OnlineFileLog;
public interface OnlineFileLogDao extends BaseMapper<OnlineFileLog> {
}
@@ -1,16 +0,0 @@
package com.jero.modules.onlyoffice.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.jero.modules.onlyoffice.entity.ProcessFile;
/**
* <p>
* 流程模块历史表 Mapper 接口
* </p>
*
* @author super_liu
* @since 2021-09-17
*/
public interface ProcessFileMapper extends BaseMapper<ProcessFile> {
}
@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jero.modules.onlyoffice.mapper.ProcessFileMapper">
</mapper>
@@ -2,12 +2,8 @@ package com.jero.modules.onlyoffice.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.jero.modules.onlyoffice.entity.ProcessFile;
import com.jero.modules.onlyoffice.entity.OnlineFileLog;
import com.jero.modules.oss.entity.OSSFile;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
* <p>
* 流程模块历史表 服务类
@@ -16,33 +12,13 @@ import java.util.List;
* @author super_liu
* @since 2021-09-17
*/
public interface IProcessFileService extends IService<ProcessFile> {
ProcessFile modelHisOneUpdStatusById(String id);
ProcessFile modelHisOneUpdStatus(String pid,String taskId);
ProcessFile modelHisOneCount(String pid);
public interface IProcessFileService {
ProcessFile processEditFile(String id);
ProcessFile modelHisOne(String pid,String taskId);
String saveEditFile(String model);
ProcessFile saveEditFile(String model);
ProcessFile saveEditFileWithOss(String ossFileId);
void replaceFile(String hisId, String replaceId);
List<ProcessFile> modelHisList(String pid);
OnlineFileLog selectOnlineFile(String onlineFileId);
void downLoadFile(String path, HttpServletResponse response);
String saveProcessFileToOss(String hisId);
ProcessFile findEditFileByStandardNo(String standardNo);
String findEditFileByStandardNo(String standardNo);
OSSFile findLastDocFileByStandardNo(String standardNo);
}
@@ -1,146 +0,0 @@
package com.jero.modules.onlyoffice.service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jero.common.util.UUIDUtils;
import com.jero.modules.onlyoffice.entity.OnlineFileLog;
import com.jero.modules.onlyoffice.mapper.OnlineFileLogDao;
import com.jero.modules.oss.entity.OSSFile;
import com.jero.modules.oss.service.IOSSFileService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;
import java.util.List;
/**
* @author liJiaRao
* @date 2023-09-14 11:13
*/
@Service
@Slf4j
public class LawsUserInfoService {
@Value("${file.path}")
private String standEditFilePath;
@Resource
private IProcessFileService busProcessModelHisService;
@Resource
private OnlineFileLogDao onlineFileLogDao;
@Resource
private IOSSFileService ossFileService;
/**
* 查找在线编辑文件
*
* @param onlineFileId
* @param standName
* @param key
*/
public void selectOnlineFile(String onlineFileId, String standName, String key) {
log.info("======================standName===============================!!!!!!!!!!!!!!!!!!!!!!" + standName);
String path = standEditFilePath + "hisFile/";
File file = null;
FileOutputStream fileOutputStream = null;
BufferedOutputStream bufferedOutputStream = null;
//下载位置
OnlineFileLog onlineFileLog = busProcessModelHisService.selectOnlineFile(onlineFileId);
long time = System.currentTimeMillis();
if (onlineFileLog == null) {
return;
}
String fileName = UUIDUtils.randomUUID(20);
try {
file = new File(path + onlineFileLog.getOldFileName());
boolean directory = file.isDirectory();
log.info("**********path+onlineFileLog.getOldFileName()本地路径************" + path + onlineFileLog.getOldFileName());
//目录是否存在
if (!directory) {
file.mkdirs();
}
file = new File(path + "/" + onlineFileLog.getOldFileName(), fileName + "." + onlineFileLog.getFileSuffix());
log.info("**********parent路径************" + path + "/" + onlineFileLog.getOldFileName());
log.info("**********child路径************" + onlineFileLog.getOldFileName() + "." + onlineFileLog.getFileSuffix());
fileOutputStream = new FileOutputStream(file);
bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
fileOutputStream.write(onlineFileLog.getBytes());
fileOutputStream.close();
//把文件下载到本地 然后获得文件的名称 通过文件名称 调用 filesave接口 获取id 进行日志存入
log.info("======================文件存储到本地成功,作为存储与Att表的桥梁===============================");
} catch (Exception e) {
log.info("======================文件存储到本地失败===============================");
} finally {
try {
if (bufferedOutputStream != null) {
bufferedOutputStream.close();
}
if (fileOutputStream != null) {
fileOutputStream.close();
}
} catch (IOException e) {
log.info("======================文件流关闭失败===============================");
}
}
// 把文件放置到本地
OSSFile ossFile = new OSSFile();
// 开始存储文件信息
ossFile.setFileName(onlineFileLog.getOldFileName());
String fileUrl = "hisFile/" + onlineFileLog.getOldFileName() + "/" + fileName + "." + onlineFileLog.getFileSuffix();
ossFile.setUrl(fileUrl);
ossFileService.save(ossFile);
log.info("======================文件成功存储到Oss中===============================" + ossFile.toString());
// 储存文件 一个文件夹 储存十个
onlineFileLog.setAttFileId(ossFile.getId());
onlineFileLog.setUpdateTime(new Date());
onlineFileLog.setCreateTime(new Date());
onlineFileLog.setFileName(String.valueOf(time));
onlineFileLog.setValidFlag("0");
onlineFileLog.setFileKey(key);
onlineFileLog.setFilePath(fileUrl);
onlineFileLogDao.insert(onlineFileLog);
log.info("======================日志存入成功===============================");
if (StringUtils.isNotBlank(standName)) {
ossFile.setFileName(standName + ".docx");
ossFileService.updateById(ossFile);
log.info("======================文件名称修改成功===============================" + standName + ".docx" + "======" + "传入对象为:" + ossFile.getFileName());
}
QueryWrapper<OnlineFileLog> onlineFileLogQueryWrapperHis = new QueryWrapper<>();
onlineFileLogQueryWrapperHis.eq("HIS_ID", onlineFileId);
onlineFileLogQueryWrapperHis.eq("VALID_FLAG", "0");
onlineFileLogQueryWrapperHis.orderByAsc("CREATE_TIME");
List<OnlineFileLog> onlineFileLogs = onlineFileLogDao.selectList(onlineFileLogQueryWrapperHis);
// 只保留最近的10个文件
if (onlineFileLogs.size() > 10) {
log.info("======================文件日志记录小于10===============================" + onlineFileLogs.size());
QueryWrapper<OnlineFileLog> onlineFileLogQueryWrapper = new QueryWrapper<>();
onlineFileLogQueryWrapper.eq("ID", onlineFileLogs.get(0).getId());
OnlineFileLog onlineFileLogIsNot = onlineFileLogDao.selectOne(onlineFileLogQueryWrapper);
if (onlineFileLogIsNot != null) {
// 删除此处有关的数据
OSSFile ossFileInfo = ossFileService.getById(onlineFileLogIsNot.getAttFileId());
if (ossFileInfo != null) {
// 删除所有相关文件和记录
File fileAtt = new File(standEditFilePath + ossFileInfo.getUrl());
boolean delete = fileAtt.delete();
if (delete) {
log.info("======================文件删除成功===============================" + ossFileInfo.getUrl());
ossFileService.removeById(onlineFileLogIsNot.getAttFileId());
onlineFileLogDao.deleteById(onlineFileLogs.get(0).getId());
}
}
}
log.info("删除成功" + onlineFileLogs.get(0).getId());
} else {
log.info("======================文件日志记录小于10===============================" + onlineFileLogs.size());
}
}
}
@@ -1,40 +1,27 @@
package com.jero.modules.onlyoffice.service.impl;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jero.common.exception.JeroBootException;
import com.jero.common.util.CommonUtils;
import com.jero.common.util.IntekeyUtils;
import com.jero.common.util.MinioUtil;
import com.jero.common.util.UUIDUtils;
import com.jero.common.util.oConvertUtils;
import com.jero.modules.laws.common.constant.FieldCommon;
import com.jero.modules.laws.standard.entity.LawsEnterpriseStandard;
import com.jero.modules.laws.standard.service.ILawsEnterpriseStandardService;
import com.jero.modules.onlyoffice.entity.OnlineFileLog;
import com.jero.modules.onlyoffice.entity.ProcessFile;
import com.jero.modules.onlyoffice.entity.StandardFileType;
import com.jero.modules.onlyoffice.mapper.OnlineFileLogDao;
import com.jero.modules.onlyoffice.mapper.ProcessFileMapper;
import com.jero.modules.onlyoffice.service.IProcessFileService;
import com.jero.modules.onlyoffice.utils.OnlyOfficePdfUtil;
import com.jero.modules.oss.entity.OSSFile;
import com.jero.modules.oss.service.IOSSFileService;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;
@@ -47,22 +34,8 @@ import java.util.stream.Collectors;
* @since 2021-09-17
*/
@Service
public class ProcessFileServiceImpl extends ServiceImpl<ProcessFileMapper, ProcessFile> implements IProcessFileService {
private static final Logger logger = LoggerFactory.getLogger(ProcessFileServiceImpl.class);
@Value("${file.path}")
private String filePath;//文件存储路径
/**
* 文件下载路径
*/
@Value("${file.downloadUrl}")
private String downloadUrl;
@Resource
private OnlineFileLogDao onlineFileLogDao;
@Slf4j
public class ProcessFileServiceImpl implements IProcessFileService {
@Resource
private IOSSFileService ossFileService;
@@ -71,404 +44,59 @@ public class ProcessFileServiceImpl extends ServiceImpl<ProcessFileMapper, Proce
private String uploadType;
@Resource
private ILawsEnterpriseStandardService eSService;
@Resource
private OnlyOfficePdfUtil onlineOfficePdfUtil;
private ILawsEnterpriseStandardService esService;
@Override
public ProcessFile saveEditFile(String model) {
ProcessFile modelHis = new ProcessFile();
public String saveEditFile(String model) {
OSSFile ossFile = new OSSFile();
try {
String preUuid2 = UUID.randomUUID().toString();
String changUuid = preUuid2.substring(0, 8);
String taskId = "task_" + changUuid;
String topId = "top_" + changUuid;
String builderModel = "model" + "/";
File dir = new File(filePath + builderModel);
if (!dir.exists()) {
boolean mkdirs = dir.mkdirs();
if (!mkdirs) {
throw new JeroBootException("创建目录失败");
}
File file = new File("wordTemplate/DOCX.docx");
FileInputStream fileInputStream = new FileInputStream(file);
MultipartFile multipartFile = new MockMultipartFile("file", file.getName(), "application/octet-stream", fileInputStream);
String savePath = CommonUtils.upload(multipartFile, "onlyoffice", uploadType);
if (oConvertUtils.isNotEmpty(savePath)) {
// 文件名
String fileName = multipartFile.getOriginalFilename();
fileName = CommonUtils.getFileName(fileName);
ossFile.setFileName(fileName);
ossFile.setUrl(savePath);
ossFile.setOnlId(UUIDUtils.randomUUID(10));
ossFileService.save(ossFile);
return ossFile.getId();
}
String fileName = model + ".docx";
modelHis.setFileName(fileName);
StringBuilder builder = new StringBuilder();
builder.append("model").append("/");
builder.append(taskId).append("/");
File file = new File(filePath + builder);
if (!file.exists()) {
boolean mkdirs = file.mkdirs();
if (!mkdirs) {
throw new JeroBootException("创建目录失败");
}
}
String targetPath = builder + taskId + "_" + topId + "_node.docx";
File sourceFile = new File("wordTemplate/DOCX.docx");
File targetFile = new File(filePath + targetPath);
FileUtils.copyFile(sourceFile, targetFile);
modelHis.setTaskId(taskId);
modelHis.setPId(topId);
modelHis.setEditFilePath(targetPath);
modelHis.setDownLoadUrl(downloadUrl + targetPath);
this.baseMapper.insert(modelHis);
} catch (Exception e) {
logger.error(e.getMessage());
log.error(e.getMessage());
}
return modelHis;
}
@Override
public ProcessFile saveEditFileWithOss(String ossFileId) {
OSSFile ossFile = ossFileService.getById(ossFileId);
ProcessFile modelHis = new ProcessFile();
try {
String taskId = generateTaskId();
String topId = generateTopId();
String builderModel = "model" + "/";
String targetPath = builderModel + taskId + "/" + taskId + "_" + topId + "_node.docx";
createDirectoryIfNotExists(filePath + builderModel);
createDirectoryIfNotExists(filePath + builderModel + taskId + "/");
String fileUrl = ossFile.getUrl();
String minioUrl = MinioUtil.getMinioUrl() + MinioUtil.getBucketName() + "/";
String url = fileUrl.replace(minioUrl, "");
InputStream minioFile = MinioUtil.getMinioFile(MinioUtil.getBucketName(), url);
// 需要将文件解密
minioFile = IntekeyUtils.autoDecryptInputStreamFile(minioFile, ossFile.getFileName());
File targetFile = new File(filePath + targetPath);
try (OutputStream outputStream = Files.newOutputStream(targetFile.toPath())) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = minioFile.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
} catch (IOException e) {
log.error("文件写入失败:" + e.getMessage());
}
modelHis.setFileName(ossFile.getFileName());
modelHis.setTaskId(taskId);
modelHis.setPId(topId);
modelHis.setEditFilePath(targetPath);
modelHis.setDownLoadUrl(downloadUrl + targetPath);
modelHis.setReplaceFileId(ossFileId);
this.baseMapper.insert(modelHis);
} catch (Exception e) {
logger.error(e.getMessage());
}
return modelHis;
}
private String generateTaskId() {
String preUuid2 = UUID.randomUUID().toString();
return "task_" + preUuid2.substring(0, 8);
}
private String generateTopId() {
String preUuid2 = UUID.randomUUID().toString();
return "top_" + preUuid2.substring(0, 8);
}
private void createDirectoryIfNotExists(String directoryPath) {
File dir = new File(directoryPath);
if (!dir.exists()) {
boolean mkdirs = dir.mkdirs();
if (!mkdirs) {
throw new JeroBootException("创建目录失败");
}
}
}
@Override
public OnlineFileLog selectOnlineFile(String onlineFileId) {
ProcessFile ProcessFile = baseMapper.selectById(onlineFileId);
OnlineFileLog onlineFileLog = new OnlineFileLog();
byte[] bytes = new byte[0];
if (ProcessFile != null) {
//获取当前文件路径 返回文件路径的数字组
try {
String editFilePath = ProcessFile.getEditFilePath();
File file = new File(filePath + editFilePath);
FileInputStream fileInputStream = new FileInputStream(file);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(1024);
byte[] aByte = new byte[1024];
int n;
while ((n = fileInputStream.read(aByte)) != -1) {
byteArrayOutputStream.write(aByte, 0, n);
}
bytes = byteArrayOutputStream.toByteArray();
} catch (IOException e) {
log.error("文件读取失败:" + e.getMessage());
}
onlineFileLog.setHisId(ProcessFile.getId());
onlineFileLog.setFilePath(ProcessFile.getEditFilePath());
if (StringUtils.isNotBlank(ProcessFile.getEditFilePath())) {
String[] split = ProcessFile.getEditFilePath().split("\\.");
onlineFileLog.setFileSuffix(split[1]);
}
if (StringUtils.isNotBlank(ProcessFile.getEditFilePath())) {
String[] split = ProcessFile.getEditFilePath().split("/");
String[] split1 = split[2].split("\\.");
onlineFileLog.setOldFileName(split1[0]);
}
onlineFileLog.setBytes(bytes);
}
return onlineFileLog;
}
@Override
public void downLoadFile(String path, HttpServletResponse response) {
InputStream inputStream = null;
OutputStream outputStream = null;
try {
File file = new File(filePath + path);
inputStream = new BufferedInputStream(Files.newInputStream(file.toPath()));
response.addHeader("Content-Disposition", "attachment;fileName="
+ new String(file.getName().getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));
response.setContentType("application/force-download");// 设置强制下载不打开
outputStream = response.getOutputStream();
byte[] buf = new byte[1024];
int len;
while ((len = inputStream.read(buf)) > 0) {
outputStream.write(buf, 0, len);
}
response.flushBuffer();
} catch (IOException e) {
log.error("预览文件失败" + e.getMessage());
response.setStatus(404);
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
log.error(e.getMessage(), e);
}
}
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
log.error(e.getMessage(), e);
}
}
}
}
/**
* 企标流程文件存储
*
* @param pid
* @param taskId
* @param fileSuffix
* @param filePath 文件存储路径
* @throws IOException
*/
public String saveProcessFile(String filePath, String pid, String taskId, String fileSuffix) {
String fileSavePath = "bussEdit" + getUUIDPath(pid, taskId);
String newFileName = "";
try {
File dir = new File(fileSavePath);
if (!dir.exists()) {
dir.mkdirs();
}
newFileName = fileSavePath + taskId + "_" + pid + "_node." + fileSuffix;
File saveFile = new File(filePath + newFileName);
FileUtils.write(saveFile, "", "UTF-8");
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return newFileName;
}
public static String getUUIDPath(String pid, String taskId) {
StringBuilder builder = new StringBuilder();
builder.append("/");
builder.append(pid).append("/");
// builder.append(taskId).append("/");
return builder.toString();
}
@Override
public ProcessFile modelHisOneUpdStatusById(String id) {
ProcessFile modelHis = new ProcessFile();
modelHis.setId(id);
modelHis.setEditStatus("1");
this.baseMapper.updateById(modelHis);
return modelHis;
}
@Override
public ProcessFile modelHisOneUpdStatus(String pid, String taskId) {
ProcessFile modelHis = new ProcessFile();
QueryWrapper wrapper = new QueryWrapper();
wrapper.eq("P_ID", pid);
wrapper.eq("TASK_ID", taskId);
List<ProcessFile> hisList = this.baseMapper.selectList(wrapper);
if (!hisList.isEmpty()) {
modelHis = hisList.get(0);
modelHis.setEditStatus("1");
this.baseMapper.updateById(modelHis);
}
return modelHis;
}
@Override
public ProcessFile modelHisOneCount(String pid) {
ProcessFile modelHis = new ProcessFile();
QueryWrapper wrapper = new QueryWrapper();
wrapper.eq("P_ID", pid);
wrapper.eq("EDIT_TYPE", "count");
List<ProcessFile> hisList = this.baseMapper.selectList(wrapper);
if (!hisList.isEmpty()) {
modelHis = hisList.get(0);
StringBuffer downloadFileUrl = new StringBuffer();
downloadFileUrl.append(downloadUrl).append(modelHis.getEditFilePath() == null ? "" : modelHis.getEditFilePath());
modelHis.setDownLoadUrl(downloadFileUrl.toString());
}
return modelHis;
return "";
}
@Override
public ProcessFile processEditFile(String id) {
ProcessFile modelHis = this.baseMapper.selectById(id);
if (StringUtils.isNotBlank(modelHis.getId())) {
modelHis.setDownLoadUrl(downloadUrl + (modelHis.getEditFilePath() == null ? "" : modelHis.getEditFilePath()));
}
return modelHis;
// ProcessFile modelHis = this.baseMapper.selectById(id);
// if (StringUtils.isNotBlank(modelHis.getId())) {
// modelHis.setDownLoadUrl(downloadUrl + (modelHis.getEditFilePath() == null ? "" : modelHis.getEditFilePath()));
// }
// return modelHis;
return null;
}
@Override
public ProcessFile modelHisOne(String pid, String taskId) {
ProcessFile modelHis = new ProcessFile();
QueryWrapper wrapper = new QueryWrapper();
wrapper.eq("P_ID", pid);
wrapper.eq("TASK_ID", taskId);
List<ProcessFile> hisList = this.baseMapper.selectList(wrapper);
if (!hisList.isEmpty()) {
modelHis = hisList.get(0);
StringBuffer downloadFileUrl = new StringBuffer();
downloadFileUrl.append(downloadUrl).append(modelHis.getEditFilePath() == null ? "" : modelHis.getEditFilePath());
modelHis.setDownLoadUrl(downloadFileUrl.toString());
}
return modelHis;
}
@Override
public List<ProcessFile> modelHisList(String pid) {
QueryWrapper wrapper = new QueryWrapper();
wrapper.eq("P_ID", pid);
return this.baseMapper.selectList(wrapper);
}
@Override
public void replaceFile(String hisId, String replaceId) {
// 找到修改后的文件上传到minio后 将相关信息替换原本的ossFile记录
ProcessFile his = this.getById(hisId);
// 找到最新的文件记录 上传到minio
LambdaQueryWrapper<OnlineFileLog> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(OnlineFileLog::getHisId, hisId);
wrapper.eq(OnlineFileLog::getValidFlag, "0");
wrapper.orderByDesc(OnlineFileLog::getCreateTime);
List<OnlineFileLog> onlineFileLogList = onlineFileLogDao.selectList(wrapper);
if (CollUtil.isEmpty(onlineFileLogList)) {
throw new JeroBootException("找不到最新的在线编辑文件记录");
}
OnlineFileLog onlineFileLog = onlineFileLogList.get(0);
OSSFile ossFile = ossFileService.getById(onlineFileLog.getAttFileId());
// 获取文件
String path = filePath + ossFile.getUrl();
// 获取上传文件对象
File file = new File(path);
MultipartFile multipartFile = ProcessFileServiceImpl.convert(file);
String savePath = CommonUtils.upload(multipartFile, "", uploadType);
OSSFile replaceFile = ossFileService.getById(replaceId);
if (oConvertUtils.isNotEmpty(savePath) && replaceFile != null) {
// 文件名
String fileName = his.getFileName();
fileName = CommonUtils.getFileName(fileName);
replaceFile.setFileName(fileName);
replaceFile.setUrl(savePath);
ossFileService.updateById(replaceFile);
// 将文件扩展名去掉
String fileTitleName = fileName.substring(0, fileName.lastIndexOf("."));
onlineOfficePdfUtil.convertAndSavePdfFile(fileTitleName, replaceFile.getId(), his.getEditFilePath());
}
}
@Override
public String saveProcessFileToOss(String hisId) {
ProcessFile his = this.getById(hisId);
// 找到最新的文件记录 上传到minio
LambdaQueryWrapper<OnlineFileLog> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(OnlineFileLog::getHisId, hisId);
wrapper.eq(OnlineFileLog::getValidFlag, "0");
wrapper.orderByDesc(OnlineFileLog::getCreateTime);
List<OnlineFileLog> onlineFileLogList = onlineFileLogDao.selectList(wrapper);
OnlineFileLog onlineFileLog = onlineFileLogList.get(0);
OSSFile ossFile = ossFileService.getById(onlineFileLog.getAttFileId());
// 获取文件
String path = filePath + ossFile.getUrl();
// 获取上传文件对象
File file = new File(path);
MultipartFile multipartFile = ProcessFileServiceImpl.convert(file);
String savePath = CommonUtils.upload(multipartFile, "", uploadType);
if (oConvertUtils.isNotEmpty(savePath)) {
// 文件名
String fileName = his.getFileName();
fileName = CommonUtils.getFileName(fileName);
ossFile.setFileName(fileName);
ossFile.setUrl(savePath);
ossFile.setStandardFileType(FieldCommon.FILE_PUBLISH_OF_ORIGINAL);
ossFileService.updateById(ossFile);
// 将文件扩展名去掉
String fileTitleName = fileName.substring(0, fileName.lastIndexOf("."));
onlineOfficePdfUtil.convertAndSavePdfFile(fileTitleName, ossFile.getId(), his.getEditFilePath());
}
return ossFile.getId();
}
@Override
public ProcessFile findEditFileByStandardNo(String standardNo) {
public String findEditFileByStandardNo(String standardNo) {
OSSFile lastDocFileByStandardNo = this.findLastDocFileByStandardNo(standardNo);
if (lastDocFileByStandardNo == null) {
// 没有docx文件则自动生成并返回
return this.saveEditFile(standardNo);
}
// 有的话需要转换为在线编辑的文件
return this.saveEditFileWithOss(lastDocFileByStandardNo.getId());
return lastDocFileByStandardNo.getId();
}
@Override
public OSSFile findLastDocFileByStandardNo(String standardNo) {
LambdaQueryWrapper<LawsEnterpriseStandard> esWrapper = new LambdaQueryWrapper<>();
esWrapper.eq(LawsEnterpriseStandard::getStandardNumber, standardNo);
LawsEnterpriseStandard es = eSService.getOne(esWrapper);
LawsEnterpriseStandard es = esService.getOne(esWrapper);
// 根据企标编号
LambdaQueryWrapper<OSSFile> ossWrapper = new LambdaQueryWrapper<>();
ossWrapper.eq(OSSFile::getStandardId, es.getId());
// 发布稿>修改单>报批稿>送审稿>征求意见稿>草稿
String[] fileTypeArr = {FieldCommon.FILE_PUBLISH_OF_ORIGINAL, FieldCommon.FILE_MODIFICATION_LIST,
FieldCommon.FILE_DRAFT_FOR_REVIEW, FieldCommon.FILE_DRAFT_FOR_APPROVAL,
FieldCommon.FILE_DRAFT_FOR_COMMENT, FieldCommon.FILE_DRAFT};
String[] fileTypeArr = {FieldCommon.FILE_PUBLISH_OF_ORIGINAL, FieldCommon.FILE_DRAFT_FOR_COMMENT};
ossWrapper.in(OSSFile::getStandardFileType, Arrays.asList(fileTypeArr));
List<OSSFile> fileList = ossFileService.list(ossWrapper);
// 根据fileName筛选出doc或docx
@@ -1,32 +1,15 @@
package com.jero.modules.sys.controller;
import cn.hutool.core.io.FileUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.jero.common.constant.CommonConstant;
import com.jero.common.exception.JeroBootException;
import com.jero.common.util.IntekeyUtils;
import com.jero.common.util.MinioUtil;
import com.jero.common.util.obs.ObsBootUtil;
import com.jero.modules.oss.entity.OSSFile;
import com.jero.modules.oss.service.IOSSFileService;
import com.jero.modules.system.util.SysWaterMarkUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.entity.ContentType;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
/**
* @author: Mzaxd
@@ -37,16 +20,10 @@ import java.nio.charset.StandardCharsets;
@RequestMapping("/sys/common")
public class SysCommonController {
@Resource
private SysWaterMarkUtil sysWaterMarkUtil;
@Resource
private IOSSFileService ossFileService;
@Value(value = "${jero.uploadType}")
private String uploadType;
private static final String FILE_VIEW_ERROR = "预览文件失败";
/**
* 下载文件
@@ -57,7 +34,7 @@ public class SysCommonController {
*/
@GetMapping(value = "/download/{id}")
public void download(@PathVariable String id, HttpServletRequest request, HttpServletResponse response) {
downloadAndViewWithWaterMark(id, response);
ossFileService.downloadAndViewWithWaterMark(id, response);
}
/**
@@ -69,7 +46,7 @@ public class SysCommonController {
*/
@GetMapping(value = "/noEncryptDownload/{id}")
public void noEncryptDownload(@PathVariable String id, HttpServletRequest request, HttpServletResponse response) {
downloadAndViewWithWaterMark(id, response);
ossFileService.downloadAndViewWithWaterMark(id, response);
}
/**
@@ -81,7 +58,7 @@ public class SysCommonController {
*/
@GetMapping(value = "/devEncryptDownload/{id}")
public void devEncryptDownload(@PathVariable String id, HttpServletRequest request, HttpServletResponse response) {
downloadAndViewWithWaterMark(id, response);
ossFileService.downloadAndViewWithWaterMark(id, response);
}
/**
@@ -93,96 +70,6 @@ public class SysCommonController {
*/
@GetMapping(value = "/view/{id}")
public void view(@PathVariable String id, HttpServletRequest request, HttpServletResponse response) {
downloadAndViewWithWaterMark(id, response);
}
private void downloadAndViewWithWaterMark(@PathVariable String id, HttpServletResponse response) {
// 查询数据表数据是否存在
LambdaQueryWrapper<OSSFile> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(OSSFile::getId, id);
OSSFile ossFile = ossFileService.getOne(queryWrapper);
if (null == ossFile) {
throw new JeroBootException("文件不存在..");
}
String fileUrl = ossFile.getUrl();
// minio 下载
// 通过MinioUtil查询时 只需要桶后面的路径
String minioUrl = MinioUtil.getMinioUrl();
// Linux/unix 系统下文件路径分隔符为"/" 获取minio与存储桶的路径
minioUrl = minioUrl + MinioUtil.getBucketName() + "/";
String url = fileUrl.replace(minioUrl, "");
// 文件名称
String fileName = ossFile.getFileName();
response.addHeader("Content-Disposition", "attachment;fileName=" + new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));
// 设置强制下载不打开
response.setContentType("application/force-download");
// 然后在您的controller方法中:
InputStream watermarkedInputStream = null;
if (CommonConstant.UPLOAD_TYPE_MINIO.equals(uploadType)) {
try (InputStream inputStream = MinioUtil.getMinioFile(MinioUtil.getBucketName(), url);
OutputStream outputStream = response.getOutputStream()
) {
byte[] buf = new byte[1024];
int len;
if (inputStream == null) {
return;
}
while ((len = inputStream.read(buf)) > 0) {
outputStream.write(buf, 0, len);
}
response.flushBuffer();
} catch (Exception e) {
log.error(e.getMessage());
response.setStatus(404);
}
}else if(CommonConstant.UPLOAD_TYPE_OBS.equals(uploadType)) {
// 华为云 下载
if ("pdf".equalsIgnoreCase(FileUtil.extName(fileName))) {
try (InputStream originalInputStream = ObsBootUtil.getOssFile(fileUrl);
OutputStream outputStream = response.getOutputStream()) {
if (originalInputStream == null) {
return;
}
MultipartFile mFile = new MockMultipartFile(fileName, fileName,
ContentType.APPLICATION_OCTET_STREAM.toString(), originalInputStream);
InputStream inputStream = IntekeyUtils.getInputStreamByDecryptFile(mFile);
watermarkedInputStream = sysWaterMarkUtil.addWatermarkToPdf(inputStream);
byte[] buf = new byte[1024];
int len;
while ((len = watermarkedInputStream.read(buf)) > 0) {
outputStream.write(buf, 0, len);
}
response.flushBuffer();
} catch (Exception e) {
log.error("error:",e);
response.setStatus(404);
}finally {
try {
if (watermarkedInputStream != null){
watermarkedInputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
} else {
try (InputStream inputStream = ObsBootUtil.getOssFile(fileUrl);
OutputStream outputStream = response.getOutputStream()
) {
byte[] buf = new byte[1024];
int len;
while ((len = inputStream.read(buf)) > 0) {
outputStream.write(buf, 0, len);
}
response.flushBuffer();
} catch (Exception e) {
log.error(FILE_VIEW_ERROR + e.getMessage());
response.setStatus(404);
e.printStackTrace();
}
}
}
ossFileService.downloadAndViewWithWaterMark(id, response);
}
}