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

发布于:2025-05-01 ⋅ 阅读:(20) ⋅ 点赞:(0)

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

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

文件名字 editer.vue

<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 代码

    @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());
        }
    }

    @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());
        }
    }
    /**
     * 还原版本
     *
     * @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());
        }
    }
    /**
     * 修改历史
     *
     * @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 代码

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

    Map<String, Object> editHistory(OnlyofficeRequestDTO params);

3.3 serviceImpl 代码

       @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;
    }

    @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;
    }
    @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;
    }
 @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公共方法代码

  /**
     * 根据请求类型执行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);
        }
    }

 /**
     * 获取授权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;
    }

    /**
     * 执行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;
        }
    }
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/"
/**
 * 获取授权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.可以参考此文章优化代码

https://www.cnblogs.com/gamepen/p/17849005.html

网站公告

今日签到

点亮在社区的每一天
去签到