package com.ruoyi.message.sms.provider.nhfy;
|
|
import com.alibaba.fastjson2.JSON;
|
import com.ruoyi.message.config.MessageProperties;
|
import com.ruoyi.message.config.MtSmsConfig;
|
import com.ruoyi.message.config.RootMessageProperties;
|
import lombok.extern.slf4j.Slf4j;
|
import org.apache.commons.lang3.StringUtils;
|
import org.springframework.http.HttpEntity;
|
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.MediaType;
|
import org.springframework.http.ResponseEntity;
|
import org.springframework.stereotype.Component;
|
import org.springframework.web.client.RestTemplate;
|
|
import java.nio.charset.StandardCharsets;
|
import java.security.MessageDigest;
|
import java.text.SimpleDateFormat;
|
import java.util.Date;
|
import java.util.HashMap;
|
import java.util.Map;
|
|
/**
|
* MT消息发送工具类(SP 向行业汇聚平台提交 MT 消息)。
|
* <p>
|
* 接口地址:{@code http://ip:port/submitsm};编码:UTF-8;鉴权算法:MD5。
|
* <p>
|
* 迁移说明:原类为 {@code com.smartor.common.MtSubmitSmUtil}({@code @Component} + {@code @Value} 注入),
|
* 迁移后配置改为从 {@link MessageProperties} 读取(底层仍是同一批 configuration key),行为不变。
|
*/
|
@Slf4j
|
@Component
|
public class MtSubmitSmUtil {
|
|
private static final RestTemplate REST_TEMPLATE = new RestTemplate();
|
|
private final MessageProperties properties;
|
|
public MtSubmitSmUtil(MessageProperties properties) {
|
this.properties = properties;
|
}
|
|
/**
|
* 发送 MT 消息
|
*
|
* @param destAddr 目标号码
|
* @param content 短信内容
|
* @return 响应结果
|
*/
|
public Map<String, Object> submitSm(String destAddr, String content) {
|
MtSmsConfig mt = properties.getSms().getMt();
|
try {
|
log.info("南华附一发送短信,destAddr:{},content:{}", destAddr, content);
|
String date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
|
String hashHex = buildHashHex(mt.getAccountName(), mt.getPassword(), date);
|
|
Map<String, Object> authMap = new HashMap<>();
|
authMap.put("Algorithm", "MD5");
|
authMap.put("Date", date);
|
authMap.put("HASHHEX", hashHex);
|
|
Map<String, Object> reqMap = new HashMap<>();
|
reqMap.put("accountName", mt.getAccountName());
|
reqMap.put("Authorization", authMap);
|
reqMap.put("DestAddr", destAddr);
|
reqMap.put("SourceAddr", mt.getSourceAddr());
|
reqMap.put("Content", mt.getFlag() + content);
|
reqMap.put("ServiceCode", mt.getServiceCode());
|
|
HttpHeaders headers = new HttpHeaders();
|
headers.setContentType(new MediaType("application", "json", StandardCharsets.UTF_8));
|
headers.set("Accept-Language", "UTF-8");
|
//TODO 待确认:原实现把 app-key 写死为 ak-BFq4NN0TMf92J7KAioNYGz74,
|
// 而 yml 里同时存在 sms_appkey 配置项却未被使用。这里为保持线上行为仍用原硬编码值,
|
// 建议改为读取 mt.getAppkey()(已支持)并确认哪个才是正确的 app-key。
|
headers.set("app-key", "ak-BFq4NN0TMf92J7KAioNYGz74");
|
|
HttpEntity<String> entity = new HttpEntity<>(JSON.toJSONString(reqMap), headers);
|
log.info("MtSubmitSm 请求地址:{},请求参数:{}", mt.getUrl() + "/submitsm", JSON.toJSONString(reqMap));
|
|
ResponseEntity<String> response = REST_TEMPLATE.postForEntity(mt.getUrl(), entity, String.class);
|
log.info("MtSubmitSm 响应结果:{}", response.getBody());
|
|
return JSON.parseObject(response.getBody(), Map.class);
|
} catch (Exception e) {
|
log.error("MtSubmitSm 发送失败,url:{},destAddr:{},error:{}", mt.getUrl(), destAddr, e.getMessage(), e);
|
Map<String, Object> resp = new HashMap<>();
|
resp.put("code", -1);
|
resp.put("message", "发送异常:" + e.getMessage());
|
return resp;
|
}
|
}
|
|
/**
|
* 计算 HASHHEX:MD5(Algorithm:帐号名:密码:Date)
|
* <p>
|
* 例:{@code MD5:95555:12345:2016-10-09 16:19:43}
|
*/
|
private static String buildHashHex(String accountName, String password, String date) throws Exception {
|
String plain = "MD5:" + accountName + ":" + password + ":" + date;
|
MessageDigest md = MessageDigest.getInstance("MD5");
|
byte[] bytes = md.digest(plain.getBytes(StandardCharsets.UTF_8));
|
StringBuilder sb = new StringBuilder();
|
for (byte b : bytes) {
|
sb.append(String.format("%02x", b));
|
}
|
return sb.toString();
|
}
|
|
/**
|
* 判断 MT 响应是否成功({@code result == "0"})
|
*/
|
public static boolean isSuccess(Map<String, Object> resp) {
|
if (resp == null) {
|
return false;
|
}
|
Object result = resp.get("result");
|
return result != null && "0".equals(result.toString());
|
}
|
|
/**
|
* 判断响应的 result 字段是否为空
|
*/
|
public static boolean hasResult(Map<String, Object> resp) {
|
return resp != null && StringUtils.isNotEmpty(String.valueOf(resp.get("result")));
|
}
|
}
|