使用 Spring Boot 快速構建企業微信 JS-SDK 權限簽名后端服務

使用 Spring Boot 快速構建企業微信 JS-SDK 權限簽名后端服務

本篇文章將介紹如何使用 Spring Boot 快速構建一個用于支持企業微信 JS-SDK 權限校驗的后端接口,并提供一個簡單的 HTML 頁面進行功能測試。適用于需要在企業微信網頁端使用掃一掃、定位、錄音等接口的場景。


一、項目目標

我們希望實現一個包含以下功能的服務:

  • 提供獲取企業微信 access_token 的接口
  • 提供獲取部門成員信息的接口(需要帶 token)
  • 提供 JS-SDK 前端初始化所需簽名參數的接口(wx.config() 配置)
  • 提供一個前端頁面用于測試掃碼、定位、數據表格展示等功能

二、開發環境與依賴

  • JDK 17
  • IDEA
  • Spring Boot 3.2.5
  • Maven 3.x

三、項目結構

DemoAPI
├── pom.xml                       		  // 項目依賴配置
├── src
│   └── main
│       ├── java
│       │   └── org.example
│       │       ├── Main.java             // 項目啟動類
│       │       ├── WeComController.java  // 控制器:處理請求
│       │       └── WeComService.java     // 服務類:處理邏輯
│       └── resources
│           └── static
│               └── index.html            // 測試前端頁面

說明: 本項目未配置 application.yml,Spring Boot 默認即可運行。


四、完整功能實現

第一步:修改 pom.xml,添加 Spring Boot 配置

pom.xml 中我們引入了:

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope></dependency>
</dependencies>

可能遇到的問題:

  • 依賴下載失敗,可通過加速器優化下載速度。
  • 注意 Spring Boot 3.x 要使用 JDK 17+。

第二步:刷新依賴

你可以點擊 IntelliJ 右側 “Maven” 工具窗口的刷新按鈕(🔄),或者右鍵 pom.xml → Add as Maven Project,IDE 會自動下載 Spring Boot 依賴。

第三步:修改你的 Main.java,變成 Spring Boot 啟動類

package org.example;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class Main {public static void main(String[] args) {SpringApplication.run(Main.class, args);}
}

問題回顧: 如果你忘記添加 @SpringBootApplication,將導致 ApplicationContext 啟動失敗,同時控制臺可能提示找不到 Web 容器類(如 Tomcat)或無法創建 Controller Bean。解決辦法:確保注解已加。

第四步:創建一個服務類 WeComService.java

提供 access_token 緩存獲取、jsapi_ticket 緩存、JS-SDK 簽名生成邏輯:

String raw = String.format("jsapi_ticket=%s&noncestr=%s&timestamp=%d&url=%s",jsapiTicket, nonceStr, timestamp, url);MessageDigest md = MessageDigest.getInstance("SHA-1");
md.update(raw.getBytes(StandardCharsets.UTF_8));

注意:

  • 簽名計算必須嚴格按參數順序和格式
  • access_tokenjsapi_ticket 建議緩存,避免頻繁請求
  • 返回格式需包括 appIdtimestampnonceStrsignature

JS-SDK 參數生成

  • 參數組成:jsapi_ticketnonceStrtimestampurl
  • 算法:SHA-1(raw字符串) 生成簽名
  • 返回結構:包含 appIdtimestampnonceStrsignature

第五步:控制器類 WeComController.java

提供如下接口:

接口地址請求方法功能描述
/wecom/tokenGET獲取 access_token
/wecom/department/usersGET獲取指定部門的成員列表
/wecom/js-sdk-configGET獲取 JS-SDK 初始化配置信息

常見問題:

  • 若自動注入失敗,請確認 @Service@RestController 注解是否添加
  • 如果依賴注入失敗,控制臺會提示 UnsatisfiedDependencyException

第六步:創建前端測試頁面 index.html

功能:

  • 獲取 Token 并展示
  • 獲取部門成員并展示表格(含滾動條)
  • 初始化 JS SDK,支持掃碼、定位等測試按鈕
wx.config({appId: config.appId,timestamp: config.timestamp,nonceStr: config.nonceStr,signature: config.signature,jsApiList: ["scanQRCode", "getLocation"]
});wx.ready(function() {alert("? 企業微信 JS SDK 初始化成功");
});

失敗處理:

wx.error(function (err) {alert("? SDK 初始化失敗: " + JSON.stringify(err));
});

頁面結構清晰,所有邏輯通過 window.onload 初始化即可。

第七步:運行你的 Spring Boot 應用

在 IntelliJ 中右鍵 Main.java → Run ‘Main’,或點擊綠色的 ? 按鈕。

看到類似:

Tomcat started on port(s): 8080
Started Main in x.xxx seconds

說明服務已成功啟動。

第八步:界面展示

http://localhost:8080/index.html

在這里插入圖片描述

運行 & 測試(可選)

啟動 Spring Boot 項目后,瀏覽器訪問可訪問下面的接口:

http://localhost:8080/wecom/token
http://localhost:8080/wecom/department/users?id=1


六、常見問題總結

問題說明解決辦法
SDK 初始化失敗簽名無效、時間戳不一致等保證 URL 不帶 #,參數順序正確
Bean 注入失敗啟動報錯找不到 Controller Bean檢查是否缺少 @SpringBootApplication@Service 注解
依賴無法拉取Maven 倉庫連接慢配置阿里云鏡像源,提高穩定性
HTML 無法訪問資源路徑未設置正確放到 resources/static/ 下由 Spring Boot 自動映射

? 錯誤核心提示:

APPLICATION FAILED TO STARTWeb application could not be started as there was no
org.springframework.boot.web.servlet.server.ServletWebServerFactory bean defined in the context.

原因解釋:Spring Boot 應用是一個 Web 項目,但 缺少內嵌 Servlet 容器(比如 Tomcat)依賴,也就是沒有 ServletWebServerFactory,Spring Boot 啟動 Web 服務失敗。

最常見的原因:

  • pom.xml 中 缺失或拼錯了 spring-boot-starter-web 依賴
  • Maven 沒有下載成功依賴(網絡或倉庫問題)
  • 沒有添加 @SpringBootApplication

七、后續可擴展方向

  • 接入企業微信身份認證(OAuth2)
  • 支持更多 JS API(如錄音、語音識別、打開地圖)
  • 使用 Redis 緩存 token,提升性能與健壯性
  • 前后端分離,使用 Vue、React 等框架

八、結語

通過本項目我們實現了從零搭建一個企業微信 JS-SDK 權限校驗服務,具備了完整的后端支持和前端測試頁面。如果想正常使用企業微信的掃描等功能需要在企業微信內部訪問,那么就需要設置 IP 白名單、域名、網頁授權及JS-SDK、企業微信授權登錄和應用主頁等。


九、推薦

Maven Central(Maven 中央倉庫 Web 版)

這是最常用、幾乎所有 Java 開發者都會用的網站 —— 一個圖形化的 Maven 中央倉庫檢索平臺:

👉 網站地址:
🌐 https://mvnrepository.com

使用 Spring Initializr 官網 創建項目(圖形化窗口版)

這個網站會自動幫你生成一個可運行的 Spring Boot 項目,并打包成一個 zip 文件。解壓 zip,然后用 IDEA 打開即可。

👉 地址:
🌐 https://start.spring.io


附錄:完整文件(可自行補全代碼)

pom.xml ?

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>DemoAPI</artifactId><version>1.0-SNAPSHOT</version><packaging>jar</packaging><!-- Spring Boot 父項目 --><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.2.5</version><relativePath/></parent><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><!-- Spring Boot Web 模塊(包含內嵌 Tomcat) --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- 開發工具(自動重啟,非必須) --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
</project>

index.html ?

<!DOCTYPE html>
<html lang="zh">
<head><meta charset="UTF-8"><title>企業微信接口測試</title><style>body {font-family: "微軟雅黑", sans-serif;margin: 20px;}table {border-collapse: collapse;width: 100%;margin-top: 10px;}th, td {border: 1px solid #ccc;padding: 6px 12px;text-align: center;}th {background-color: #f5f5f5;}pre {background-color: #eee;padding: 10px;}.scroll-box {max-height: 160px;overflow-y: auto;border: 1px solid #ccc;}</style><!-- 引入企業微信 JS SDK --><script src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script><script>// 初始化企業微信 JS SDKasync function initWeComJsSdk() {const url = window.location.href.split('#')[0];const res = await fetch('/wecom/js-sdk-config?url=' + encodeURIComponent(url));const config = await res.json();wx.config({beta: true,debug: false,appId: config.appId,timestamp: config.timestamp,nonceStr: config.nonceStr,signature: config.signature,jsApiList: ["scanQRCode", "getLocation"]});wx.ready(function () {console.log("企業微信 JS SDK 就緒");alert("? 企業微信 JS SDK 初始化成功!");document.getElementById('scanBtn').onclick = function () {wx.scanQRCode({needResult: 1,scanType: ["qrCode", "barCode"],success: function (res) {alert("掃碼結果:" + res.resultStr);}});};document.getElementById('locBtn').onclick = function () {wx.getLocation({type: 'wgs84',success: function (res) {alert("當前位置:經度 " + res.longitude + ",緯度 " + res.latitude);}});};});wx.error(function (err) {console.error("JS SDK 初始化失敗:", err);alert("? 企業微信 JS SDK 初始化失敗!\n" + JSON.stringify(err));});}async function getToken() {const res = await fetch('/wecom/token');const token = await res.text();document.getElementById('token').innerText = token;}async function getUsers() {const deptId = document.getElementById('dept').value || '1';const res = await fetch(`/wecom/department/users?id=${deptId}`);const json = await res.json();document.getElementById('result').innerText = JSON.stringify(json, null, 2);if (json.userlist) {renderTable(json.userlist);} else {document.getElementById('userTableBody').innerHTML = "<tr><td colspan='6'>無成員數據</td></tr>";}}function renderTable(users) {const tbody = document.getElementById("userTableBody");tbody.innerHTML = "";users.forEach(user => {const row = document.createElement("tr");row.innerHTML = `<td>${user.name}</td><td>${user.userid}</td><td>${(user.department || []).join(',')}</td><td>${user.isleader === 1 ? '是' : '否'}</td><td>${translateStatus(user.status)}</td><td>${user.telephone || ''}</td>`;tbody.appendChild(row);});}function translateStatus(status) {switch (status) {case 1: return "正常";case 2: return "已禁用";case 4: return "未激活";default: return "未知";}}window.onload = function () {initWeComJsSdk();};</script>
</head>
<body><h1>企業微信接口測試</h1><!-- 獲取 Token -->
<button onclick="getToken()">獲取 Token</button>
<p>Token:<code id="token">(點擊上面按鈕)</code></p><!-- 獲取部門成員 -->
<hr>
<label>部門 ID:</label>
<input type="text" id="dept" value="1">
<button onclick="getUsers()">獲取部門成員</button><!-- 顯示返回數據 -->
<h3>接口返回數據:</h3>
<pre id="result">(點擊按鈕查看 JSON)</pre><!-- 成員列表表格 -->
<h3>成員列表表格:</h3>
<div class="scroll-box"><table><thead><tr><th>姓名</th><th>用戶ID</th><th>部門</th><th>是否領導</th><th>狀態</th><th>座機</th></tr></thead><tbody id="userTableBody"></tbody></table>
</div><!-- 企業微信 JS API 按鈕 -->
<h3>企業微信功能測試:</h3>
<button id="scanBtn">掃一掃</button>
<button id="locBtn">獲取當前位置</button></body>
</html>

Main.java ?

package org.example;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;/*** ==================================================* This class ${NAME} is responsible for [功能描述].** @author Darker* @version 1.0* ==================================================*/@SpringBootApplication
public class Main {public static void main(String[] args) {SpringApplication.run(Main.class, args);}
}

WeComService.java ?

package org.example;import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
import org.springframework.http.ResponseEntity;import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.Formatter;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;import java.time.Instant;/*** ==================================================* This class WeComService is responsible for [功能描述].** @author Darker* @version 1.0* ==================================================*/@Service
public class WeComService {private static final String CORP_ID = "你的企業微信ID";private static final String SECRET = "你的自建應用的Secret";private static final String TOKEN_URL = "https://qyapi.weixin.qq.com/cgi-bin/gettoken";private String accessToken;private long expireTime = 0;// jsapi_ticket(緩存 2 小時)private String jsapiTicket;private long ticketExpire = 0;public String getAccessToken() {long now = Instant.now().getEpochSecond();if (accessToken != null && now < expireTime) {return accessToken;}// 請求新的 tokenRestTemplate restTemplate = new RestTemplate();UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(TOKEN_URL).queryParam("corpid", CORP_ID).queryParam("corpsecret", SECRET);ResponseEntity<WeComTokenResponse> response = restTemplate.getForEntity(builder.toUriString(), WeComTokenResponse.class);WeComTokenResponse body = response.getBody();if (body != null && body.getAccess_token() != null) {this.accessToken = body.getAccess_token();this.expireTime = now + body.getExpires_in() - 60; // 提前60秒過期return accessToken;}throw new RuntimeException("無法獲取 access_token");}public Map<String, Object> getJsSdkConfig(String url) {String jsapiTicket = getJsApiTicket(); // 用下面方法實現String nonceStr = UUID.randomUUID().toString().replace("-", "");long timestamp = System.currentTimeMillis() / 1000;String raw = String.format("jsapi_ticket=%s&noncestr=%s&timestamp=%d&url=%s",jsapiTicket, nonceStr, timestamp, url);String signature;try {MessageDigest md = MessageDigest.getInstance("SHA-1");md.update(raw.getBytes(StandardCharsets.UTF_8));signature = bytesToHex(md.digest());} catch (Exception e) {throw new RuntimeException("簽名失敗", e);}Map<String, Object> result = new HashMap<>();result.put("appId", CORP_ID);result.put("timestamp", timestamp);result.put("nonceStr", nonceStr);result.put("signature", signature);return result;}private String bytesToHex(byte[] bytes) {Formatter formatter = new Formatter();for (byte b : bytes) {formatter.format("%02x", b);}String result = formatter.toString();formatter.close();return result;}public String getJsApiTicket() {long now = System.currentTimeMillis() / 1000;if (jsapiTicket != null && now < ticketExpire) {return jsapiTicket;}String token = getAccessToken();String url = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=" + token;RestTemplate restTemplate = new RestTemplate();Map<String, Object> res = restTemplate.getForObject(url, Map.class);if (res != null && res.get("ticket") != null) {jsapiTicket = (String) res.get("ticket");ticketExpire = now + ((Integer) res.get("expires_in")) - 60;return jsapiTicket;}throw new RuntimeException("獲取 jsapi_ticket 失敗");}// 內部類用于接收 JSON 響應public static class WeComTokenResponse {private String access_token;private int expires_in;public String getAccess_token() {return access_token;}public void setAccess_token(String access_token) {this.access_token = access_token;}public int getExpires_in() {return expires_in;}public void setExpires_in(int expires_in) {this.expires_in = expires_in;}}
}

WeComController.java ?

package org.example;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.web.util.UriComponentsBuilder;/*** ==================================================* This class WeComController is responsible for [功能描述].** @author Darker* @version 1.0* ==================================================*/@RestController
@RequestMapping("/wecom")
public class WeComController {@Autowiredprivate WeComService weComService;// GET 接口:/wecom/token@GetMapping("/token")public String getToken() {return weComService.getAccessToken();}@GetMapping("/department/users")public Object getDepartmentUsers(@RequestParam("id") String departmentId) {String token = weComService.getAccessToken();String url = "https://qyapi.weixin.qq.com/cgi-bin/user/list";UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url).queryParam("access_token", token).queryParam("department_id", departmentId);RestTemplate restTemplate = new RestTemplate();ResponseEntity<Object> response = restTemplate.getForEntity(builder.toUriString(), Object.class);return response.getBody();}// GET 接口:/wecom/js-sdk-config?url=xxx@GetMapping("/js-sdk-config")public Object getJsSdkConfig(@RequestParam("url") String url) {return weComService.getJsSdkConfig(url);}
}

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

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

相關文章

工程師 - FTDI SPI converter

中國網站&#xff1a;FTDIChip- 首頁 UMFT4222EV-D UMFT4222EV-D - FTDI 可以下載Datasheet。 UMFT4222EVUSB2.0 to QuadSPI/I2C Bridge Development Module Future Technology Devices International Ltd. The UMFT4222EV is a development module which uses FTDI’s FT4222H…

rcore day6

批處理系統 (Batch System) 出現于計算資源匱乏的年代&#xff0c;其核心思想是&#xff1a; 將多個程序打包到一起輸入計算機&#xff1b;當一個程序運行結束后&#xff0c;計算機會 自動 執行下一個程序 應用程序難免會出錯&#xff0c;如果一個程序的錯誤導致整個操作系統都…

Linux系統學習Day2——在Linux系統中開發OpenCV

一、OpenCV簡介 OpenCV&#xff08;Open Source Computer Vision Library&#xff09;是一個開源的跨平臺計算機視覺和機器學習庫&#xff0c;廣泛應用于圖像處理、視頻分析、物體檢測等領域。它提供了豐富的算法和高效的工具集&#xff0c;支持C、Python等多種語言&#xff0c…

SAP Overview

SAP—企業運營的數字化引擎 在數字化轉型的浪潮中&#xff0c;SAP以其全面的企業應用軟件套件&#xff0c;為全球企業提供了強大的運營支持。SAP的模塊化解決方案覆蓋了企業運作的每一個關鍵環節&#xff0c;從銷售到倉庫管理&#xff0c;每個模塊都是針對特定業務需求精心設計…

Kafka 中的冪等機制

Kafka 中的 冪等性&#xff08;Idempotence&#xff09; 是生產者端的重要機制&#xff0c;旨在確保即使在網絡抖動、重試、Broker 重啟等情況下&#xff0c;同一條消息不會被重復寫入到 Topic 中。這是實現可靠消息傳遞、避免重復消費的關鍵手段之一。 ? 什么是冪等性&#…

用c語言寫一個linux進程之間通信(聊天)的簡單程序

使用talk 用戶在同一臺機器上talk指令格式如下&#xff1a; ? talk 用戶名ip地址 [用戶終端號] 如果用戶只登錄了一個終端&#xff0c;那么可以不寫用戶終端號&#xff0c;如&#xff1a; talk userlocalhost可以使用who指令來查看當前有哪些用戶登錄&#xff0c;他的終端號…

深入探索Scala:從基礎到進階的全面總結

在大數據技術領域&#xff0c;Scala語言憑借其獨特優勢占據重要地位。它與Spark緊密相連&#xff0c;為大數據計算提供強大支持。今天&#xff0c;讓我們一同深入回顧Scala從基礎到進階的關鍵知識點。 Scala開發環境搭建是入門的第一步&#xff0c;需確保JDK安裝成功&#xff0…

【每日一個知識點】分布式數據湖與實時計算

在現代數據架構中&#xff0c;分布式數據湖&#xff08;Distributed Data Lake&#xff09; 結合 實時計算&#xff08;Real-time Computing&#xff09; 已成為大數據處理的核心模式。數據湖用于存儲海量的結構化和非結構化數據&#xff0c;而實時計算則確保數據能夠被迅速處理…

GPT-5、o3和o4-mini即將到來

原計劃有所變更: 關于我們應有何期待的一些零散想法。 深度研究(Deep Research)確實強大但成本高昂且速度較慢(當前使用o3模型)。即將推出的o4-mini在性能上可能與o3相近,但將突破這些限制,讓全球用戶——甚至免費用戶(盡管會有速率限制)——都能用上世界頂級AI研究助…

Spring Cloud LoadBalancer負載均衡+算法切換

目錄 介紹核心功能負載均衡啟動兩個支付服務訂單模塊引入依賴LoadBalanced 注解啟動訂單服務測試結果 負載均衡算法切換總結 介紹 Spring Cloud LoadBalancer 是 Spring Cloud 提供的客戶端負載均衡解決方案&#xff0c;提供更現代化的 API 和更好的 Spring 生態系統集成。它支…

Chrome 瀏覽器插件收錄

1. Responsive Viewer 可以在同個窗口內&#xff0c;針對同一網站&#xff0c;添加多個不同設備屏幕顯示。 在前端開發&#xff0c;需要多端適配&#xff0c;尤其是移動端響應式適配的網站開發中&#xff0c;可以同時測試多個不同屏幕的適配效果。 2. VisBug 提供工具欄&#x…

SQL 函數概述

SQL 函數概述 SQL 函數可以分為幾大類&#xff0c;不同數據庫系統可能有略微不同的實現。以下是主要的 SQL 函數分類&#xff1a; 1. 聚合函數 (Aggregate Functions) COUNT() - 計算行數 SUM() - 計算總和 AVG() - 計算平均值 MIN() - 找最小值 MAX() - 找最大值 GROUP…

MySQL學習筆記九

第十一章使用數據處理函數 11.1函數 SQL支持函數來處理數據但是函數的可移植性沒有SQL強。 11.2使用函數 11.2.1文本處理函數 輸入&#xff1a; SELECT vend_name,UPPER(vend_name) AS vend_name_upcase FROM vendors ORDER BY vend_name; 輸出&#xff1a; 說明&#…

認識vue中的install和使用場景

寫在前面 install 在實際開發中如果你只是一個簡單的業務實現者&#xff0c;那么大部分時間你是用不到install的&#xff0c;因為你用到的基本上都是別人封裝好的插件、組件、方法、指令等等&#xff0c;但是如果你需要給公司的架構做建設&#xff0c;install就是你避不開的一個…

【SpringCloud】構建分布式系統的利器

一、引言 在當今數字化時代&#xff0c;隨著業務規模的不斷擴大和用戶量的急劇增長&#xff0c;單體應用逐漸暴露出諸多局限性&#xff0c;如可擴展性差、維護困難等。分布式系統應運而生&#xff0c;而 Spring Cloud 則成為了構建分布式系統的熱門框架之一。它提供了一系列豐…

mkdir通配符詳解

在 mkdir 命令中使用通配符可以簡化批量創建目錄的操作。通配符如 {} 和 * 可以用來生成多個目錄名稱&#xff0c;從而減少重復輸入。以下是一些常見的使用方法和示例。 使用 {} 通配符 {} 通配符可以用來生成一系列的目錄名稱&#xff0c;語法如下&#xff1a; mkdir dir_{…

Transformer的Word Embedding

一、Transformer 中的詞嵌入是什么&#xff1f; 1. 定義與作用 ? 詞嵌入&#xff08;Word Embedding&#xff09;&#xff1a;將離散的詞語映射為低維連續向量&#xff0c;捕捉語義和語法信息。 ? 在 Transformer 中的位置&#xff1a; ? 輸入層&#xff1a;每個詞通過嵌入…

Linux 進程間通信:信號機制

Linux 進程間通信&#xff1a;信號機制 在多進程操作系統中&#xff0c;進程之間的通信至關重要&#xff0c;尤其是在Linux系統中&#xff0c;信號&#xff08;Signal&#xff09;作為一種特殊的進程間通信方式&#xff0c;廣泛用于進程之間的協調和控制。信號可以看作是操作系…

基于TRIZ創新方法論的九屏法分析系統

1. 文件頭與庫導入 # -*- coding: utf-8 -*- import streamlit as st import pandas as pd import numpy as np import plotly.graph_objects as go from datetime import datetime from sklearn.ensemble import RandomForestRegressor ??作用??&#xff1a;設置文件編碼…

【LangChain框架組成】 LangChain 技術棧的模塊化架構解析

目錄 整體架構概述 整體架構層級劃分 模塊詳細解析 1. 部署與服務層&#xff08;LangServe & Deployments&#xff09; 2. 應用模板層&#xff08;Templates & Committee Architectures&#xff09; 3. 核心功能層&#xff08;LangChain&#xff09; 4. 社區擴展…