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
相关推荐
Struggler2811 分钟前
pinia-基于monorepo的项目结构管理
前端
Struggler2815 分钟前
SSE的使用
前端
用户58061393930012 分钟前
前端文件下载实现深度解析:Blob与ObjectURL的完美协作
前端
Lin866615 分钟前
Vue 3 + TypeScript 组件类型推断失败问题完整解决方案
前端
coding随想15 分钟前
从零开始:前端开发者的SEO优化入门与实战
前端
前端工作日常18 分钟前
我理解的JSBridge
前端
Au_ust18 分钟前
前端模块化
前端
顺丰同城前端技术团队18 分钟前
还不会用 Charles?最后一遍了啊!
前端
BUG收容所所长19 分钟前
二分查找的「左右为难」:如何优雅地找到数组中元素的首尾位置
前端·javascript·算法
彬师傅20 分钟前
geojson、csv、json 数据加载
前端