From 933846091c0b8f06158fcab23cfa0b59e8514f9b Mon Sep 17 00:00:00 2001
From: 陈昶聿 <chychen@nbjetron.com>
Date: 星期四, 22 十月 2026 15:44:25 +0800
Subject: [PATCH] 【丽水】妇幼短信发送
---
ruoyi-common/src/main/java/com/ruoyi/common/utils/sms/SmsUtils.java | 336 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 336 insertions(+), 0 deletions(-)
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/sms/SmsUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/sms/SmsUtils.java
new file mode 100644
index 0000000..ae2c286
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/sms/SmsUtils.java
@@ -0,0 +1,336 @@
+package com.ruoyi.common.utils.sms;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson.annotation.JSONField;
+import com.ruoyi.common.utils.HttpUtil;
+import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.common.utils.http.HttpUtils;
+import com.ruoyi.common.utils.sign.Md5Utils;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+
+import java.nio.charset.StandardCharsets;
+import java.util.Base64;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 鐭俊鍙戦�佸伐鍏风被
+ *
+ * @author ruoyi
+ */
+@Slf4j
+public final class SmsUtils {
+
+ private SmsUtils() {
+ }
+
+ /**
+ * 浜慚AS 姣忔壒娆℃渶澶氭墜鏈哄彿鏁伴噺
+ */
+ private static final int YUNMAS_MAX_MOBILES = 5000;
+
+ /**
+ * 浜慚AS 杩斿洖鐮佽鏄�
+ */
+ private static final Map<String, String> YUNMAS_RSPCOD_DESC = new HashMap<>();
+
+ static {
+ YUNMAS_RSPCOD_DESC.put("success", "鏁版嵁楠岃瘉閫氳繃");
+ YUNMAS_RSPCOD_DESC.put("IllegalMac", "mac鏍¢獙涓嶉�氳繃");
+ YUNMAS_RSPCOD_DESC.put("IllegalSignId", "鏃犳晥鐨勭鍚嶇紪鐮�");
+ YUNMAS_RSPCOD_DESC.put("InvalidMessage", "闈炴硶娑堟伅锛岃姹傛暟鎹В鏋愬け璐�");
+ YUNMAS_RSPCOD_DESC.put("InvalidUsrOrPwd", "闈炴硶鐢ㄦ埛鍚�/瀵嗙爜");
+ YUNMAS_RSPCOD_DESC.put("NoSignId", "鏈尮閰嶅埌瀵瑰簲鐨勭鍚嶄俊鎭�");
+ YUNMAS_RSPCOD_DESC.put("TooManyMobiles", "鎵嬫満鍙锋暟閲忚秴闄�(>5000)");
+ }
+
+ /**
+ * 浜慚AS 鎺ュ彛閰嶇疆銆�
+ * <p>
+ * 娉ㄦ剰锛歴ecretKey 鍙弬涓� mac 璁$畻锛屼笉鑳芥斁杩涜姹傛姤鏂囥��
+ */
+ @Data
+ public static class YunMasConfig {
+ /**
+ * 鎺ュ彛鍦板潃
+ */
+ private String url;
+ /**
+ * 浼佷笟鍚嶇О
+ */
+ private String ecName;
+ /**
+ * 鎺ュ彛璐﹀彿鐢ㄦ埛鍚�
+ */
+ private String apId;
+ /**
+ * 瀵嗛挜锛堜粎鍙備笌 mac 璁$畻锛�
+ */
+ private String secretKey;
+ /**
+ * 绛惧悕缂栫爜
+ */
+ private String sign;
+ /**
+ * 鎵╁睍鐮侊細绮剧‘鍖归厤濉┖瀛楃涓诧紱妯$硦鍖归厤鍙~绌哄瓧绗︿覆鎴栬嚜瀹氫箟鎵╁睍鐮侊紙涓庢湇鍔′唬鐮佸悎璁′笉瓒呰繃20浣嶏級
+ */
+ private String addSerial;
+
+ public String getAddSerial() {
+ return addSerial == null ? "" : addSerial;
+ }
+
+ /**
+ * 涓芥按濡囧辜榛樿閰嶇疆锛堟湭鍦� sys_config 涓厤缃椂浣跨敤锛�
+ */
+ public static YunMasConfig defaultLishui() {
+ YunMasConfig config = new YunMasConfig();
+ config.setUrl("http://9.208.5.35:1992/sms/norsubmit");
+ config.setEcName("涓芥按甯傚骞间繚鍋ラ櫌");
+ config.setApId("dxjkkf");
+ config.setSecretKey("1q2w3e4r5t6y");
+ config.setSign("D9gKbwdt7");
+ config.setAddSerial("");
+ return config;
+ }
+
+ /**
+ * 鏍规嵁閰嶇疆鍐呭锛坖son锛夋瀯寤猴紝鏈厤缃殑瀛楁娌跨敤榛樿鍊�
+ *
+ * @param configJson 褰㈠ {"url":"...","ecName":"...","apId":"...","secretKey":"...","sign":"...","addSerial":""}
+ */
+ public static YunMasConfig of(String configJson) {
+ YunMasConfig config = defaultLishui();
+ if (StringUtils.isEmpty(configJson)) {
+ return config;
+ }
+ JSONObject json;
+ try {
+ json = JSON.parseObject(configJson);
+ } catch (Exception e) {
+ log.error("銆愪簯MAS銆戦厤缃В鏋愬け璐ワ紝浣跨敤榛樿閰嶇疆锛岄厤缃唴瀹癸細{}", configJson, e);
+ return config;
+ }
+ if (json == null) {
+ return config;
+ }
+ if (StringUtils.isNotEmpty(json.getString("url"))) {
+ config.setUrl(json.getString("url"));
+ }
+ if (StringUtils.isNotEmpty(json.getString("ecName"))) {
+ config.setEcName(json.getString("ecName"));
+ }
+ if (StringUtils.isNotEmpty(json.getString("apId"))) {
+ config.setApId(json.getString("apId"));
+ }
+ if (StringUtils.isNotEmpty(json.getString("secretKey"))) {
+ config.setSecretKey(json.getString("secretKey"));
+ }
+ if (StringUtils.isNotEmpty(json.getString("sign"))) {
+ config.setSign(json.getString("sign"));
+ }
+ if (json.containsKey("addSerial")) {
+ config.setAddSerial(json.getString("addSerial"));
+ }
+ return config;
+ }
+
+ /**
+ * 鍏抽敭鍙傛暟鏄惁榻愬叏
+ */
+ public boolean isValid() {
+ return StringUtils.isNotEmpty(url) && StringUtils.isNotEmpty(ecName)
+ && StringUtils.isNotEmpty(apId) && StringUtils.isNotEmpty(secretKey)
+ && StringUtils.isNotEmpty(sign);
+ }
+ }
+
+ /**
+ * 鐭俊鍙戦�佺粨鏋�
+ */
+ @Data
+ public static class SmsResult {
+ /**
+ * 骞冲彴杩斿洖鐨勭姸鎬佺爜锛坰uccess 琛ㄧず鏍¢獙閫氳繃锛�
+ */
+ private String rspcod;
+ /**
+ * 娑堟伅鎵规鍙凤紝澶辫触鏃朵负绌�
+ */
+ private String msgGroup;
+ /**
+ * 骞冲彴杩斿洖鐨勬暟鎹牎楠岀粨鏋�
+ */
+ private boolean success;
+ /**
+ * 鏈湴寮傚父/澶辫触鎻忚堪锛屼究浜庢帓鏌�
+ */
+ private String message;
+
+ /**
+ * 鏄惁鍙戦�佹垚鍔燂紙骞冲彴鏍¢獙閫氳繃锛�
+ */
+ @JSONField(serialize = false, deserialize = false)
+ public boolean isOk() {
+ return success && "success".equals(rspcod);
+ }
+
+ public static SmsResult fail(String message) {
+ SmsResult result = new SmsResult();
+ result.setSuccess(false);
+ result.setMessage(message);
+ return result;
+ }
+ }
+
+ /**
+ * 鏉窞甯備竴鍖婚櫌鍚村北闄㈠尯鎴戠煭淇℃帴鍙�
+ *
+ * @param url 鐭俊URL
+ * @param userName 鐭俊甯愬彿
+ * @param passWord 鐭俊瀵嗙爜
+ * @param phone 鎵嬫満鍙风粍鍚堝 13500000001,13500000002
+ * @param content 鐭俊鍐呭
+ * @return 鍙戦�佺粨鏋�
+ */
+ public static String sendSms(String url, String userName, String passWord, String phone, String content) {
+ long timestamp = new Date().getTime();
+ String sign = Md5Utils.hash(userName + timestamp + Md5Utils.hash(passWord));
+ content = "銆愭澀宸炲競鑲跨槫鍖婚櫌銆�" + content;
+ String jsonMsg = "{" +
+ "\"userName\": \"" + userName + "\"," +
+ "\"content\": \"" + content + "\"," +
+ "\"phoneList\": [" + phone + "]," +
+ "\"timestamp\": " + timestamp + "," +
+ "\"sign\": \"" + sign + "\"" +
+ "}";
+ Boolean sendMsg = HttpUtil.postJsonRequest(url, jsonMsg);
+ return sendMsg.toString();
+
+ }
+
+
+ /**
+ * 鏉窞甯備竴鍖婚櫌婀栨花闄㈠尯鎴戠煭淇℃帴鍙�
+ *
+ * @param url 鐭俊URL
+ * @param userName 鐭俊甯愬彿
+ * @param passWord 鐭俊瀵嗙爜
+ * @param phone 鎵嬫満鍙风粍鍚堝 13500000001,13500000002
+ * @param content 鐭俊鍐呭
+ * @return 鍙戦�佺粨鏋�
+ */
+ public static String sendSms1(String url, String userName, String passWord, String phone, String content) {
+ long timestamp = new Date().getTime();
+ String sign = Md5Utils.hash(userName + timestamp + Md5Utils.hash(passWord));
+ content = "銆愭澀宸炲競绗竴浜烘皯鍖婚櫌銆�" + content;
+ String jsonMsg = "{" +
+ "\"userName\": \"" + userName + "\"," +
+ "\"content\": \"" + content + "\"," +
+ "\"phoneList\": [" + phone + "]," +
+ "\"timestamp\": " + timestamp + "," +
+ "\"sign\": \"" + sign + "\"" +
+ "}";
+ Boolean sendMsg = HttpUtil.postJsonRequest(url, jsonMsg);
+ return sendMsg.toString();
+
+ }
+
+ /**
+ * 涓浗绉诲姩浜慚AS 鏅�氱煭淇″彂閫侊紙涓�瀵逛竴/澶氬涓�妯″紡锛�
+ * <p>
+ * 鎺ュ彛锛歅OST {url}锛屾姤鏂囦负 json 鐨� base64 缂栫爜銆�
+ * <ul>
+ * <li>mac 鎸� ecName銆乤pId銆乻ecretKey銆乵obiles銆乧ontent銆乻ign銆乤ddSerial 椤哄簭鎷兼帴鍚庡彇 MD5锛�32浣嶅皬鍐欙級</li>
+ * <li>secretKey 鍙弬涓� mac 璁$畻锛屼笉鏀捐繘璇锋眰鎶ユ枃</li>
+ * <li>绛惧悕鐢卞钩鍙版牴鎹� sign 缂栫爜鑷姩杩藉姞锛宑ontent 涓笉瑕佸啀鎵嬪伐鎷笺�愮鍚嶃��</li>
+ * </ul>
+ *
+ * @param config 浜慚AS 閰嶇疆
+ * @param mobiles 鏀朵俊鎵嬫満鍙凤紝鑻辨枃閫楀彿鍒嗛殧锛屽 13800138000,13800138001锛屾瘡鎵逛笉瓒呰繃 5000 涓�
+ * @param content 鐭俊鍐呭锛坢ac 鐢ㄦ渶缁堝唴瀹硅绠楋紝璁$畻鍚庝笉寰楀啀淇敼锛�
+ * @return 鍙戦�佺粨鏋滐紝閫氳繃 {@link SmsResult#isOk()} 鍒ゆ柇鏄惁鎴愬姛
+ */
+ public static SmsResult sendYunMasSms(YunMasConfig config, String mobiles, String content) {
+ if (config == null || !config.isValid()) {
+ return SmsResult.fail("浜慚AS閰嶇疆涓嶅畬鏁�");
+ }
+ if (StringUtils.isEmpty(mobiles)) {
+ return SmsResult.fail("鏀朵俊鎵嬫満鍙蜂笉鑳戒负绌�");
+ }
+ if (StringUtils.isEmpty(content)) {
+ return SmsResult.fail("鐭俊鍐呭涓嶈兘涓虹┖");
+ }
+ if (mobiles.split(",").length > YUNMAS_MAX_MOBILES) {
+ return SmsResult.fail("鎵嬫満鍙锋暟閲忚秴闄�(>" + YUNMAS_MAX_MOBILES + ")");
+ }
+
+ String addSerial = config.getAddSerial();
+ // 1. mac 蹇呴』鐢ㄦ姤鏂囬噷鏈�缁堝彂閫佺殑鍐呭璁$畻
+ String mac = Md5Utils.hash(config.getEcName() + config.getApId() + config.getSecretKey()
+ + mobiles + content + config.getSign() + addSerial);
+
+ // 2. 鐢� json 缁勮鎶ユ枃锛岄伩鍏嶅唴瀹逛腑鐨勫紩鍙�/鍙嶆枩鏉犵牬鍧忔姤鏂囷紱secretKey 涓嶈惤鎶ユ枃
+ JSONObject body = new JSONObject(true);
+ body.put("ecName", config.getEcName());
+ body.put("apId", config.getApId());
+ body.put("mobiles", mobiles);
+ body.put("content", content);
+ body.put("sign", config.getSign());
+ body.put("addSerial", addSerial);
+ body.put("mac", mac);
+
+ String requestBody = Base64.getEncoder()
+ .encodeToString(body.toJSONString().getBytes(StandardCharsets.UTF_8));
+
+ try {
+ String resp = HttpUtil.postJsonRequestForString(config.getUrl(), requestBody);
+ log.info("銆愪簯MAS銆戝彂閫佺煭淇★紝鎵嬫満鍙凤細{}锛屽搷搴旓細{}", mobiles, resp);
+ if (StringUtils.isEmpty(resp)) {
+ return SmsResult.fail("浜慚AS鍝嶅簲涓虹┖");
+ }
+ SmsResult result = JSON.parseObject(resp, SmsResult.class);
+ if (result == null) {
+ return SmsResult.fail("浜慚AS鍝嶅簲瑙f瀽澶辫触锛�" + resp);
+ }
+ if (!result.isOk()) {
+ String desc = YUNMAS_RSPCOD_DESC.getOrDefault(result.getRspcod(), "鏈煡閿欒");
+ result.setMessage(desc);
+ log.error("銆愪簯MAS銆戝彂閫佸け璐ワ紝鎵嬫満鍙凤細{}锛宺spcod锛歿}锛坽}锛夛紝鍝嶅簲锛歿}",
+ mobiles, result.getRspcod(), desc, resp);
+ }
+ return result;
+ } catch (Exception e) {
+ log.error("銆愪簯MAS銆戝彂閫佸紓甯革紝鎵嬫満鍙凤細{}锛屽師鍥狅細{}", mobiles, e.getMessage(), e);
+ return SmsResult.fail("浜慚AS鍙戦�佸紓甯革細" + e.getMessage());
+ }
+ }
+
+ /**
+ * 鏉窞甯備竴鍖婚櫌鍚村北闄㈠尯寰俊鎺ュ彛
+ *
+ * @param url 寰俊URL
+ * @param phone 鎵嬫満鍙� 13500000001
+ * @param idCard 韬唤璇�
+ * @return 鍙戦�佺粨鏋�
+ */
+ public static String sendChat(String url, String phone, String idCard) {
+ String urlTemp = "http://192.200.54.14:5003/sfjk/SendMessage?sfzh="
+ + idCard
+ + "&title=鎮ㄥソ锛岄個璇锋偍濉啓鍑洪櫌璋冩煡琛紝璇风偣鍑诲~鍐欍��&content=寰呴殢璁�&phone=" + phone
+ + "&url=" + url + "&key=ff76f8904f5f32b5ee1739e8ea46e60g";
+ String sendMsg = "";
+ try {
+ log.info("銆恠endChat銆戝競涓�寰俊鍏紬鍙疯姹傚弬鏁帮細{}", urlTemp);
+ sendMsg = HttpUtils.sendPost(urlTemp);
+ log.info("銆恠endChat銆戝競涓�寰俊鍏紬鍙疯繑鍥炲�硷細{}", sendMsg);
+ } catch (Exception ex) {
+ sendMsg = ex.getMessage();
+ log.error(ex.getMessage());
+ }
+ return sendMsg;
+ }
+}
--
Gitblit v1.9.3