|
@@ -1,33 +1,28 @@
|
|
|
package com.github.jfcloud.excel.editor.docdeal.controller;
|
|
package com.github.jfcloud.excel.editor.docdeal.controller;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+import cn.hutool.core.io.IoUtil;
|
|
|
|
|
+import cn.hutool.core.io.file.FileNameUtil;
|
|
|
|
|
+import cn.hutool.core.lang.Pair;
|
|
|
|
|
+import cn.hutool.core.util.StrUtil;
|
|
|
|
|
+import cn.hutool.http.HttpResponse;
|
|
|
|
|
+import cn.hutool.http.HttpUtil;
|
|
|
import com.alibaba.fastjson.JSON;
|
|
import com.alibaba.fastjson.JSON;
|
|
|
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
|
|
-import com.github.jfcloud.excel.editor.docdeal.bean.Document;
|
|
|
|
|
-import com.github.jfcloud.excel.editor.docdeal.bean.FileUpload;
|
|
|
|
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
|
|
+import com.amazonaws.services.s3.model.S3Object;
|
|
|
|
|
+import com.github.jfcloud.excel.editor.docdeal.bean.*;
|
|
|
|
|
+import com.github.jfcloud.excel.editor.docdeal.constant.CommandEnum;
|
|
|
import com.github.jfcloud.excel.editor.docdeal.constant.DocumentConstants;
|
|
import com.github.jfcloud.excel.editor.docdeal.constant.DocumentConstants;
|
|
|
-import com.github.jfcloud.excel.editor.docdeal.constant.ErrorCodeEnum;
|
|
|
|
|
-import com.github.jfcloud.excel.editor.docdeal.exception.DocumentException;
|
|
|
|
|
|
|
+import com.github.jfcloud.excel.editor.docdeal.constant.DocumentStatus;
|
|
|
import com.github.jfcloud.excel.editor.docdeal.oss.OssProperties;
|
|
import com.github.jfcloud.excel.editor.docdeal.oss.OssProperties;
|
|
|
import com.github.jfcloud.excel.editor.docdeal.oss.service.OssTemplate;
|
|
import com.github.jfcloud.excel.editor.docdeal.oss.service.OssTemplate;
|
|
|
-import com.github.jfcloud.excel.editor.docdeal.service.DocumentService;
|
|
|
|
|
import com.github.jfcloud.excel.editor.docdeal.service.FileUploadService;
|
|
import com.github.jfcloud.excel.editor.docdeal.service.FileUploadService;
|
|
|
-import com.github.jfcloud.excel.editor.docdeal.utils.FileUtil;
|
|
|
|
|
-import com.github.jfcloud.excel.editor.docdeal.utils.Md5Utils;
|
|
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.apache.commons.io.FilenameUtils;
|
|
import org.apache.commons.io.FilenameUtils;
|
|
|
-import org.apache.commons.io.IOUtils;
|
|
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
-import org.hashids.Hashids;
|
|
|
|
|
-import org.json.simple.JSONObject;
|
|
|
|
|
-import org.json.simple.parser.JSONParser;
|
|
|
|
|
-import org.json.simple.parser.ParseException;
|
|
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
|
-import org.springframework.http.HttpStatus;
|
|
|
|
|
-import org.springframework.http.ResponseEntity;
|
|
|
|
|
import org.springframework.stereotype.Controller;
|
|
import org.springframework.stereotype.Controller;
|
|
|
-import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
import org.springframework.ui.Model;
|
|
import org.springframework.ui.Model;
|
|
|
import org.springframework.web.bind.annotation.*;
|
|
import org.springframework.web.bind.annotation.*;
|
|
|
import org.springframework.web.client.RestTemplate;
|
|
import org.springframework.web.client.RestTemplate;
|
|
@@ -35,290 +30,267 @@ import org.springframework.web.multipart.MultipartFile;
|
|
|
|
|
|
|
|
import javax.servlet.http.HttpServletRequest;
|
|
import javax.servlet.http.HttpServletRequest;
|
|
|
import javax.servlet.http.HttpServletResponse;
|
|
import javax.servlet.http.HttpServletResponse;
|
|
|
-import java.io.*;
|
|
|
|
|
|
|
+import java.io.ByteArrayInputStream;
|
|
|
|
|
+import java.io.IOException;
|
|
|
import java.util.Date;
|
|
import java.util.Date;
|
|
|
-import java.util.HashMap;
|
|
|
|
|
-import java.util.Map;
|
|
|
|
|
-import java.util.Scanner;
|
|
|
|
|
|
|
+import java.util.List;
|
|
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
@Slf4j
|
|
@Slf4j
|
|
|
@Controller
|
|
@Controller
|
|
|
public class FileController {
|
|
public class FileController {
|
|
|
- @Value("${files.savePath}")
|
|
|
|
|
- private String filePath;
|
|
|
|
|
- @Value("${files.docservice.url.site}")
|
|
|
|
|
- private String officeUrl;
|
|
|
|
|
- @Value("${files.docservice.url.command}")
|
|
|
|
|
- private String officeCommand;
|
|
|
|
|
- @Autowired
|
|
|
|
|
- private DocumentService documentService;
|
|
|
|
|
- @Autowired
|
|
|
|
|
- private FileUploadService uploadService;
|
|
|
|
|
@Autowired
|
|
@Autowired
|
|
|
RestTemplate restTemplate;
|
|
RestTemplate restTemplate;
|
|
|
@Autowired
|
|
@Autowired
|
|
|
OssTemplate ossTemplate;
|
|
OssTemplate ossTemplate;
|
|
|
@Autowired
|
|
@Autowired
|
|
|
OssProperties ossProperties;
|
|
OssProperties ossProperties;
|
|
|
|
|
+ @Value("${files.docservice.url.site}")
|
|
|
|
|
+ private String officeUrl;
|
|
|
|
|
+ @Value("${files.docservice.url.command}")
|
|
|
|
|
+ private String officeCommand;
|
|
|
|
|
+ @Value("${document.server.url}")
|
|
|
|
|
+ private String serverUrl;
|
|
|
|
|
|
|
|
-
|
|
|
|
|
- @ResponseBody
|
|
|
|
|
- @GetMapping("/syncOss")
|
|
|
|
|
- @Transactional(rollbackFor = Exception.class)
|
|
|
|
|
- public ResponseEntity<Object> syncOss(@RequestParam(required = false) String bucket,@RequestParam String objectName) {
|
|
|
|
|
- int count = uploadService.count(new LambdaQueryWrapper<FileUpload>()
|
|
|
|
|
- .eq(FileUpload::getFile_name, objectName));
|
|
|
|
|
- if(count>=1){
|
|
|
|
|
- return new ResponseEntity<>(objectName, HttpStatus.OK);
|
|
|
|
|
- }
|
|
|
|
|
- String fileName = FilenameUtils.getName(objectName);
|
|
|
|
|
- if(new File(filePath+fileName).exists()){
|
|
|
|
|
- fileName = FilenameUtils.getBaseName(objectName)+"_"+System.currentTimeMillis()+"."+FilenameUtils.getExtension(objectName);
|
|
|
|
|
- }
|
|
|
|
|
- try(InputStream is = ossTemplate.getObject(StringUtils.isNotBlank(bucket)?bucket:ossProperties.getBucketName(),objectName).getObjectContent();
|
|
|
|
|
- OutputStream ous=new FileOutputStream(filePath+ fileName)) {
|
|
|
|
|
- IOUtils.copy(is,ous);
|
|
|
|
|
- FileUpload upload = new FileUpload();
|
|
|
|
|
- upload.setUpload_date(new Date());
|
|
|
|
|
- upload.setFile_type(fileName.substring(fileName.indexOf(".")));
|
|
|
|
|
- upload.setFile_path(filePath);
|
|
|
|
|
- upload.setFile_name(fileName);
|
|
|
|
|
- upload.setFile_size(0L);
|
|
|
|
|
- uploadService.save(upload);
|
|
|
|
|
- return new ResponseEntity<>(upload, HttpStatus.OK);
|
|
|
|
|
- }catch (Exception e){
|
|
|
|
|
- log.error("文件同步失败",e);
|
|
|
|
|
- throw new RuntimeException();
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private FileUploadService uploadService;
|
|
|
|
|
|
|
|
@ResponseBody
|
|
@ResponseBody
|
|
|
@PostMapping(value = "upload")
|
|
@PostMapping(value = "upload")
|
|
|
- public ResponseEntity<Object> upload(MultipartFile file, HttpServletRequest request) throws Exception {
|
|
|
|
|
|
|
+ public String upload(@RequestPart("file") MultipartFile file, @RequestParam(required = false) String bucket) throws Exception {
|
|
|
if (file.isEmpty()) {
|
|
if (file.isEmpty()) {
|
|
|
throw new Exception("上传文件不能为空");
|
|
throw new Exception("上传文件不能为空");
|
|
|
}
|
|
}
|
|
|
- FileUpload upload = new FileUpload();
|
|
|
|
|
|
|
+
|
|
|
String fileName = file.getOriginalFilename();
|
|
String fileName = file.getOriginalFilename();
|
|
|
-// if (!fileName.endsWith("xls") && !fileName.endsWith("xlsx")) {
|
|
|
|
|
-// throw new Exception("请上传Excel文件");
|
|
|
|
|
-// }
|
|
|
|
|
- //更新保存文件信息到数据库
|
|
|
|
|
- try(InputStream is = file.getInputStream();OutputStream osm = new FileOutputStream(filePath + file.getOriginalFilename());){
|
|
|
|
|
- FileUtil.saveFile(file.getInputStream(), osm);
|
|
|
|
|
|
|
+ log.info("上传文件 {}", fileName);
|
|
|
|
|
+
|
|
|
|
|
+ if (StringUtils.isBlank(bucket)) {
|
|
|
|
|
+ bucket = ossProperties.getBucketName();
|
|
|
}
|
|
}
|
|
|
-// log.info(fileName);
|
|
|
|
|
|
|
+ ossTemplate.putObject(bucket, fileName, file.getInputStream());
|
|
|
|
|
+ log.info("上传文档已保存,bucket={} name={}", bucket, fileName);
|
|
|
|
|
+
|
|
|
|
|
+ FileUpload upload = new FileUpload();
|
|
|
upload.setUpload_date(new Date());
|
|
upload.setUpload_date(new Date());
|
|
|
- log.info("{}",".".indexOf(fileName));
|
|
|
|
|
- log.info("{}",fileName.length());
|
|
|
|
|
- upload.setFile_type(fileName.substring(fileName.indexOf(".")));
|
|
|
|
|
- upload.setFile_path(filePath);
|
|
|
|
|
- upload.setFile_name(file.getOriginalFilename());
|
|
|
|
|
|
|
+ upload.setFile_type(FileNameUtil.getSuffix(fileName));
|
|
|
|
|
+ upload.setFile_path(String.format("/admin/sys-file/%s/%s", bucket, fileName));
|
|
|
|
|
+ upload.setFile_name(fileName);
|
|
|
upload.setFile_size(file.getSize());
|
|
upload.setFile_size(file.getSize());
|
|
|
uploadService.save(upload);
|
|
uploadService.save(upload);
|
|
|
- //操作人
|
|
|
|
|
-// String operator=request.getAttribute(StrUtil.USER_WORKNUMBER).toString();
|
|
|
|
|
-// xxxService.saveUploadCkdExecl(file,operator);
|
|
|
|
|
-
|
|
|
|
|
- return new ResponseEntity<Object>("上传成功", HttpStatus.OK);
|
|
|
|
|
|
|
|
|
|
|
|
+ return "上传成功";
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * \
|
|
|
|
|
* 查询所有上传文档信息接口
|
|
* 查询所有上传文档信息接口
|
|
|
*
|
|
*
|
|
|
* @return
|
|
* @return
|
|
|
*/
|
|
*/
|
|
|
@GetMapping("/filelist")
|
|
@GetMapping("/filelist")
|
|
|
- public ResponseEntity<Object> listFile() {
|
|
|
|
|
-
|
|
|
|
|
- return new ResponseEntity<Object>(uploadService.list(), HttpStatus.OK);
|
|
|
|
|
|
|
+ @ResponseBody
|
|
|
|
|
+ public List<FileUpload> listFile() {
|
|
|
|
|
+ return uploadService.list();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* 下载文档接口
|
|
* 下载文档接口
|
|
|
|
|
+ *
|
|
|
* @param name
|
|
* @param name
|
|
|
* @param response
|
|
* @param response
|
|
|
*/
|
|
*/
|
|
|
@GetMapping("/download")
|
|
@GetMapping("/download")
|
|
|
- public void download(String name, HttpServletResponse response) {
|
|
|
|
|
|
|
+ public void download(@RequestParam String name,
|
|
|
|
|
+ @RequestParam(required = false) String bucket,
|
|
|
|
|
+ HttpServletResponse response) {
|
|
|
|
|
+ if (StrUtil.isBlank(bucket)) {
|
|
|
|
|
+ bucket = ossProperties.getBucketName();
|
|
|
|
|
+ }
|
|
|
|
|
+ log.info("==> 下载文档: name={}, bucket={}", name, bucket);
|
|
|
try {
|
|
try {
|
|
|
- FileUtil.downLoadFile(name,filePath,response);
|
|
|
|
|
|
|
+ S3Object s3Object = ossTemplate.getObject(bucket, name);
|
|
|
|
|
+ IoUtil.copy(s3Object.getObjectContent(), response.getOutputStream());
|
|
|
} catch (IOException e) {
|
|
} catch (IOException e) {
|
|
|
- e.printStackTrace();
|
|
|
|
|
|
|
+ log.error("文档下载失败 name={}, error={}", name, e.getMessage());
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@GetMapping("/review")
|
|
@GetMapping("/review")
|
|
|
- public String reviewDocFile(@RequestParam(required = false) String bucket, @RequestParam(required = false) String title,
|
|
|
|
|
- @RequestParam String name, String userName, String userId, Model model) {
|
|
|
|
|
- syncOss(bucket, name);
|
|
|
|
|
- String path = filePath + name;
|
|
|
|
|
-// String name = "cc.docx";
|
|
|
|
|
- Document document = documentService.getDocument(documentService.buildDocument(path, name));
|
|
|
|
|
- if (org.springframework.util.StringUtils.hasLength(title)) {
|
|
|
|
|
- document.setTitle(title);
|
|
|
|
|
- }
|
|
|
|
|
- Map<String, Object> map = new HashMap<>();
|
|
|
|
|
- map.put("chat", true);
|
|
|
|
|
- map.put("comment", true);
|
|
|
|
|
- map.put("copy", true);
|
|
|
|
|
- map.put("download", true);
|
|
|
|
|
- map.put("edit", false);
|
|
|
|
|
- map.put("fillForms", false);
|
|
|
|
|
- map.put("modifyContentControl", true);
|
|
|
|
|
- map.put("modifyFilter", true);
|
|
|
|
|
- map.put("print", true);
|
|
|
|
|
- map.put("review", false);
|
|
|
|
|
- map.put("reviewGroups", null);
|
|
|
|
|
- map.put("commentGroups", null);
|
|
|
|
|
- map.put("userInfoGroups", null);
|
|
|
|
|
- document.setPermissions(map);
|
|
|
|
|
|
|
+ public String reviewDocFile(@RequestParam(required = false) String bucket,
|
|
|
|
|
+ @RequestParam(required = false) String title,
|
|
|
|
|
+ @RequestParam String name,
|
|
|
|
|
+ @RequestParam String userId,
|
|
|
|
|
+ @RequestParam String userName,
|
|
|
|
|
+ Model model) {
|
|
|
|
|
+ log.info("==> 预览文档 bucket: {}, name: {}", bucket, name);
|
|
|
|
|
+
|
|
|
|
|
+ Pair<Document, DocumentEditParam> pair = docPair(bucket, title, name, userId, userName);
|
|
|
|
|
+ Document document = pair.getKey();
|
|
|
model.addAttribute("document", document);
|
|
model.addAttribute("document", document);
|
|
|
- // 如果该格式不支持编辑,则返回预览页面
|
|
|
|
|
- if (!documentService.canEdit(document)) {
|
|
|
|
|
- return "/demo";
|
|
|
|
|
|
|
+ model.addAttribute("documentEditParam", pair.getValue());
|
|
|
|
|
+
|
|
|
|
|
+ if (document.getFileType().equals("xls") || document.getFileType().equals("xlsx")) {
|
|
|
|
|
+ return "/viewerExcel";
|
|
|
}
|
|
}
|
|
|
- model.addAttribute("documentEditParam", documentService.buildDocumentEditParam(userId, userName, name));
|
|
|
|
|
return "/viewer";
|
|
return "/viewer";
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- @GetMapping("/reviewExcel")
|
|
|
|
|
- public String reviewExcel(@RequestParam(required = false) String bucket, @RequestParam(required = false) String title,
|
|
|
|
|
- @RequestParam String name, String userName, String userId, Model model) {
|
|
|
|
|
- syncOss(bucket, name);
|
|
|
|
|
- String path = filePath + name;
|
|
|
|
|
-// String name = "cc.docx";
|
|
|
|
|
- Document document = documentService.getDocument(documentService.buildDocument(path, name));
|
|
|
|
|
- if (org.springframework.util.StringUtils.hasLength(title)) {
|
|
|
|
|
- document.setTitle(title);
|
|
|
|
|
- }
|
|
|
|
|
- model.addAttribute("document", document);
|
|
|
|
|
- // 如果该格式不支持编辑,则返回预览页面
|
|
|
|
|
- if (!documentService.canEdit(document)) {
|
|
|
|
|
- return "/demo";
|
|
|
|
|
|
|
+ private Pair<Document, DocumentEditParam> docPair(String bucket, String title, String name,
|
|
|
|
|
+ String userId, String userName) {
|
|
|
|
|
+ String downloadUrl = String.format(DocumentConstants.OFFICE_API_DOC_FILE, serverUrl, name);
|
|
|
|
|
+ if (StrUtil.isNotBlank(bucket)) {
|
|
|
|
|
+ downloadUrl += "&bucket=" + bucket;
|
|
|
}
|
|
}
|
|
|
- model.addAttribute("documentEditParam", documentService.buildDocumentEditParam(userId, userName, name));
|
|
|
|
|
- return "/viewerExcel";
|
|
|
|
|
|
|
+
|
|
|
|
|
+ title = StrUtil.isBlank(title) ? name : title;
|
|
|
|
|
+ bucket = StrUtil.isBlank(bucket) ? ossProperties.getBucketName() : bucket;
|
|
|
|
|
+
|
|
|
|
|
+ Document document = Document.builder()
|
|
|
|
|
+ .key(FilenameUtils.getBaseName(name))
|
|
|
|
|
+ .title(title)
|
|
|
|
|
+ .fileType(FilenameUtils.getExtension(name))
|
|
|
|
|
+ .url(downloadUrl)
|
|
|
|
|
+ .permissions(new JSONObject()
|
|
|
|
|
+ .fluentPut("chat", true)
|
|
|
|
|
+ .fluentPut("comment", true)
|
|
|
|
|
+ .fluentPut("copy", true)
|
|
|
|
|
+ .fluentPut("download", true)
|
|
|
|
|
+ .fluentPut("edit", false)
|
|
|
|
|
+ .fluentPut("fillForms", false)
|
|
|
|
|
+ .fluentPut("modifyContentControl", true)
|
|
|
|
|
+ .fluentPut("modifyFilter", true)
|
|
|
|
|
+ .fluentPut("print", true)
|
|
|
|
|
+ .fluentPut("review", false)
|
|
|
|
|
+ .fluentPut("reviewGroups", null)
|
|
|
|
|
+ .fluentPut("commentGroups", null)
|
|
|
|
|
+ .fluentPut("userInfoGroups", null))
|
|
|
|
|
+ .build();
|
|
|
|
|
+ log.info("document: {}", JSON.toJSONString(document));
|
|
|
|
|
+
|
|
|
|
|
+ DocumentEditParam param = DocumentEditParam.builder()
|
|
|
|
|
+ .callbackUrl(String.format(DocumentConstants.OFFICE_API_CALLBACK_BUCKET, serverUrl, name, bucket))
|
|
|
|
|
+ .user(new DocumentEditParam.UserBean(userId, userName))
|
|
|
|
|
+ .build();
|
|
|
|
|
+ log.info("param: {}", JSON.toJSONString(param));
|
|
|
|
|
+
|
|
|
|
|
+ return Pair.of(document, param);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @GetMapping("/reviewExcel")
|
|
|
|
|
+ public String reviewExcel(@RequestParam(required = false) String bucket,
|
|
|
|
|
+ @RequestParam(required = false) String title,
|
|
|
|
|
+ @RequestParam String name,
|
|
|
|
|
+ String userId,
|
|
|
|
|
+ String userName,
|
|
|
|
|
+ Model model) {
|
|
|
|
|
+ return reviewDocFile(bucket, title, name, userName, userId, model);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@GetMapping("/edit")
|
|
@GetMapping("/edit")
|
|
|
- public String editDocFile(@RequestParam(required = false) String bucket, @RequestParam(required = false) String title,
|
|
|
|
|
- @RequestParam String name, String userName, String userId, Model model) {
|
|
|
|
|
- syncOss(bucket, name);
|
|
|
|
|
- String path = filePath + name;
|
|
|
|
|
-// String name = "cc.docx";
|
|
|
|
|
- Document document = documentService.getDocument(documentService.buildDocument(path, name));
|
|
|
|
|
- if (org.springframework.util.StringUtils.hasLength(title)) {
|
|
|
|
|
- document.setTitle(title);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ public String editDocFile(@RequestParam(required = false) String bucket,
|
|
|
|
|
+ @RequestParam(required = false) String title,
|
|
|
|
|
+ @RequestParam String name,
|
|
|
|
|
+ String userName,
|
|
|
|
|
+ String userId,
|
|
|
|
|
+ Model model) {
|
|
|
|
|
+ log.info("==> 编辑文档 bucket: {}, name: {}", bucket, name);
|
|
|
|
|
+
|
|
|
|
|
+ Pair<Document, DocumentEditParam> pair = docPair(bucket, title, name, userId, userName);
|
|
|
|
|
+ Document document = pair.getKey();
|
|
|
|
|
+ document.getPermissions().clear();
|
|
|
model.addAttribute("document", document);
|
|
model.addAttribute("document", document);
|
|
|
- // 如果该格式不支持编辑,则返回预览页面
|
|
|
|
|
- if (!documentService.canEdit(document)) {
|
|
|
|
|
- return "/demo";
|
|
|
|
|
- }
|
|
|
|
|
- model.addAttribute("documentEditParam", documentService.buildDocumentEditParam(userId, userName, name));
|
|
|
|
|
|
|
+ model.addAttribute("documentEditParam", pair.getValue());
|
|
|
return "/editor";
|
|
return "/editor";
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * 编辑文档时回调接口
|
|
|
|
|
- * @param request
|
|
|
|
|
- * @param response
|
|
|
|
|
- * @throws IOException
|
|
|
|
|
|
|
+ * Only Office 回调接口
|
|
|
|
|
+ * <a href="https://api.onlyoffice.com/zh-CN/docs/docs-api/usage-api/callback-handler/">回调参数</a>
|
|
|
*/
|
|
*/
|
|
|
@RequestMapping("/callback")
|
|
@RequestMapping("/callback")
|
|
|
- public void saveDocumentFile(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
|
|
|
|
- //处理编辑回调逻辑
|
|
|
|
|
- callBack(request, response);
|
|
|
|
|
- String fileName = request.getParameter("fileName");
|
|
|
|
|
- try(InputStream is = new FileInputStream(filePath+ fileName)) {
|
|
|
|
|
- ossTemplate.putObject(ossProperties.getBucketName(),fileName,is);
|
|
|
|
|
- log.info("修改文件{}同步至oss成功",fileName);
|
|
|
|
|
- }catch (Exception e){
|
|
|
|
|
- log.error("文件同步至oss失败",e);
|
|
|
|
|
- throw new RuntimeException();
|
|
|
|
|
|
|
+ @ResponseBody
|
|
|
|
|
+ public DocumentEditCallbackResponse callback(@RequestBody DocumentEditCallback param, HttpServletRequest request) {
|
|
|
|
|
+ String name = request.getParameter("name");
|
|
|
|
|
+ String bucket = request.getParameter("bucket");
|
|
|
|
|
+ log.info("==> onlyoffice 回调 name={}, bucket={}, body={}", name, bucket, JSON.toJSONString(param));
|
|
|
|
|
+
|
|
|
|
|
+ String userIds = param.getActions()
|
|
|
|
|
+ .stream()
|
|
|
|
|
+ .map(DocumentEditCallback.ActionsBean::getUserid)
|
|
|
|
|
+ .collect(Collectors.joining(", "));
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ switch (param.getStatus()) {
|
|
|
|
|
+ case 0:
|
|
|
|
|
+ log.info("找不到具有对应key的文档 user={}", userIds);
|
|
|
|
|
+ break;
|
|
|
|
|
+ case 1:
|
|
|
|
|
+ log.info("文档正在被编辑 user={}", userIds);
|
|
|
|
|
+ break;
|
|
|
|
|
+ case 2:
|
|
|
|
|
+ case 6:
|
|
|
|
|
+ if (param.getStatus() == 2) {
|
|
|
|
|
+ log.info("文档已准备好保存 user={}", userIds);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ log.info("正在进行强制保存请求 user={}", userIds);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ //更新oss文件
|
|
|
|
|
+ byte[] bytes = HttpUtil.downloadBytes(param.getUrl());
|
|
|
|
|
+ ossTemplate.putObject(bucket, name, new ByteArrayInputStream(bytes));
|
|
|
|
|
+ log.info("文档已保存,bucket={} name={}", bucket, name);
|
|
|
|
|
+ break;
|
|
|
|
|
+ case 3:
|
|
|
|
|
+ log.info("文档保存时发生错误 user={}", userIds);
|
|
|
|
|
+ break;
|
|
|
|
|
+ case 4:
|
|
|
|
|
+ log.info("文档关闭时没有更改 user={}", userIds);
|
|
|
|
|
+ break;
|
|
|
|
|
+ case 7:
|
|
|
|
|
+ log.info("强制保存文档时发生错误 user={}", userIds);
|
|
|
|
|
+ break;
|
|
|
|
|
+ default:
|
|
|
|
|
+ log.info("未知状态 user={}", userIds);
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (Exception ex) {
|
|
|
|
|
+ log.error("文档保存时发生错误 user={} msg={}", userIds, ex.getMessage());
|
|
|
|
|
+ return DocumentEditCallbackResponse.fail();
|
|
|
}
|
|
}
|
|
|
|
|
+ return DocumentEditCallbackResponse.success();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
|
|
+ * 获取文档编辑状态
|
|
|
*
|
|
*
|
|
|
|
|
+ * @param name
|
|
|
* @return
|
|
* @return
|
|
|
*/
|
|
*/
|
|
|
@GetMapping("/editStatus")
|
|
@GetMapping("/editStatus")
|
|
|
- public ResponseEntity<Object> getDoucmentEditStatus(String name) throws ParseException {
|
|
|
|
|
- String url = officeUrl+officeCommand;
|
|
|
|
|
- Map<String,String> map = new HashMap<String,String>();
|
|
|
|
|
- map.put("c", "forcesave");
|
|
|
|
|
- String docFileMd5 = Md5Utils.getFileMd5(new File(filePath+name));
|
|
|
|
|
- if (StringUtils.isBlank(docFileMd5)) {
|
|
|
|
|
- throw new DocumentException(ErrorCodeEnum.DOC_FILE_MD5_ERROR);
|
|
|
|
|
- }
|
|
|
|
|
- String pathShortMd5 = Md5Utils.md5(filePath + name);
|
|
|
|
|
- String nameShortMd5 = Md5Utils.md5(name);
|
|
|
|
|
- Hashids hashids = new Hashids(DocumentConstants.HASH_KEY);
|
|
|
|
|
- // (将路径字符串短md5值 + 名称字符串短md5值) ==> 再转成短id形式 ==> 作为文档的key(暂且认为是不会重复的)
|
|
|
|
|
- String key = hashids.encodeHex(String.format("%s%s%s", docFileMd5,pathShortMd5, nameShortMd5));
|
|
|
|
|
- map.put("key", key);
|
|
|
|
|
- map.put("userdata", "sample userdata");
|
|
|
|
|
- JSONObject obj = (JSONObject) new JSONParser().parse(FileUtil.editStatus(url, JSON.toJSONString(map)));
|
|
|
|
|
- return new ResponseEntity<Object>(obj, HttpStatus.OK);
|
|
|
|
|
|
|
+ @ResponseBody
|
|
|
|
|
+ public JSONObject getDoucmentEditStatus(@RequestParam String name, @RequestParam(required = false) String command) {
|
|
|
|
|
+ log.info("查询文档编辑状态 name={}", name);
|
|
|
|
|
|
|
|
- }
|
|
|
|
|
- /**
|
|
|
|
|
- * 处理在线编辑文档的逻辑
|
|
|
|
|
- * @param request
|
|
|
|
|
- * @param response
|
|
|
|
|
- * @throws IOException
|
|
|
|
|
- */
|
|
|
|
|
- private void callBack(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
|
|
|
|
- PrintWriter writer = null;
|
|
|
|
|
- JSONObject jsonObj = null;
|
|
|
|
|
- log.info("===saveeditedfile------------");
|
|
|
|
|
|
|
+ command = StrUtil.isBlank(command) ? CommandEnum.FORCE_SAVE.getCommand() : command;
|
|
|
|
|
+ JSONObject params = new JSONObject()
|
|
|
|
|
+ .fluentPut("c", command)
|
|
|
|
|
+ .fluentPut("key", name);
|
|
|
|
|
|
|
|
- try {
|
|
|
|
|
- writer = response.getWriter();
|
|
|
|
|
- Scanner scanner = new Scanner(request.getInputStream()).useDelimiter("\\A");
|
|
|
|
|
- String body = scanner.hasNext() ? scanner.next() : "";
|
|
|
|
|
- jsonObj = (JSONObject) new JSONParser().parse(body);
|
|
|
|
|
- log.info("{}",jsonObj);
|
|
|
|
|
- log.info("===saveeditedfile:" + jsonObj.get("status"));
|
|
|
|
|
- /*
|
|
|
|
|
- 0 - no document with the key identifier could be found,
|
|
|
|
|
- 1 - document is being edited,
|
|
|
|
|
- 2 - document is ready for saving,
|
|
|
|
|
- 3 - document saving error has occurred,
|
|
|
|
|
- 4 - document is closed with no changes,
|
|
|
|
|
- 6 - document is being edited, but the current document state is saved,
|
|
|
|
|
- 7 - error has occurred while force saving the document.
|
|
|
|
|
- * */
|
|
|
|
|
- if ((long) jsonObj.get("status") == 2) {
|
|
|
|
|
- FileUtil.callBackSaveDocument(jsonObj,filePath,request, response);
|
|
|
|
|
- }
|
|
|
|
|
- } catch (IOException | ParseException e) {
|
|
|
|
|
- e.printStackTrace();
|
|
|
|
|
- }
|
|
|
|
|
- /*
|
|
|
|
|
- * status = 1,我们给onlyoffice的服务返回{"error":"0"}的信息,这样onlyoffice会认为回调接口是没问题的,这样就可以在线编辑文档了,否则的话会弹出窗口说明
|
|
|
|
|
- * 在线编辑还没有关闭,前端有人下载文档时,强制保存最新内容 当status 是6时说明有人在编辑时下载文档
|
|
|
|
|
- * */
|
|
|
|
|
- log.info("{}",jsonObj.get("status"));
|
|
|
|
|
- if ((long) jsonObj.get("status") == 6) {
|
|
|
|
|
- //处理当文档正在编辑为关闭时,下载文档
|
|
|
|
|
- if (((String)jsonObj.get("userdata")).equals("sample userdata")){
|
|
|
|
|
- FileUtil.callBackSaveDocument(jsonObj,filePath,request, response);
|
|
|
|
|
|
|
+ try (HttpResponse response = HttpUtil.createPost( officeUrl + officeCommand)
|
|
|
|
|
+ .body(params.toJSONString())
|
|
|
|
|
+ .header("Content-Type", "application/json")
|
|
|
|
|
+ .execute()) {
|
|
|
|
|
+
|
|
|
|
|
+ JSONObject responseObj = JSON.parseObject(response.body());
|
|
|
|
|
+ if (CommandEnum.INFO.getCommand().equals(command)) {
|
|
|
|
|
+ DocumentStatus documentStatus = DocumentStatus.getDocumentStatus(responseObj.getInteger("error"));
|
|
|
|
|
+ if (documentStatus != null) {
|
|
|
|
|
+ responseObj.put("msg", documentStatus.getMsg());
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- log.info("====保存失败:");
|
|
|
|
|
- writer.write("{\"error\":1}");
|
|
|
|
|
- } else {
|
|
|
|
|
- //执行删除编辑时下载保存的文件:
|
|
|
|
|
- FileUtil.deleteTempFile(filePath,request.getParameter("fileName"));
|
|
|
|
|
- writer.write("{\"error\":0}");
|
|
|
|
|
|
|
+ log.info("文档({})编辑状态 {}", name, responseObj);
|
|
|
|
|
+ return responseObj;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|