onloyoffice历史版本功能实现,版本恢复功能,编辑器功能实现 springboot+vue2

文章目录

  • [onloyoffice历史版本功能实现,版本恢复功能,编辑器功能实现 springboot+vue2](#onloyoffice历史版本功能实现,版本恢复功能,编辑器功能实现 springboot+vue2)
  • [前提 需要注意把这个 (改成自己服务器的ip或者域名) 改成 自己服务器的域名或者地址](#前提 需要注意把这个 (改成自己服务器的ip或者域名) 改成 自己服务器的域名或者地址)
  • [我使用的onloyoffice版本 8.1.3.4](#我使用的onloyoffice版本 8.1.3.4)
  • [1. onloyoffice服务器部署 搜索其他文章](#1. onloyoffice服务器部署 搜索其他文章)
  • [2. 前段代码 vue 2](#2. 前段代码 vue 2)
    • [2.1 需要注意把这个 (改成自己服务器的ip或者域名) 改成 自己服务器的域名或者地址](#2.1 需要注意把这个 (改成自己服务器的ip或者域名) 改成 自己服务器的域名或者地址)
    • [2.2. openedit getHistoryData 这两个 是调用后端的 接口 改成自己项目的写法 都是 post 请求](#2.2. openedit getHistoryData 这两个 是调用后端的 接口 改成自己项目的写法 都是 post 请求)
    • [2.3 下面是整个页面代码 需要 别的页面进入下面这个页面 入参是 文件id](#2.3 下面是整个页面代码 需要 别的页面进入下面这个页面 入参是 文件id)
    • 举例
    • [进入editer.vue 页面的 页面代码 row.id 是文件id 也就是 onloyoffice 文件id](#进入editer.vue 页面的 页面代码 row.id 是文件id 也就是 onloyoffice 文件id)
      • [文件名字 editer.vue](#文件名字 editer.vue)
  • [3. 后端java 代码](#3. 后端java 代码)
    • [3.1 controller 代码](#3.1 controller 代码)
    • [3.2 service 代码](#3.2 service 代码)
    • [3.3 serviceImpl 代码](#3.3 serviceImpl 代码)
    • 3.3公共方法代码
  • 4.效果图
  • 5.可以参考此文章优化代码

onloyoffice历史版本功能实现,版本恢复功能,编辑器功能实现 springboot+vue2

前提 需要注意把这个 (改成自己服务器的ip或者域名) 改成 自己服务器的域名或者地址

我使用的onloyoffice版本 8.1.3.4

1. onloyoffice服务器部署 搜索其他文章

2. 前段代码 vue 2

2.1 需要注意把这个 (改成自己服务器的ip或者域名) 改成 自己服务器的域名或者地址

2.2. openedit getHistoryData 这两个 是调用后端的 接口 改成自己项目的写法 都是 post 请求

2.3 下面是整个页面代码 需要 别的页面进入下面这个页面 入参是 文件id

举例

进入editer.vue 页面的 页面代码 row.id 是文件id 也就是 onloyoffice 文件id

csharp 复制代码
//row.id 是文件id 也就是 onloyoffice 文件id
//  /only/editer/   这是页面路由的地址需要在路由里面配置
//页面
openFile(row) {
      window.open('#/only/editer/' + row.id,'_blank');
    },

文件名字 editer.vue

js 复制代码
<template>
  <div>
    <div id="onlyoffice-container" ref="editorContainer"></div>
  </div>
</template>

<script>
import {openedit, getHistoryData, restoreVersion, editHistory} from '@/http/http';

export default {
  name: 'OnlyOfficeEditor',
  props: {
    isEdit: {
      type: Boolean,
      default: true
    }
  },
  data() {
    return {
      docEditor: null,
      currentVersion: null,
      fileToken: null,
      historyData: null,
      historys: [],
      historyList: []
    };
  },
  mounted() {
    this.loadScript().then(() => {
      this.initEditor();
    });
  },
  methods: {
    // 加载脚本
    loadScript() {
      return new Promise((resolve, reject) => {
        const scriptId = "onlyoffice-api-script";
        if (!document.getElementById(scriptId)) {
          const script = document.createElement('script');
          script.id = scriptId;
          script.src = "https://(替换为自己的域名或者ip)/ds-vpath/web-apps/apps/api/documents/api.js";
          script.type = "text/javascript";
          script.onload = resolve;
          script.onerror = reject;
          document.head.appendChild(script);
        } else {
          resolve();
        }
      });
    },
    // 初始化编辑器
    initEditor() {
      if (this.docEditor) {
        this.docEditor.destroyEditor();
        this.docEditor = null;
      }
      openedit({"fileId": this.$route.params.id})
        .then((res) => {
          if (res.code === 200) {
            const config = res.data.openedit;
            config.events = this.getEditorEvents();
            this.docEditor = new window.DocsAPI.DocEditor(this.$refs.editorContainer.id, config);
          }
        })
        .catch(this.handleError);
    },
    // 获取编辑器事件配置
    getEditorEvents() {
      return {
        onRequestHistory: this.handleRequestHistory,
        onRequestHistoryClose: this.handleRequestHistoryClose,
        onRequestHistoryData: this.handleRequestHistoryData,
        onRequestRestore: this.handleRequestRestore
      };
    },
    // 处理请求历史记录事件
    handleRequestHistory() {
      editHistory({"fileId": this.$route.params.id})
        .then((res) => {
          if (res.code === 200) {
            const historyList = res.data.editHistory;
            const fileToken = res.data.fileToken;
            const currentVersion = historyList[historyList.length - 1].version;
            this.docEditor.refreshHistory({
              currentVersion,
              token: fileToken,
              history: historyList
            });
          }
        })
        .catch(this.handleError);
    },
    // 处理关闭历史记录事件
    handleRequestHistoryClose() {
      document.location.reload();
    },
    // 处理请求历史记录数据事件
    handleRequestHistoryData(event) {
      const version = event.data;
      getHistoryData({"fileId": this.$route.params.id, "version": version})
        .then((res) => {
          if (res.code === 200) {
            const historyData = res.data.historyData;
            this.docEditor.setHistoryData(historyData);
          }
        })
        .catch(this.handleError);
    },
    // 处理版本恢复事件
    handleRequestRestore(event) {
      const version = event.data.version;
      restoreVersion({"fileId": this.$route.params.id, "version": version})
        .then((res) => {
          if (res.code === 200) {
            const historyList = res.data.editHistory;
            const currentVersion = historyList[historyList.length - 1].version;
            this.docEditor.refreshHistory({
              currentVersion,
              history: historyList
            });
          }
        })
        .catch(this.handleError);
    },
    // 统一错误处理
    handleError(err) {
      console.log(err);
    },
    // 销毁编辑器
    destroyEditor() {
      if (this.docEditor) {
        this.docEditor.destroyEditor();
        this.docEditor = null;
      }
      if (this.DocsAPIInterval) {
        clearInterval(this.DocsAPIInterval);
      }
    }
  },
  beforeDestroy() {
    this.destroyEditor();
  },
  beforeRouteLeave(to, from, next) {
    this.destroyEditor();
    next();
  },
};
</script>

<style>
iframe {
  border: none;
  width: 100%;
  height: 100vh;
}
</style>

3. 后端java 代码

3.1 controller 代码

java 复制代码
    @PostMapping("/openedit")
    public RestResultDTO openedit(HttpServletRequest request, @RequestBody OnlyofficeRequestDTO params) {
        try {
            if (CommonFunctions.isEmpty(params.getFileId())) {
                throw new BusinessServiceException("非空校验失败");
            }
            Map<String, Object> resultMap  = onlyofficeService.openedit(params);
            return RestResultDTO.success(resultMap);
        } catch (Exception e) {
            LOGGER.error("openedit 方法发生异常: ", e);
            return RestResultDTO.error(ResponseCodeDTO.INTERNAL_SERVER_ERROR, e.getMessage());
        }
    }
java 复制代码
    @PostMapping("/getHistoryData")
    public RestResultDTO getHistoryData(HttpServletRequest request, @RequestBody OnlyofficeRequestDTO params) {
        try {
            if (CommonFunctions.isEmpty(params.getFileId()) || CommonFunctions.isEmpty(params.getVersion())) {
                throw new BusinessServiceException("非空校验失败");
            }
            Map<String, Object> resultMap  = onlyofficeService.getHistoryData(params);
            return RestResultDTO.success(resultMap);
        } catch (Exception e) {
            LOGGER.error("openedit 方法发生异常: ", e);
            return RestResultDTO.error(ResponseCodeDTO.INTERNAL_SERVER_ERROR, e.getMessage());
        }
    }
java 复制代码
    /**
     * 还原版本
     *
     * @return
     * @request: fileId   personId
     */
    @PostMapping("/restoreVersion")
    public RestResultDTO restoreVersion(HttpServletRequest request, @RequestBody OnlyofficeRequestDTO params) {
        try {
            if (CommonFunctions.isEmpty(params.getFileId()) || CommonFunctions.isEmpty(params.getVersion())) {
                throw new BusinessServiceException("非空校验失败");
            }
            Map<String, Object> resultMap  = onlyofficeService.restoreVersion(params);
            return RestResultDTO.success(resultMap);
        } catch (Exception e) {
            LOGGER.error("restoreVersion 方法发生异常: ", e);
            return RestResultDTO.error(ResponseCodeDTO.INTERNAL_SERVER_ERROR, e.getMessage());
        }
    }
java 复制代码
    /**
     * 修改历史
     *
     * @return
     * @request: fileId   personId
     */
    @PostMapping("/editHistory")
    public RestResultDTO editHistory(HttpServletRequest request, @RequestBody OnlyofficeRequestDTO params) {
        try {
            if (CommonFunctions.isEmpty(params.getFileId())) {
                throw new BusinessServiceException("非空校验失败");
            }
            Map<String, Object> resultMap  = onlyofficeService.editHistory(params);
            return RestResultDTO.success(resultMap);
        } catch (Exception e) {
            LOGGER.error("editHistory 方法发生异常: ", e);
            return RestResultDTO.error(ResponseCodeDTO.INTERNAL_SERVER_ERROR, e.getMessage());
        }
    }

3.2 service 代码

java 复制代码
    Map<String, Object> openedit(OnlyofficeRequestDTO params);
java 复制代码
 //获取文件的初始化配置
    Map<String, Object> getHistoryData(OnlyofficeRequestDTO params);
java 复制代码
    Map<String, Object> restoreVersion(OnlyofficeRequestDTO params);
java 复制代码
    Map<String, Object> editHistory(OnlyofficeRequestDTO params);

3.3 serviceImpl 代码

java 复制代码
       @Override
    public Map<String, Object> openedit(OnlyofficeRequestDTO params) {
    String fileId = params.getFileId();
        String permissionType = "";
        JSONObject onlyOfficeConfig = null;
        try {
            String result = HttpUtils.executeRequestOnlyoffice(HttpUtils.O_SHAREFILE_URL + fileId + "/openedit", null, null, "UTF-8", "get");
            JSONObject resJsonObject = JSONObject.parseObject(result);
            if (CollectionUtils.isEmpty(resJsonObject)) {
                throw new BusinessServiceException("获取配置文件异常");
            } else if (resJsonObject.getInteger("statusCode") == 200) {
                onlyOfficeConfig = resJsonObject.getJSONObject("response");
            } else if (resJsonObject.getInteger("statusCode") == 500) {
                throw new BusinessServiceException(resJsonObject.getJSONObject("error").getString("message"));
            } else {
                throw new BusinessServiceException("获取配置文件异常");
            }
             //只读
            if ("4".equals(permissionType)) {
                onlyOfficeConfig.getJSONObject("editorConfig").put("mode", "view");
            }
        } catch (Exception e) {
            LOGGER.error("解析JSON响应失败", e);
            throw new BusinessServiceException("", e);
        }
        // 使用 Map 封装多个 JSON 对象
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("openedit", onlyOfficeConfig);
        return resultMap;
    }
java 复制代码
    @Override
    public Map<String, Object> getHistoryData(OnlyofficeRequestDTO params) {
        String fileId = params.getFileId();
        String version = params.getVersion();
        JSONObject responseArray = null;
        try {
            String result = HttpUtils.executeRequestOnlyoffice(HttpUtils.O_FILES_URL + "/edit-diff-url?fileId=" + fileId + "&version=" + version, null, null, "UTF-8", "get");
            responseArray = JSONObject.parseObject(result);
            if (CollectionUtils.isEmpty(responseArray))  {
                throw new BusinessServiceException("获取配置文件异常");
            }
        } catch (Exception e) {
            LOGGER.error("解析JSON响应失败", e);
            throw new BusinessServiceException("", e);
        }
        // 使用 Map 封装多个 JSON 对象
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("historyData", responseArray);
        return resultMap;
    }
java 复制代码
    @Override
    public Map<String, Object> restoreVersion(OnlyofficeRequestDTO params) {
        String fileId = params.getFileId();
        String version = params.getVersion();
        JSONArray responseArray = null;
        try {
            String result = HttpUtils.executeRequestOnlyoffice(HttpUtils.O_FILES_URL + "/restore-version?fileId=" + fileId + "&version=" + version, null, null, "UTF-8", "put");
            // 尝试解析为 JSONArray
            JSONArray resJsonArray = JSONArray.parseArray(result);
            if (CollectionUtils.isEmpty(resJsonArray))  {
                throw new BusinessServiceException("获取配置文件异常");
            }
        } catch (Exception e) {
            LOGGER.error(" 解析JSON响应失败", e);
            throw new BusinessServiceException("", e);
        }
        Map<String, Object> stringObjectMap = this.editHistory(params);
        return stringObjectMap;
    }
java 复制代码
 @Override
    public Map<String, Object> editHistory(OnlyofficeRequestDTO params) {
        String fileId = params.getFileId();
        JSONArray responseArray = null;
        try {
            String result = HttpUtils.executeRequestOnlyoffice(HttpUtils.O_FILES_URL  + "/edit-history?fileId=" + fileId, null, null, "UTF-8", "get");
            // 尝试解析为 JSONArray
            JSONArray resJsonArray = JSONArray.parseArray(result);
            if (CollectionUtils.isEmpty(resJsonArray))  {
                throw new BusinessServiceException("获取配置文件异常");
            }
            responseArray = resJsonArray;
        } catch (Exception e) {
            LOGGER.error(" 解析JSON响应失败", e);
            throw new BusinessServiceException("", e);
        }
        // 使用 Map 封装多个 JSON 对象
        Map<String, Object> resultMap = new HashMap<>();
        try {
            resultMap.put("fileToken",HttpUtils.renovateAuthorizationToken());
        } catch (Exception e) {
            LOGGER.error(" 获取token失败", e);
            throw new BusinessServiceException("", e);
        }
        resultMap.put("editHistory", responseArray);
        return resultMap;
    }

3.3公共方法代码

java 复制代码
  /**
     * 根据请求类型执行POST或PUT请求
     */
    public static String executeRequestOnlyoffice(String url, Map<String, Object> params, Map<String, String> headers, String encoding, String requestType) throws Exception {
        Map<String, String> headersCover = new HashMap<>();
        String authorizationToken = getAuthorizationToken();
        //覆盖默认请求头
        headersCover.put("Authorization", authorizationToken);
        headersCover.put("Accept", "application/json");
        headersCover.put("Content-Type", "application/json");
        if (headers != null) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                headersCover.put(entry.getKey(), entry.getValue());
            }
        }

        switch (requestType.toLowerCase()) {
            case "get":
                return executeGetRequestCommon(url, params, headersCover, encoding);
            case "post":
                return executePostRequestCommon(url, params, headersCover, encoding);
            case "put":
                return executePutRequestCommon(url, params, headersCover, encoding);
            case "delete":
                return executeDeleteRequestCommon(url, params, headersCover, encoding);
            default:
                throw new IllegalArgumentException("Unsupported request type: " + requestType);
        }
    }
java 复制代码
 /**
     * 获取授权Token
     */
    public static synchronized void refreshAuthorizationToken() throws Exception {
        Map<String, Object> params = new HashMap<>();
        params.put("userName", "");//输入onloyoffice 登录用户名
        params.put("password", "");//输入onloyoffice登录密码

        Map<String, String> headers = new HashMap<>();
        headers.put("Accept", "application/json");
        headers.put("Content-Type", "application/json");

        String result = executePostRequestCommon(HttpUtils.O_AUTH_URL, params, headers, "UTF-8");
        JSONObject jsonObject = JSONObject.parseObject(result);
        HttpUtils.authorizationToken = "Bearer " + jsonObject.getJSONObject("response").getString("token");
    }

    // 获取Token的方法
    @PostConstruct
    public static String getAuthorizationToken() throws Exception {
        if (CommonFunctions.isEmpty(HttpUtils.authorizationToken)) {
            refreshAuthorizationToken();
        }
        return HttpUtils.authorizationToken;
    }
java 复制代码
    /**
     * 执行GET通用请求
     */
    public static String executeGetRequestCommon(String url, Map<String, Object> params, Map<String, String> headers, String encoding) throws Exception {
        // 创建一个带有默认配置的HttpClient,并设置超时时间
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(5000) // 连接超时时间
                .setSocketTimeout(10000) // 读取超时时间
                .build();

        try (CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(requestConfig).build()) {
            // 构建带有查询参数的URL
            if (params != null && !params.isEmpty()) {
                StringBuilder queryString = new StringBuilder(url);
                if (!url.contains("?")) {
                    queryString.append("?");
                } else {
                    queryString.append("&");
                }
                for (String key : params.keySet()) {
                    queryString.append(key).append("=").append(params.get(key)).append("&");
                }
                // 去掉最后一个多余的&
                if (queryString.toString().endsWith("&")) {
                    queryString.setLength(queryString.length() - 1);
                }
                url = queryString.toString();
            }

            HttpGet httpGet = new HttpGet(url);

            // 添加自定义头信息
            if (headers != null) {
                for (Map.Entry<String, String> entry : headers.entrySet()) {
                    httpGet.addHeader(entry.getKey(), entry.getValue());
                }
            }

            // 执行请求并获取响应
            try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
                HttpEntity entity = response.getEntity();
                return entity != null ? EntityUtils.toString(entity, encoding != null ? encoding : "UTF-8") : null;
            }
        } catch (IOException e) {
            logger.error("Error executing GET request to URL: {}. Exception: {}", url, e.getMessage(), e);
            throw e;
        }
    }
java 复制代码
public static String O_FILES_URL = "https://(自己服务器ip或者域名)/Products/Files/Services/WCFService/service.svc"

public static String O_SHAREFILE_URL = "https://(自己服务器ip或者域名)/api/2.0/files/file/"
java 复制代码
/**
 * 获取授权Token
 * @return 授权Token字符串
 * @throws Exception 如果请求或解析失败
 */
    public static String renovateAuthorizationToken() throws Exception {
        // 构造请求参数
        Map<String, Object> params = new HashMap<>();
        params.put("userName", "");//输入onloyoffice 登录用户名
        params.put("password", "");//输入onloyoffice登录密码

        // 构造请求头
        Map<String, String> headers = new HashMap<>();
        headers.put("Accept", "application/json");
        headers.put("Content-Type", "application/json");

        // 执行POST请求并获取结果
        String result = executePostRequestCommon(HttpUtils.O_AUTH_URL, params, headers, "UTF-8");

        // 解析JSON结果
        JSONObject jsonObject = JSONObject.parseObject(result);
        return jsonObject.getJSONObject("response").getString("token");
    }

4.效果图


5.可以参考此文章优化代码

java 复制代码
https://www.cnblogs.com/gamepen/p/17849005.html
相关推荐
艾小逗2 小时前
vue3中的effectScope有什么作用,如何使用?如何自动清理
前端·javascript·vue.js
他҈姓҈林҈4 小时前
使用 Spring Boot 进行开发
spring boot
小小小小宇5 小时前
手写 zustand
前端
Hamm5 小时前
用装饰器和ElementPlus,我们在NPM发布了这个好用的表格组件包
前端·vue.js·typescript
小小小小宇6 小时前
前端国际化看这一篇就够了
前端
大G哥6 小时前
PHP标签+注释+html混写+变量
android·开发语言·前端·html·php
whoarethenext6 小时前
html初识
前端·html
小小小小宇7 小时前
一个功能相对完善的前端 Emoji
前端
m0_627827527 小时前
vue中 vue.config.js反向代理
前端