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