文章目录
- [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