onloyoffice歷史版本功能實現,版本恢復功能,編輯器功能實現 springboot+vue2

文章目錄

  • 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
      • 文件名字 editer.vue
  • 3. 后端java 代碼
    • 3.1 controller 代碼
    • 3.2 service 代碼
    • 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

//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 代碼

       @Overridepublic 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;}
    @Overridepublic 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;}
    @Overridepublic 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");// 嘗試解析為 JSONArrayJSONArray 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;}
 @Overridepublic 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");// 嘗試解析為 JSONArrayJSONArray 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的方法@PostConstructpublic 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()) {// 構建帶有查詢參數的URLif (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

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/78732.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/78732.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/78732.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

概率論與統計(不確定性分析)主要應用在什么方面?涉及到具體知識是什么?

用戶問的是概率論與統計&#xff08;不確定性分析&#xff09;的主要應用方面&#xff0c;涉及的具體知識以及具體公式。首先&#xff0c;我需要確定概率論與統計在哪些領域有應用&#xff0c;比如工程、金融、醫學、數據科學等等。然后&#xff0c;具體知識部分應該包括概率論…

如何利用快照與備份快速恢復服務器的數據

在服務器上利用**快照&#xff08;Snapshot&#xff09;**和**備份&#xff08;Backup&#xff09;**快速恢復數據&#xff0c;可顯著減少停機時間并確保業務連續性。以下是具體操作步驟和最佳實踐&#xff1a; --- ### **1. 快照&#xff08;Snapshot&#xff09;恢復** **適…

安卓APP開發項目源碼

在移動互聯網蓬勃發展的今天&#xff0c;安卓應用幾乎覆蓋了人們生活的方方面面。從社交、購物&#xff0c;到醫療、教育&#xff0c;APP 的需求呈指數級增長。然而&#xff0c;如何高效、低成本地開發一款質量可靠的安卓應用&#xff0c;仍是很多開發者和團隊關注的核心問題。…

遨游三防|30200mAh、雙露營燈三防平板,見證堆料天花板

在工業4.0與智能化轉型的浪潮中&#xff0c;專業設備對性能、防護及場景適應性的要求日益嚴苛。遨游通訊作為國家級高新技術企業&#xff0c;依托“危、急、特”場景的深耕經驗&#xff0c;推出的旗艦級產品AORO-P300三防平板&#xff0c;以30200mAh超大容量電池、雙露營燈設計…

【Python】Matplotlib:立體永生花繪制

本文代碼部分實現參考自CSDN博客&#xff1a;https://blog.csdn.net/ak_bingbing/article/details/135852038 一、引言 Matplotlib作為Python生態中最著名的可視化庫&#xff0c;其三維繪圖功能可以創造出令人驚嘆的數學藝術。本文將通過一個獨特的參數方程&#xff0c;結合極…

OpenCV 圖形API(57)顏色空間轉換-----將圖像從 RGB 色彩空間轉換為 YUV 色彩空間函數RGB2YUV()

操作系統&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 編程語言&#xff1a;C11 算法描述 將圖像從 RGB 色彩空間轉換為 YUV 色彩空間。 該函數將輸入圖像從 RGB 色彩空間轉換為 YUV。R、G 和 B 通道值的常規范圍是 0 到 255。 在進行線…

Kubernetes(K8S)入門階段詳細指南

Kubernetes(K8S)入門階段詳細指南 一、容器技術基礎:Docker核心操作與理解 1.1 Docker核心操作 鏡像管理: 拉取鏡像:docker pull ubuntu(以Ubuntu為例)查看本地鏡像:docker images刪除鏡像:docker rmi <image_id>容器生命周期管理: 啟動容器:docker run -d -…

AI大模型學習十一:?嘗鮮ubuntu 25.04 桌面版私有化sealos cloud + devbox+minio,實戰運行成功

一、說明 沒意思&#xff0c;devbox私有化不支持&#xff0c;看來這個開源意義不大&#xff0c;和宣傳差距很大啊&#xff0c;那devbox就不用玩 用了ubuntu 25.04&#xff0c;內核為GNU/Linux 6.14.0-15-generic x86_64&#xff0c;升級了部分image&#xff0c;過程曲折啊 se…

[GXYCTF2019]Ping Ping Ping

解題步驟 1、先使用 內斂執行 查看當前的php文件 執行 命令執行 發現空格被過濾 ?ip127.0.0.1$IFS|$IFSwhomi 還有一個點就是這個 執行的命令是不能進行拼接的 可能就是被過濾了 | 所以我們使用 ; 進行繞過一下 空格過濾代替 $IFS ${IFS} ${IFS}$9 //這里$1到$9都可以 $IFS$1…

重溫TCP通信過程

文章目錄 1. 慢啟動2. 擁塞避免 3. 快速重傳和快速恢復 初識tcp報文 我們先來簡單認識一下報文的格式,具體理解需要后面詳細介紹 源端口和目的端口:顧名思義就是標識傳輸雙方的信息首部長度:指的是TCP報頭的長度,換句話來說,我們需要用一個屬性來描述報頭的長度,就說明TCP的報…

力扣HOT100之鏈表:23. 合并 K 個升序鏈表

這道題我是用最淳樸最簡單的思路去做的&#xff0c;用一個while循環持續地將當前遍歷到的最小值加入到合并鏈表中&#xff0c;while循環中使用一個for循環遍歷整個指針數組&#xff0c;將其中的最小值和對應下標記錄下來&#xff0c;并將其值加入到合并鏈表中&#xff0c;同時對…

Spring Boot 支持政策

&#x1f9d1;&#x1f4bb; Spring Boot 支持政策 ?? Andy Wilkinson 于2023年12月7日編輯本頁 32次修訂 &#x1f4cc; 核心政策 &#x1f6e1;? VMware Tanzu 開源支持政策 Spring Boot 針對關鍵錯誤和安全問題提供支持 &#x1f4c6; 版本支持周期 1?? 主要版本&a…

WeakAuras Lua Script TOC BOSS2 <Lord Jaraxxus>

WeakAuras Lua腳本&#xff08;WA 字符串&#xff09; 十字軍試煉老2 加拉克蘇斯 血肉成灰 !WA:2!TIv7VnYrz8UXuDudiDN7PqFfCdTHKYLOeN7sBpXvKDIZf36Kyw7KRT3DYE2Dh7DAwV7CZSoXUOIewf4GdAfgbu13LPasv8MS4diavKoH4RSkIp0phXDT8je5FGYZmZU2oVCqrGLJZUpZZoZZB)EEz1wkr9ewjSU6MD5u…

Spring security詳細上手教學(二)用戶管理

Spring security詳細上手教學&#xff08;二&#xff09;用戶管理 這章節主要學習&#xff1a; 如何使用UserDetails接口描述用戶在鑒權流中使用UserDetailsService自定義的UserDetailsService實現自定義的UserDetailsManager實現在鑒權中使用JdbcUserDetialsManager 在Spri…

網絡安全廠商F5榮登2025 CRN AI 100榜單,釋放AI潛力

近期&#xff0c;網絡安全廠商F5憑借其應用交付和安全技術與前沿的人工智能洞察&#xff0c;成功入選“2025 CRN AI 100 榜單”&#xff0c;并躋身“領導者”之列。這一榮譽的獲得&#xff0c;彰顯了F5在助力企業擁抱人工智能創新的過程中&#xff0c;無需犧牲性能、靈活性或安…

4.RabbitMQ - 延遲消息

RabbitMQ延遲消息 文章目錄 RabbitMQ延遲消息一、延遲消息介紹二、實現2.1 死信交換機2.2 延遲消息插件2.3 取消超時訂單 一、延遲消息介紹 延遲消息&#xff1a;生產者發送消息時指定一個時間&#xff0c;消費者不會立刻收到消息&#xff0c;而是在指定時間后才收到消息 用戶…

5.學習筆記-SpringMVC(P53-P60)

1.響應 &#xff08;1&#xff09;響應頁面 &#xff08;2&#xff09;響應數據&#xff08;異步提交&#xff09;&#xff1a;文本數據、json數據 2.REST風格 (1)REST:表現形式狀態轉換。 (2)傳統風格資源描述形式 3.Restful入門案例 5.基于RESTful頁面數據…

Golang | 搜索表達式

// (( A | B | C ) & D ) | E & (( F | G ) & H )import "strings"// 實例化一個搜索表達式 func NewTermQuery(field, keyword string) *TermQuery {return &TermQuery{Keyword: &Keyword{Field: field, Word: keyword},} }func (tq *TermQuery…

LangChain構建大模型應用之RAG

RAG(Retrieval-augmented Generation 檢索增強生成)是一種結合信息檢索與生成模型的技術,通過動態整合外部知識庫提升大模型輸出的準確性和時效性。其核心思想是在生成答案前,先檢索外部知識庫中的相關信息作為上下文依據,從而突破傳統生成模型的靜態知識邊界。 為什么我們…

Ubuntu 下 Nginx 1.28.0 源碼編譯安裝與 systemd 管理全流程指南

一、環境與依賴準備 為確保編譯順利&#xff0c;我們首先更新系統并安裝必要的編譯工具和庫&#xff1a; sudo apt update sudo apt install -y build-essential \libpcre3 libpcre3-dev \zlib1g zlib1g-dev \libssl-dev \wgetbuild-essential&#xff1a;提供 gcc、make 等基…