From 94fd4658ea62c63a164a06fd5973432b651a23f3 Mon Sep 17 00:00:00 2001
From: 陈昶聿 <chychen@nbjetron.com>
Date: 星期五, 26 六月 2026 14:41:51 +0800
Subject: [PATCH] 【市一】接入阿里NLP
---
ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java | 2
smartor/src/main/java/com/smartor/common/AliNlpUtil.java | 299 +++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 300 insertions(+), 1 deletions(-)
diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java
index ec9250f..c5e07e7 100644
--- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java
+++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java
@@ -1346,7 +1346,7 @@
Map<String, String> headerMap = new HashMap<>();
headerMap.put("sign", encode);
String result = HttpUtils.sendPostByHeader(wxqqxx.get(3), body, headerMap);
-
+ log.info("銆恎etWXCode銆戝井淇″叕浼楀彿杩斿洖鍙傛暟锛歿}", result);
JSONObject jsonObject = JSONObject.parseObject(result);
String code = (String) jsonObject.toString();
return code;
diff --git a/smartor/src/main/java/com/smartor/common/AliNlpUtil.java b/smartor/src/main/java/com/smartor/common/AliNlpUtil.java
new file mode 100644
index 0000000..967832a
--- /dev/null
+++ b/smartor/src/main/java/com/smartor/common/AliNlpUtil.java
@@ -0,0 +1,299 @@
+package com.smartor.common;
+
+import com.alibaba.fastjson2.JSONArray;
+import com.alibaba.fastjson2.JSONObject;
+import com.aliyuncs.CommonRequest;
+import com.aliyuncs.CommonResponse;
+import com.aliyuncs.DefaultAcsClient;
+import com.aliyuncs.IAcsClient;
+import com.aliyuncs.exceptions.ClientException;
+import com.aliyuncs.exceptions.ServerException;
+import com.aliyuncs.http.MethodType;
+import com.aliyuncs.profile.DefaultProfile;
+import com.aliyuncs.profile.IClientProfile;
+import com.google.gson.Gson;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 闃块噷浜戣嚜鐒惰瑷�澶勭悊锛圢LP锛夊伐鍏风被銆�
+ * <p>
+ * 鏂囨。锛�<a href="https://help.aliyun.com/zh/document_detail/181284.html">NLP 鑷涔犲钩鍙� / 鍩虹鏂囨湰鏈嶅姟</a>
+ * <p>
+ * 璋冪敤鏂瑰紡鍩轰簬 {@code aliyun-java-sdk-alinlp} 鐨� {@link CommonRequest}锛�
+ * 缁熶竴鍚� {@code alinlp.cn-hangzhou.aliyuncs.com} 鍙戦�� POST 璇锋眰锛岀増鏈彿 2020-06-29锛�
+ * 閫氳繃浼犲叆涓嶅悓鐨� {@code Action} 涓� {@code ServiceCode} 璋冪敤鍏蜂綋鑳藉姏銆�
+ * <p>
+ * 閰嶇疆椤癸紙application.yml锛夛細
+ * <pre>
+ * aliyun:
+ * nlp:
+ * access-key-id: ${accessKeyId} # 榛樿澶嶇敤涓昏处鍙� accessKeyId
+ * access-key-secret: ${accessKeySecret}
+ * region-id: cn-hangzhou
+ * domain: alinlp.cn-hangzhou.aliyuncs.com
+ * version: 2020-06-29
+ * read-timeout: 5000
+ * connect-timeout: 3000
+ * </pre>
+ */
+@Slf4j
+@Component
+public class AliNlpUtil {
+
+ /** 闃块噷浜� AccessKey ID锛岄粯璁ゅ鐢ㄤ富璐﹀彿閰嶇疆 */
+ @Value("${aliyun.nlp.access-key-id:${accessKeyId:}}")
+ private String accessKeyId;
+
+ /** 闃块噷浜� AccessKey Secret */
+ @Value("${aliyun.nlp.access-key-secret:${accessKeySecret:}}")
+ private String accessKeySecret;
+
+ /** 鍦板煙 ID锛屽叕鍏变簯鍥哄畾涓� cn-hangzhou */
+ @Value("${aliyun.nlp.region-id:cn-hangzhou}")
+ private String regionId;
+
+ /** 鎺ュ叆鍩熷悕 */
+ @Value("${aliyun.nlp.domain:alinlp.cn-hangzhou.aliyuncs.com}")
+ private String domain = "alinlp.cn-hangzhou.aliyuncs.com";
+
+ /** API 鐗堟湰鍙� */
+ @Value("${aliyun.nlp.version:2020-06-29}")
+ private String version = "2020-06-29";
+
+ /** 璇诲彇瓒呮椂锛堟绉掞級 */
+ @Value("${aliyun.nlp.read-timeout:5000}")
+ private int readTimeout = 5000;
+
+ /** 杩炴帴瓒呮椂锛堟绉掞級 */
+ @Value("${aliyun.nlp.connect-timeout:3000}")
+ private int connectTimeout = 3000;
+
+ // NLP鍦板煙鍥哄畾 cn-hangzhou
+ private static final String REGION_ID = "cn-hangzhou";
+ private static final String PRODUCT = "nlp";
+ private static final String VERSION = "2020-06-08";
+
+ private static final Gson gson = new Gson();
+
+ private IAcsClient client;
+
+ @PostConstruct
+ private void init() {
+// String accessKeyId = "LTAI5tPfc1VJzz7VuhzcBwug";
+// String accessKeySecret = "gG1srKxPFDBNWe2oHfqmK1qsSQkf1e";
+
+ String accessKeyId = "LTAI5t6GBf9nUXfX37CUDi4H";
+ String accessKeySecret = "BtjYAES4yjvde5Lwg46sTqnZefPnOE";
+ String regionId = "cn-hangzhou";
+ if (StringUtils.isBlank(accessKeyId) || StringUtils.isBlank(accessKeySecret)) {
+ log.warn("闃块噷浜� NLP 鏈厤缃� AccessKey锛孉liNlpUtil 灏嗕笉鍙敤");
+ return;
+ }
+ IClientProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
+ this.client = new DefaultAcsClient(profile);
+ }
+
+ // ============================== 鍩虹璋冪敤 ==============================
+
+ /**
+ * 閫氱敤璋冪敤鍏ュ彛锛氫紶鍏� Action 涓庝笟鍔″弬鏁帮紝杩斿洖瑙f瀽鍚庣殑 JSON 瀵硅薄銆�
+ *
+ * @param action API 鍔ㄤ綔鍚嶏紝渚嬪 {@code GetWsChGeneral}
+ * @param params 涓氬姟鍙傛暟锛岃嚦灏戦渶瑕佸寘鍚� {@code ServiceCode}銆亄@code Text} 绛�
+ * @return 鎺ュ彛杩斿洖鐨� JSON 瀵硅薄锛涘け璐ユ椂杩斿洖 {@code null}
+ */
+ public JSONObject invoke(String action, Map<String, String> params) {
+ if (client == null) {
+ log.error("闃块噷浜� NLP 瀹㈡埛绔湭鍒濆鍖栵紝鏃犳硶璋冪敤 action={}", action);
+ return null;
+ }
+ if (StringUtils.isBlank(action)) {
+ throw new IllegalArgumentException("action 涓嶈兘涓虹┖");
+ }
+
+ CommonRequest request = new CommonRequest();
+ request.setSysMethod(MethodType.POST);
+ request.setSysDomain(domain);
+ request.setSysVersion(version);
+ request.setSysAction(action);
+ request.setSysReadTimeout(readTimeout);
+ request.setSysConnectTimeout(connectTimeout);
+ if (params != null) {
+ for (Map.Entry<String, String> e : params.entrySet()) {
+ if (e.getValue() != null) {
+ request.putBodyParameter(e.getKey(), e.getValue());
+ }
+ }
+ }
+
+ try {
+ CommonResponse response = client.getCommonResponse(request);
+ String data = response.getData();
+ if (StringUtils.isBlank(data)) {
+ log.error("闃块噷浜� NLP 杩斿洖涓虹┖锛宎ction={}, params={}", action, params);
+ return null;
+ }
+ return JSONObject.parseObject(data);
+ } catch (ClientException e) {
+ log.error("闃块噷浜� NLP 璋冪敤澶辫触 action={}, params={}, errCode={}, errMsg={}",
+ action, params, e.getErrCode(), e.getErrMsg(), e);
+ return null;
+ } catch (Exception e) {
+ log.error("闃块噷浜� NLP 璋冪敤寮傚父 action={}, params={}", action, params, e);
+ return null;
+ }
+ }
+
+ // ============================== 渚挎嵎鏂规硶 ==============================
+
+ /**
+ * 涓枃鍒嗚瘝锛堥�氱敤棰嗗煙锛岄珮绾х増锛夈��
+ * 瀵瑰簲 Action锛歿@code GetWsChGeneral}锛孲erviceCode锛歿@code alinlp}銆�
+ *
+ * @param text 寰呭垎璇嶆枃鏈�
+ * @param tokenizer 鍒嗚瘝绮掑害锛屽彲绌恒�傚父鐢ㄥ�硷細{@code GENERAL_CHN}锛堥�氱敤鍩虹绮掑害锛�
+ * @return 鍒嗚瘝缁撴灉鍒楄〃锛涜皟鐢ㄥけ璐ヨ繑鍥炵┖鍒楄〃
+ */
+ public List<String> segmentChinese(String text, String tokenizer) {
+ if (StringUtils.isBlank(text)) {
+ return Collections.emptyList();
+ }
+ Map<String, String> params = new LinkedHashMap<>();
+ params.put("ServiceCode", "alinlp");
+ params.put("Text", text);
+ if (StringUtils.isNotBlank(tokenizer)) {
+ params.put("TokenizerId", tokenizer);
+ }
+ JSONObject resp = invoke("GetWsChGeneral", params);
+ return parseWordsFromData(resp);
+ }
+
+ /** 涓枃鍒嗚瘝锛屼娇鐢ㄩ粯璁ら�氱敤绮掑害 {@code GENERAL_CHN}銆� */
+ public List<String> segmentChinese(String text) {
+ return segmentChinese(text, "GENERAL_CHN");
+ }
+
+ /**
+ * 鎯呮劅鍒嗘瀽锛堥�氱敤棰嗗煙锛屽熀纭�鐗堬級銆�
+ * 瀵瑰簲 Action锛歿@code GetSaChGeneral}銆�
+ *
+ * @param text 寰呭垎鏋愭枃鏈�
+ * @return 褰㈠ {@code {"sentiment":"positive","positive_prob":0.97,...}} 鐨勫璞★紱澶辫触杩斿洖 {@code null}
+ */
+ public JSONObject sentimentAnalysis(String text) {
+ if (StringUtils.isBlank(text)) {
+ return null;
+ }
+ Map<String, String> params = new LinkedHashMap<>();
+ params.put("ServiceCode", "alinlp");
+ params.put("Text", text);
+ JSONObject resp = invoke("GetSaChGeneral", params);
+ return extractDataObject(resp);
+ }
+
+ // 娴嬭瘯鍏ュ彛
+ @Test
+ public void main() {
+ String text1 = "杩欏濂惰尪瓒呯骇濂藉枬锛屼笅娆¤繕鏉ワ紒";
+ String text2 = "鍛抽亾寰堝樊锛屾湇鍔℃�佸害涔熶笉濂斤紝涓嶆帹鑽�";
+ String text3 = "浠婂ぉ鍑洪棬涔颁簡涓�鐡剁熆娉夋按";
+
+ this.init();
+ JSONObject res1 = sentimentAnalysis(text1);
+ JSONObject res2 = sentimentAnalysis(text2);
+ JSONObject res3 = sentimentAnalysis(text3);
+
+ System.out.println("姝i潰鏂囨湰缁撴灉锛�" + gson.toJson(res1));
+ System.out.println("璐熼潰鏂囨湰缁撴灉锛�" + gson.toJson(res2));
+ System.out.println("涓�ф枃鏈粨鏋滐細" + gson.toJson(res3));
+ }
+
+ /**
+ * 鍛藉悕瀹炰綋璇嗗埆锛堥�氱敤棰嗗煙锛夈��
+ * 瀵瑰簲 Action锛歿@code GetNerChGeneral}銆�
+ *
+ * @param text 寰呰瘑鍒枃鏈�
+ * @return 瀹炰綋鍒楄〃锛堟瘡涓厓绱犲惈 word銆乼ag銆乻tartIndex 绛夊瓧娈碉級锛涘け璐ヨ繑鍥炵┖鍒楄〃
+ */
+ public JSONArray namedEntityRecognition(String text) {
+ if (StringUtils.isBlank(text)) {
+ return new JSONArray();
+ }
+ Map<String, String> params = new LinkedHashMap<>();
+ params.put("ServiceCode", "alinlp");
+ params.put("Text", text);
+ JSONObject resp = invoke("GetNerChGeneral", params);
+ JSONObject data = extractDataObject(resp);
+ if (data == null) {
+ return new JSONArray();
+ }
+ JSONArray arr = data.getJSONArray("result");
+ return arr == null ? new JSONArray() : arr;
+ }
+
+ // ============================== 鍝嶅簲瑙f瀽 ==============================
+
+ /**
+ * 瑙f瀽闃块噷 NLP 鐨� {@code Data} 瀛楁锛堝瓧绗︿覆鍖栫殑 JSON锛夈��
+ * 椤跺眰鍝嶅簲褰㈠锛歿@code {"Data":"{...}","RequestId":"..."}}銆�
+ */
+ private JSONObject extractDataObject(JSONObject resp) {
+ if (resp == null) {
+ return null;
+ }
+ String dataStr = resp.getString("Data");
+ if (StringUtils.isBlank(dataStr)) {
+ log.warn("闃块噷浜� NLP 鍝嶅簲缂哄皯 Data 瀛楁锛宺esp={}", resp);
+ return null;
+ }
+ try {
+ return JSONObject.parseObject(dataStr);
+ } catch (Exception e) {
+ log.error("闃块噷浜� NLP Data 瀛楁瑙f瀽澶辫触锛宒ataStr={}", dataStr, e);
+ return null;
+ }
+ }
+
+ /**
+ * 浠庡垎璇嶅搷搴旈噷鎶藉彇璇嶅垪琛ㄣ�俽esult 褰㈠ {@code [{"word":"浠婂ぉ","tag":"t"},...]}銆�
+ */
+ private List<String> parseWordsFromData(JSONObject resp) {
+ JSONObject data = extractDataObject(resp);
+ if (data == null) {
+ return Collections.emptyList();
+ }
+ JSONArray result = data.getJSONArray("result");
+ if (result == null || result.isEmpty()) {
+ return Collections.emptyList();
+ }
+ String[] words = new String[result.size()];
+ for (int i = 0; i < result.size(); i++) {
+ JSONObject item = result.getJSONObject(i);
+ words[i] = item == null ? "" : item.getString("word");
+ }
+ return Arrays.asList(words);
+ }
+
+ @Test
+ public void test() {
+ List <String> result = segmentChinese("闃块噷宸村反闆嗗洟鐨勪娇鍛芥槸璁╁ぉ涓嬫病鏈夐毦鍋氱殑鐢熸剰銆�");
+ log.info(result.toString());
+ }
+
+ @Test
+ public void testP() {
+ JSONObject result = sentimentAnalysis("鎴戣寰椾綘鍙兘鏄鐨�");
+ log.info(result.toString());
+ }
+}
--
Gitblit v1.9.3