fxkh-txl-service/src/main/java/com/whdc/utils/SmsHelper.java

175 lines
6.3 KiB
Java
Raw Normal View History

2025-07-14 11:23:11 +08:00
package com.whdc.utils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* @author lyf
* @since 2025-06-25
*/
@Component
@Slf4j
public class SmsHelper {
@Value("${sms.url}")
private String url;
@Value("${sms.userName}")
private String userName;
@Value("${sms.serviceCode}")
private String serviceCode;
@Value("${sms.userPassword}")
private String userPassword;
@Autowired
private HttpHelper httpHelper;
public String send(List<String> phones, String content) {
return send(phones, content, "201");
}
private String send(List<String> phones, String content, String msgType) {
if (phones == null || phones.size() == 0) {
return "未选择手机号";
}
if (content == null || content.length() == 0) {
return "短信内容为空";
}
String[] msgIds = new String[phones.size()];
for (int i = 0; i < phones.size(); i++) {
msgIds[i] = UUID.randomUUID().toString().replace("-", "");
}
String strPhones = String.join(",", phones);
String strMsgIds = String.join(",", msgIds);
String timestamp = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
String sign = md5(userPassword + timestamp).toUpperCase();
Map<String, Object> params = new HashMap<>();
params.put("serviceCode", serviceCode);
params.put("userName", userName);
params.put("userPassword", userPassword);
params.put("phones", strPhones);
params.put("msgContent", encodeGBK(content));
params.put("timestamp", timestamp);
params.put("sign", sign);
params.put("mhtMsgIds", strMsgIds);
params.put("sendTime", "");
params.put("priority", "5");
params.put("orgCode", "42");
params.put("msgType", msgType);
params.put("reportFlag", "0");
String strResult = httpHelper.postFormUrlEncoded(url, params, null, Charset.forName("GBK"));
if (strResult == null) {
return "发送失败";
}
// Map result = new ObjectMapper().readValue(strResult, Map.class);
JSONObject result = JSON.parseObject(strResult);
if (result == null) {
return "发送结果解析失败";
}
int errorCode = (Integer) result.get("result");
if (errorCode != 0) {
return SmtpErrorCode.getErrorString(errorCode);
}
return "发送成功";
}
private String md5(String str) {
MessageDigest m;
try {
m = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
m.update(str.getBytes());
byte[] s = m.digest();
return parseByte2HexStr(s);
}
private static String encodeGBK(String content) {
try {
return URLDecoder.decode(content, "GBK");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
//将二进制数组转换成16进制字符串
private String parseByte2HexStr(byte[] buf) {
StringBuilder sb = new StringBuilder();
for (byte b : buf) {
String hex = Integer.toHexString(b & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
sb.append(hex);
}
return sb.toString();
}
public static class SmtpErrorCode {
private static Map<Integer, String> map;
static {
map = new HashMap<>();
map.put(100, "非法登录如登录名、口令出错、登录名与口令不符md5 值不匹配等。");
map.put(101, "连接过多,指单个商户要求同时建立的连接数过多。");
map.put(102, "登陆类型错。");
map.put(103, "协议版本号错");
map.put(104, "ip 不合法,请联系管理员绑定 ip 后才可正常使用");
map.put(105, "Smtp 的 tcp 协议只支持后付费类型");
map.put(201, "非法手机号码。");
map.put(202, "reportFlag 值不合法,值必须为 0 或 1");
map.put(203, "信息长度错");
map.put(204, "短信内容中有非法字符");
map.put(205, "短信内容太长");
map.put(206, "不存在的优先级");
map.put(207, "SUBMIT 命令中的 serviceCode 不合法或者过期");
map.put(208, "手机号和商户消息 id 个数不匹配");
map.put(209, "orgCode 字段超过规定长度");
map.put(210, "msgType 字段超过规定长度");
map.put(211, "http 提交短信时的 url 不正确");
map.put(212, "被代理的商户与代理商户之间的关系不合法");
map.put(213, "暂未开通此商户通道,或者商户通道名称配置错误");
map.put(214, "请求参数有误,比如传递了不在接口文档中定义的参数");
map.put(215, "被代理的商户 id 不存在");
map.put(216, "商户平台的消息 id 的长度超过最大长度");
map.put(217, "sendTime 参数时间戳格式不正确");
map.put(218, "商户服务代码与用户名密码不匹配");
map.put(219, "接口只支持 HTTP POST 方式提交,而您的请求为 HTTP GET 方式");
map.put(220, "批量提交一次最多只支持 50 个");
map.put(221, "手机号不能为空");
map.put(222, "短信内容含有乱码");
map.put(500, "系统内部失败");
map.put(900, "余额不足");
map.put(901, "发送速度太快");
}
public static String getErrorString(int errorcode) {
if (!map.containsKey(errorcode)) {
return "errorcode:" + errorcode + "未定义";
}
return map.get(errorcode);
}
}
}