OnlyOffice在线文档

OnlyOfficeController.java 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. package com.oo.demo.controller;
  2. import com.alibaba.fastjson.JSON;
  3. import com.alibaba.fastjson.JSONObject;
  4. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  5. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  6. import com.oo.demo.entity.OnFile;
  7. import com.oo.demo.entity.Result;
  8. import com.oo.demo.entity.WebsocketResult;
  9. import com.oo.demo.service.FileService;
  10. import com.oo.demo.service.OnFileService;
  11. import com.oo.demo.service.Oprator;
  12. import com.oo.demo.service.WebSocketServer;
  13. import com.oo.onlyoffice.api.OnlyServiceAPI;
  14. import com.oo.onlyoffice.dto.edit.FileUser;
  15. import com.oo.onlyoffice.tools.FileUtil;
  16. import com.oo.onlyoffice.tools.SecurityUtils;
  17. import lombok.extern.slf4j.Slf4j;
  18. import org.springframework.beans.factory.annotation.Autowired;
  19. import org.springframework.beans.factory.annotation.Value;
  20. import org.springframework.data.redis.core.StringRedisTemplate;
  21. import org.springframework.stereotype.Controller;
  22. import org.springframework.ui.Model;
  23. import org.springframework.web.bind.annotation.*;
  24. import org.springframework.web.multipart.MultipartFile;
  25. import org.springframework.web.multipart.commons.CommonsMultipartFile;
  26. import javax.servlet.http.HttpServletRequest;
  27. import javax.servlet.http.HttpServletResponse;
  28. import java.io.PrintWriter;
  29. import java.text.SimpleDateFormat;
  30. import java.util.*;
  31. /**
  32. * @BelongsProject: leaf-onlyoffice
  33. * @BelongsPackage: com.ideayp.leaf.onlyoffice.controller
  34. * @CreateTime: 2022-11-08 18:11
  35. * @Description: TODO
  36. * @Version: 1.0
  37. */
  38. @Controller
  39. @Slf4j
  40. public class OnlyOfficeController {
  41. private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  42. @Autowired
  43. private OnFileService onFileService;
  44. @Autowired
  45. private FileService fileService;
  46. @Autowired
  47. private OnlyServiceAPI onlyServiceAPI;
  48. @Value("${filepath}")
  49. private String filepath;
  50. @RequestMapping("/")
  51. public String filesView(Model model) {
  52. return "/index";
  53. }
  54. /**
  55. * 查询所有的文件
  56. * @param parameter
  57. * @return
  58. */
  59. @RequestMapping("/file/all")
  60. @ResponseBody
  61. public Object file(@RequestParam Map<String, String> parameter) {
  62. int page = Integer.parseInt(parameter.get("page"));
  63. int limit = Integer.parseInt(parameter.get("limit"));
  64. QueryWrapper queryWrapper = new QueryWrapper();
  65. // queryWrapper.notLike("id","MD");
  66. queryWrapper.orderByDesc("created_time");
  67. Page<OnFile> p = new Page<>(page, limit);
  68. p = onFileService.page(p, queryWrapper);
  69. Map<String, Object> map = new HashMap<>();
  70. map.put("code", 0);
  71. map.put("msg", "SUCCESS");
  72. map.put("count", p.getTotal());
  73. map.put("data", p.getRecords());
  74. return map;
  75. }
  76. /**
  77. * 文件上传
  78. * @param file
  79. * @param caseId
  80. * @return
  81. */
  82. @PostMapping("/files/upload/{caseId}")
  83. @ResponseBody
  84. public Object upload(@RequestParam("file") MultipartFile[] file, @PathVariable(required = true) String caseId) {
  85. List<OnFile> result = new ArrayList<>();
  86. int i = 0;
  87. for (MultipartFile multipartFile : file) {
  88. CommonsMultipartFile commonsMultipartFile = (CommonsMultipartFile) multipartFile;
  89. String filename = multipartFile.getOriginalFilename();
  90. // 获取文件后缀
  91. String suffix = filename.substring(filename.lastIndexOf(".") + 1);
  92. String fileId = "";
  93. try {
  94. fileId = onFileService.saveFile(commonsMultipartFile.getBytes(), suffix);
  95. } catch (Exception e) {
  96. e.printStackTrace();
  97. }
  98. OnFile onFile = new OnFile();
  99. onFile.setFileId(fileId);
  100. onFile.setFileName(filename);
  101. onFile.setVersion("1.0.0");
  102. onFile.setCreatedTime(sdf.format(new Date()));
  103. onFile.setFileSize(commonsMultipartFile.getSize());
  104. onFile.setFileType(suffix);
  105. onFile.setFilePath(filepath + "/" + fileId + "." + suffix);
  106. onFile.setCaseId(caseId);
  107. FileUser userSession = SecurityUtils.getUserSession();
  108. if (userSession != null) {
  109. onFile.setUserName(userSession.getName());
  110. onFile.setUserId(userSession.getId());
  111. }
  112. onFileService.save(onFile);
  113. result.add(onFile);
  114. i++;
  115. }
  116. if (file.length == i) {
  117. log.info("文件上传成功");
  118. return result;
  119. }
  120. return Result.error("文件上传失败");
  121. }
  122. @Autowired
  123. StringRedisTemplate stringRedisTemplate;
  124. final static String REDISUSERPREFIX = "user_key:";
  125. /**
  126. * 获取config配置信息
  127. */
  128. @RequestMapping("/onlyOfficeConfig/{mode}/{id}/{userId}/{clientType}/{collaborativeEditing}")
  129. @ResponseBody
  130. public Object openDocument(@PathVariable(required = false) String mode, @PathVariable(required = false) String id, @PathVariable(required = true) Integer userId, @PathVariable(required = false) String clientType, @PathVariable(required = false) Boolean collaborativeEditing, Model model) {//@RequestParam("url") String url,
  131. log.info("only office file:" + id);
  132. OnFile onFile = onFileService.getById(id);
  133. if (onFile == null) {
  134. return Result.error("文件不存在");
  135. }
  136. /**
  137. * 必要步骤
  138. */
  139. FileUser user = new FileUser();
  140. //获取缓存Redis中的用户信息
  141. String userString = stringRedisTemplate.opsForValue().get(REDISUSERPREFIX + userId);
  142. if (userString != null && !"".equals(userString)) {
  143. JSONObject userObj = JSON.parseObject(userString);
  144. String userId1 = userObj.getString("userId");
  145. String userName1 = userObj.getString("userName");
  146. String nickName1 = userObj.getString("nickName");
  147. user.setId(userId1);
  148. user.setName(userName1);
  149. user.setNickname(nickName1);
  150. SecurityUtils.setUserSession(user);
  151. } else {
  152. return Result.error("当前用户不存在");
  153. }
  154. /**
  155. * 必要步骤
  156. */
  157. Map<String, Object> map = new HashMap<>();
  158. map.put("fileId", onFile.getFileId());
  159. map.put("fileName", onFile.getFileName());
  160. map.put("fileType", onFile.getFileType());
  161. map.put("fileSize", onFile.getFileSize());
  162. map.put("version", onFile.getVersion());
  163. map.put("caseId", onFile.getCaseId());
  164. if (clientType == null || clientType == "") {
  165. clientType = "desktop";
  166. }
  167. if (collaborativeEditing == null) {
  168. collaborativeEditing = false;
  169. }
  170. /**
  171. *打开文件获取config配置信息
  172. */
  173. Map config = onlyServiceAPI.openDocument(map, mode, collaborativeEditing, clientType);
  174. SecurityUtils.removeUserSession();
  175. String s = JSON.toJSONString(config);
  176. log.info("only office config:" + s);
  177. return s;
  178. }
  179. // @RequestMapping("/onlyOffice/{mode}/{id}")
  180. // public ModelAndView openDocument(@PathVariable String mode,@PathVariable String id, Model model) {//@RequestParam("url") String url,
  181. // log.info("only office key:" + id);
  182. // OnFile onFile = onFileService.getById(id);
  183. //
  184. //
  185. // /**
  186. // * 必要步骤
  187. // */
  188. // FileUser user = new FileUser();
  189. // user.setId(TempUser.getUserId());
  190. // user.setName(TempUser.getUserName());
  191. // SecurityUtils.setUserSession(user);
  192. // /**
  193. // * 必要步骤
  194. // */
  195. // Map<String,Object> map = new HashMap<>();
  196. // map.put("fileId",onFile.getFileId());
  197. // map.put("fileName",onFile.getFileName());
  198. // map.put("fileType",onFile.getFileType());
  199. // map.put("fileSize",onFile.getFileSize());
  200. // map.put("version",onFile.getVersion());
  201. //
  202. // Map config = onlyServiceAPI.openDocument(map, mode, false);
  203. //
  204. // SecurityUtils.removeUserSession();
  205. //
  206. // String s = JSON.toJSONString(config);
  207. // log.info("only office config:" + s);
  208. // model.addAllAttributes(config);
  209. // return new ModelAndView("onlyOffice");
  210. // }
  211. /**
  212. * 文档编辑服务使用JavaScript API通知callbackUrl,向文档存储服务通知文档编辑的状态。
  213. * 文档编辑服务使用具有正文中的信息的POST请求。
  214. * https://api.onlyoffice.com/editors/callback
  215. * 当我们关闭编辑窗口后,十秒钟左右only office会将它存储的我们的编辑后的文件
  216. * 0 - 找不到具有密钥标识符的文档
  217. * 1 - 正在编辑文档
  218. * 2 - 文档已准备好保存
  219. * 3 - 发生文档保存错误
  220. * 4 - 不作任何更改就关闭文档
  221. * 6 - 正在编辑文档,但保存当前文档状态
  222. * 7 - 强制保存文档时发生错误
  223. */
  224. @RequestMapping("/onlyOffice/save")
  225. @ResponseBody
  226. public void saveFile(HttpServletRequest request, HttpServletResponse response) {
  227. PrintWriter writer = null;
  228. try {
  229. writer = response.getWriter();
  230. // 获取传输的json数据
  231. Scanner scanner = new Scanner(request.getInputStream()).useDelimiter("\\A");
  232. String body = scanner.hasNext() ? scanner.next() : "";
  233. JSONObject jsonObject = JSONObject.parseObject(body);
  234. log.info("{}", jsonObject);
  235. WebsocketResult result = fileService.documentSave(jsonObject);
  236. /*
  237. * status = 1,我们给onlyOffice的服务返回{"error":"0"}的信息。
  238. * 这样onlyOffice会认为回调接口是没问题的,这样就可以在线编辑文档了,否则的话会弹出窗口说明
  239. */
  240. FileUser userSession = SecurityUtils.getUserSession();
  241. String userId = result.getUserId();
  242. if (userSession != null) {
  243. userId = userSession.getId();
  244. }
  245. WebSocketServer.sendInfo(JSON.toJSONString(result.getOnFile()), userId);
  246. if (Objects.nonNull(writer)) {
  247. writer.write("{\"error\":0}");
  248. }
  249. } catch (Exception e) {
  250. e.printStackTrace();
  251. log.info("报错信息" + e.getMessage());
  252. // writer.write("{\"error\":-1}");
  253. writer.write("{\"error\":0}");
  254. }
  255. }
  256. @PostMapping("/save/{id}")
  257. @ResponseBody
  258. public Object save(@PathVariable(required = false) String id) {
  259. OnFile onFile = onFileService.getById(id);
  260. if (onFile == null) {
  261. return Result.error("文件不存在,保存失败");
  262. }
  263. /**
  264. * 必要步骤
  265. */
  266. try {
  267. FileUser user = new FileUser();
  268. user.setId(Oprator.getUserId());
  269. user.setName(Oprator.getUserName());
  270. SecurityUtils.setUserSession(user);
  271. String key = onlyServiceAPI.getKey(onFile.getFileId());
  272. String msg = onlyServiceAPI.save(key, Oprator.getUserId());
  273. SecurityUtils.removeUserSession();
  274. OnFile fileInfo = new OnFile();
  275. fileInfo.setFileId(id);
  276. fileInfo.setFileName(onFile.getFileName());
  277. fileInfo.setFileType(onFile.getFileType());
  278. fileInfo.setFilePath(filepath + "/" + id + "." + onFile.getFileType());
  279. return fileInfo;
  280. } catch (Exception e) {
  281. return Result.error("保存失败");
  282. }
  283. }
  284. @RequestMapping("/converted")
  285. public void converted(String id, String suffix, HttpServletResponse response) {
  286. try {
  287. OnFile onFile = onFileService.getById(id);
  288. String title = onFile.getFileName().replace(onFile.getFileType(), suffix);
  289. String path = onlyServiceAPI.converted(onFile.getFileType(), onFile.getFileId(), suffix, title, null);
  290. FileUtil.downloadAttachment(path, title, response);
  291. } catch (Exception e) {
  292. e.printStackTrace();
  293. }
  294. }
  295. @PostMapping("/del")
  296. @ResponseBody
  297. public Object delFile(String id) {
  298. try {
  299. onFileService.removeFile(id);
  300. return Result.OK("删除成功", "fileTable");
  301. } catch (Exception e) {
  302. e.printStackTrace();
  303. }
  304. return Result.error("删除失败");
  305. }
  306. /**
  307. * @param id
  308. * @param isBrowser 用来判断是否是oo服务的回调下载 1.没有值 = oo服务回调下载。2.有值 = 页面手动下载
  309. * @param response
  310. */
  311. @RequestMapping("/download/{id}")
  312. public void download(@PathVariable String id, String isBrowser, HttpServletResponse response) {
  313. try {
  314. onFileService.download(id, isBrowser, response);
  315. } catch (Exception e) {
  316. e.printStackTrace();
  317. }
  318. }
  319. }