175 lines
6.3 KiB
Java
175 lines
6.3 KiB
Java
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);
|
||
}
|
||
}
|
||
|
||
}
|