短信回调的解析重构
parent
c91833a504
commit
8ab29d2a25
|
@ -39,6 +39,6 @@ public interface SmsClient {
|
||||||
* @return 结果内容
|
* @return 结果内容
|
||||||
* @throws Throwable 当解析 text 发生异常时,则会抛出异常
|
* @throws Throwable 当解析 text 发生异常时,则会抛出异常
|
||||||
*/
|
*/
|
||||||
SmsCommonResult<SmsReceiveRespDTO> parseSmsReceiveStatus(String text) throws Throwable;
|
List<SmsReceiveRespDTO> parseSmsReceiveStatus(String text) throws Throwable;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
package cn.iocoder.dashboard.framework.sms.core.client.dto;
|
package cn.iocoder.dashboard.framework.sms.core.client.dto;
|
||||||
|
|
||||||
import cn.iocoder.dashboard.modules.system.enums.sms.SysSmsSendStatusEnum;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -12,35 +10,39 @@ import java.util.Date;
|
||||||
* @author 芋道源码
|
* @author 芋道源码
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
public class SmsReceiveRespDTO implements Serializable {
|
public class SmsReceiveRespDTO {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 唯一标识
|
* 是否接收成功
|
||||||
*/
|
*/
|
||||||
private String apiId;
|
private Boolean success;
|
||||||
|
/**
|
||||||
|
* API 接收结果编码
|
||||||
|
*/
|
||||||
|
private String errorCode;
|
||||||
|
/**
|
||||||
|
* API 接收结果说明
|
||||||
|
*/
|
||||||
|
private String errorMsg;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 短信发送状态 {@link SysSmsSendStatusEnum}
|
* 手机号
|
||||||
*/
|
*/
|
||||||
private Integer sendStatus;
|
private String mobile;
|
||||||
|
/**
|
||||||
|
* 用户接收时间
|
||||||
|
*/
|
||||||
|
private Date receiveTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 接收手机号
|
* 短信 API 发送返回的序号
|
||||||
*/
|
*/
|
||||||
private String phone;
|
private String serialNo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 提示
|
* 短信日志编号
|
||||||
|
*
|
||||||
|
* 对应 SysSmsLogDO 的编号
|
||||||
*/
|
*/
|
||||||
private String message;
|
private Long logId;
|
||||||
|
|
||||||
/**
|
|
||||||
* 时间
|
|
||||||
*/
|
|
||||||
private Date sendTime;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 接口返回值
|
|
||||||
*/
|
|
||||||
private Object callbackResponseBody;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,7 +90,7 @@ public abstract class AbstractSmsClient implements SmsClient {
|
||||||
throws Throwable;
|
throws Throwable;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SmsCommonResult<SmsReceiveRespDTO> parseSmsReceiveStatus(String text) throws Throwable {
|
public List<SmsReceiveRespDTO> parseSmsReceiveStatus(String text) throws Throwable {
|
||||||
try {
|
try {
|
||||||
return doParseSmsReceiveStatus(text);
|
return doParseSmsReceiveStatus(text);
|
||||||
} catch (Throwable ex) {
|
} catch (Throwable ex) {
|
||||||
|
@ -99,6 +99,6 @@ public abstract class AbstractSmsClient implements SmsClient {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract SmsCommonResult<SmsReceiveRespDTO> doParseSmsReceiveStatus(String text) throws Throwable;
|
protected abstract List<SmsReceiveRespDTO> doParseSmsReceiveStatus(String text) throws Throwable;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
package cn.iocoder.dashboard.framework.sms.core.client.impl.aliyun;
|
package cn.iocoder.dashboard.framework.sms.core.client.impl.aliyun;
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollectionUtil;
|
|
||||||
import cn.hutool.core.date.DateUtil;
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.iocoder.dashboard.common.core.KeyValue;
|
import cn.iocoder.dashboard.common.core.KeyValue;
|
||||||
import cn.iocoder.dashboard.framework.sms.core.client.SmsCommonResult;
|
import cn.iocoder.dashboard.framework.sms.core.client.SmsCommonResult;
|
||||||
|
@ -9,7 +7,6 @@ import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsReceiveRespDTO;
|
||||||
import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsSendRespDTO;
|
import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsSendRespDTO;
|
||||||
import cn.iocoder.dashboard.framework.sms.core.client.impl.AbstractSmsClient;
|
import cn.iocoder.dashboard.framework.sms.core.client.impl.AbstractSmsClient;
|
||||||
import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperties;
|
import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperties;
|
||||||
import cn.iocoder.dashboard.modules.system.enums.sms.SysSmsSendStatusEnum;
|
|
||||||
import cn.iocoder.dashboard.util.collection.MapUtils;
|
import cn.iocoder.dashboard.util.collection.MapUtils;
|
||||||
import cn.iocoder.dashboard.util.json.JsonUtils;
|
import cn.iocoder.dashboard.util.json.JsonUtils;
|
||||||
import com.aliyuncs.DefaultAcsClient;
|
import com.aliyuncs.DefaultAcsClient;
|
||||||
|
@ -20,16 +17,17 @@ import com.aliyuncs.exceptions.ClientException;
|
||||||
import com.aliyuncs.http.MethodType;
|
import com.aliyuncs.http.MethodType;
|
||||||
import com.aliyuncs.profile.DefaultProfile;
|
import com.aliyuncs.profile.DefaultProfile;
|
||||||
import com.aliyuncs.profile.IClientProfile;
|
import com.aliyuncs.profile.IClientProfile;
|
||||||
import com.fasterxml.jackson.core.type.TypeReference;
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import lombok.Data;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import javax.servlet.ServletRequest;
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static cn.iocoder.dashboard.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||||
|
import static cn.iocoder.dashboard.util.date.DateUtils.TIME_ZONE_DEFAULT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 阿里短信客户端的实现类
|
* 阿里短信客户端的实现类
|
||||||
|
@ -40,8 +38,9 @@ import java.util.Map;
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class AliyunSmsClient extends AbstractSmsClient {
|
public class AliyunSmsClient extends AbstractSmsClient {
|
||||||
|
|
||||||
private static final String PRODUCT = "Dystopi";
|
/**
|
||||||
private static final String DOMAIN = "dysmsapi.aliyuncs.com";
|
* REGION, 使用杭州
|
||||||
|
*/
|
||||||
private static final String ENDPOINT = "cn-hangzhou";
|
private static final String ENDPOINT = "cn-hangzhou";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -56,7 +55,6 @@ public class AliyunSmsClient extends AbstractSmsClient {
|
||||||
@Override
|
@Override
|
||||||
protected void doInit() {
|
protected void doInit() {
|
||||||
IClientProfile profile = DefaultProfile.getProfile(ENDPOINT, properties.getApiKey(), properties.getApiSecret());
|
IClientProfile profile = DefaultProfile.getProfile(ENDPOINT, properties.getApiKey(), properties.getApiSecret());
|
||||||
DefaultProfile.addEndpoint(ENDPOINT, PRODUCT, DOMAIN);
|
|
||||||
acsClient = new DefaultAcsClient(profile);
|
acsClient = new DefaultAcsClient(profile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,133 +91,80 @@ public class AliyunSmsClient extends AbstractSmsClient {
|
||||||
return ex.getErrMsg() + " => " + ex.getErrorDescription();
|
return ex.getErrMsg() + " => " + ex.getErrorDescription();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* [{
|
|
||||||
* "send_time" : "2017-08-30 00:00:00",
|
|
||||||
* "report_time" : "2017-08-30 00:00:00",
|
|
||||||
* "success" : true,
|
|
||||||
* "err_msg" : "用户接收成功",
|
|
||||||
* "err_code" : "DELIVERED",
|
|
||||||
* "phone_number" : "18612345678",
|
|
||||||
* "sms_size" : "1",
|
|
||||||
* "biz_id" : "932702304080415357^0",
|
|
||||||
* "out_id" : "1184585343"
|
|
||||||
* }]
|
|
||||||
*
|
|
||||||
* @param request 请求
|
|
||||||
* @return
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
public SmsReceiveRespDTO smsSendCallbackHandle(ServletRequest request) throws Exception {
|
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream()));
|
|
||||||
String paramStr = reader.readLine();
|
|
||||||
List<Map<String, Object>> params = JsonUtils.parseObject(paramStr, new TypeReference<List<Map<String, Object>>>() {
|
|
||||||
});
|
|
||||||
if (CollectionUtil.isNotEmpty(params)) {
|
|
||||||
Map<String, Object> sendResultParamMap = params.get(0);
|
|
||||||
return CallbackHelper.of(sendResultParamMap).toResultDetail();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected SmsCommonResult<SmsReceiveRespDTO> doParseSmsReceiveStatus(String text) throws Throwable {
|
protected List<SmsReceiveRespDTO> doParseSmsReceiveStatus(String text) throws Throwable {
|
||||||
return null;
|
List<SmsReceiveStatus> statuses = JsonUtils.parseArray(text, SmsReceiveStatus.class);
|
||||||
|
return statuses.stream().map(status -> {
|
||||||
|
SmsReceiveRespDTO resp = new SmsReceiveRespDTO();
|
||||||
|
resp.setSuccess(status.getSuccess());
|
||||||
|
resp.setErrorCode(status.getErrCode()).setErrorMsg(status.getErrMsg());
|
||||||
|
resp.setMobile(status.getPhoneNumber()).setReceiveTime(status.getReportTime());
|
||||||
|
resp.setSerialNo(status.getBizId()).setLogId(Long.valueOf(status.getOutId()));
|
||||||
|
return resp;
|
||||||
|
}).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 短信发送回调辅助类
|
* 短信接收状态
|
||||||
|
*
|
||||||
|
* 参见 https://help.aliyun.com/document_detail/101867.html 文档
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
*/
|
*/
|
||||||
private static class CallbackHelper {
|
@Data
|
||||||
|
public static class SmsReceiveStatus {
|
||||||
private final Map<String, Object> sendResultParamMap;
|
|
||||||
|
|
||||||
private CallbackHelper(Map<String, Object> sendResultParamMap) {
|
|
||||||
this.sendResultParamMap = sendResultParamMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static CallbackHelper of(Map<String, Object> sendResultParamMap) {
|
|
||||||
return new CallbackHelper(sendResultParamMap);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getSendStatus() {
|
|
||||||
return ((Boolean) sendResultParamMap.get(CallbackField.SUCCESS))
|
|
||||||
? SysSmsSendStatusEnum.SUCCESS.getStatus()
|
|
||||||
: SysSmsSendStatusEnum.FAILURE.getStatus();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getBizId() {
|
|
||||||
return sendResultParamMap.get(CallbackField.BIZ_ID).toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getErrMsg() {
|
|
||||||
return sendResultParamMap.get(CallbackField.ERR_MSG).toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getErrCode() {
|
|
||||||
return sendResultParamMap.get(CallbackField.ERR_CODE).toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getSendTime() {
|
|
||||||
return DateUtil.parseTime(sendResultParamMap.get(CallbackField.SEND_TIME).toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPhoneNumber() {
|
|
||||||
return sendResultParamMap.get(CallbackField.PHONE_NUMBER).toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getOutId() {
|
|
||||||
return sendResultParamMap.get(CallbackField.OUT_ID).toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public SmsReceiveRespDTO toResultDetail() {
|
|
||||||
SmsReceiveRespDTO resultDetail = new SmsReceiveRespDTO();
|
|
||||||
resultDetail.setSendStatus(getSendStatus());
|
|
||||||
resultDetail.setApiId(getBizId());
|
|
||||||
resultDetail.setSendTime(getSendTime());
|
|
||||||
resultDetail.setPhone(getPhoneNumber());
|
|
||||||
resultDetail.setMessage(getErrMsg());
|
|
||||||
|
|
||||||
resultDetail.setCallbackResponseBody(generateSuccessResponseBody());
|
|
||||||
return resultDetail;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成回调成功的返回对象
|
* 手机号
|
||||||
*/
|
*/
|
||||||
private Map<String, Object> generateSuccessResponseBody() {
|
@JsonProperty("phone_number")
|
||||||
Map<String, Object> result = new HashMap<>();
|
private String phoneNumber;
|
||||||
result.put("code", 0);
|
/**
|
||||||
result.put("msg", "成功");
|
* 发送时间
|
||||||
return result;
|
*/
|
||||||
}
|
@JsonProperty("send_time")
|
||||||
|
@JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT)
|
||||||
|
private Date sendTime;
|
||||||
|
/**
|
||||||
|
* 状态报告时间
|
||||||
|
*/
|
||||||
|
@JsonProperty("report_time")
|
||||||
|
@JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT)
|
||||||
|
private Date reportTime;
|
||||||
|
/**
|
||||||
|
* 是否接收成功
|
||||||
|
*/
|
||||||
|
private Boolean success;
|
||||||
|
/**
|
||||||
|
* 状态报告说明
|
||||||
|
*/
|
||||||
|
@JsonProperty("err_msg")
|
||||||
|
private String errMsg;
|
||||||
|
/**
|
||||||
|
* 状态报告编码
|
||||||
|
*/
|
||||||
|
@JsonProperty("err_code")
|
||||||
|
private String errCode;
|
||||||
|
/**
|
||||||
|
* 发送序列号
|
||||||
|
*/
|
||||||
|
@JsonProperty("biz_id")
|
||||||
|
private String bizId;
|
||||||
|
/**
|
||||||
|
* 用户序列号
|
||||||
|
*
|
||||||
|
* 这里我们传递的是 SysSmsLogDO 的日志编号
|
||||||
|
*/
|
||||||
|
@JsonProperty("out_id")
|
||||||
|
private String outId;
|
||||||
|
/**
|
||||||
|
* 短信长度,例如说 1、2、3
|
||||||
|
*
|
||||||
|
* 140 字节算一条短信,短信长度超过 140 字节时会拆分成多条短信发送
|
||||||
|
*/
|
||||||
|
@JsonProperty("sms_size")
|
||||||
|
private Integer smsSize;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 回调接口字段定义
|
|
||||||
*/
|
|
||||||
private interface CallbackField {
|
|
||||||
//是否成功 boolean
|
|
||||||
String SUCCESS = "success";
|
|
||||||
|
|
||||||
//发送时间
|
|
||||||
String SEND_TIME = "send_time";
|
|
||||||
|
|
||||||
//错误信息
|
|
||||||
String ERR_MSG = "err_msg";
|
|
||||||
|
|
||||||
//错误编码
|
|
||||||
String ERR_CODE = "err_code";
|
|
||||||
|
|
||||||
//手机号
|
|
||||||
String PHONE_NUMBER = "phone_number";
|
|
||||||
|
|
||||||
//用户序列号 out_id
|
|
||||||
String OUT_ID = "out_id";
|
|
||||||
|
|
||||||
//biz_id 即 apiId 唯一标识
|
|
||||||
String BIZ_ID = "biz_id";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
package cn.iocoder.dashboard.framework.sms.core.client.impl.yunpian;
|
package cn.iocoder.dashboard.framework.sms.core.client.impl.yunpian;
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.collection.CollectionUtil;
|
|
||||||
import cn.hutool.core.util.CharsetUtil;
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.hutool.core.util.URLUtil;
|
import cn.hutool.core.util.URLUtil;
|
||||||
import cn.iocoder.dashboard.common.core.KeyValue;
|
import cn.iocoder.dashboard.common.core.KeyValue;
|
||||||
|
@ -11,11 +9,9 @@ import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsReceiveRespDTO;
|
||||||
import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsSendRespDTO;
|
import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsSendRespDTO;
|
||||||
import cn.iocoder.dashboard.framework.sms.core.client.impl.AbstractSmsClient;
|
import cn.iocoder.dashboard.framework.sms.core.client.impl.AbstractSmsClient;
|
||||||
import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperties;
|
import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperties;
|
||||||
import cn.iocoder.dashboard.util.date.DateUtils;
|
|
||||||
import cn.iocoder.dashboard.util.json.JsonUtils;
|
import cn.iocoder.dashboard.util.json.JsonUtils;
|
||||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
import com.fasterxml.jackson.core.type.TypeReference;
|
|
||||||
import com.yunpian.sdk.YunpianClient;
|
import com.yunpian.sdk.YunpianClient;
|
||||||
import com.yunpian.sdk.constant.YunpianConstant;
|
import com.yunpian.sdk.constant.YunpianConstant;
|
||||||
import com.yunpian.sdk.model.Result;
|
import com.yunpian.sdk.model.Result;
|
||||||
|
@ -23,10 +19,11 @@ import com.yunpian.sdk.model.SmsSingleSend;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import javax.servlet.ServletRequest;
|
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.net.URLEncoder;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static cn.iocoder.dashboard.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||||
|
import static cn.iocoder.dashboard.util.date.DateUtils.TIME_ZONE_DEFAULT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 云片短信客户端的实现类
|
* 云片短信客户端的实现类
|
||||||
|
@ -42,9 +39,6 @@ public class YunpianSmsClient extends AbstractSmsClient {
|
||||||
*/
|
*/
|
||||||
private volatile YunpianClient client;
|
private volatile YunpianClient client;
|
||||||
|
|
||||||
private final TypeReference<List<Map<String, String>>> callbackType = new TypeReference<List<Map<String, String>>>() {
|
|
||||||
};
|
|
||||||
|
|
||||||
public YunpianSmsClient(SmsChannelProperties properties) {
|
public YunpianSmsClient(SmsChannelProperties properties) {
|
||||||
super(properties, new YunpianSmsCodeMapping());
|
super(properties, new YunpianSmsCodeMapping());
|
||||||
}
|
}
|
||||||
|
@ -105,28 +99,17 @@ public class YunpianSmsClient extends AbstractSmsClient {
|
||||||
return sendResult.getMsg() + " => " + sendResult.getDetail();
|
return sendResult.getMsg() + " => " + sendResult.getDetail();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 从 request 中获取请求中传入的短信发送结果信息
|
|
||||||
*
|
|
||||||
* @param request 回调请求
|
|
||||||
* @return 短信发送结果信息
|
|
||||||
* @throws UnsupportedEncodingException 解码异常
|
|
||||||
*/
|
|
||||||
private Map<String, String> getRequestParams(ServletRequest request) throws UnsupportedEncodingException {
|
|
||||||
Map<String, String[]> parameterMap = request.getParameterMap();
|
|
||||||
String[] smsStatuses = parameterMap.get(YunpianConstant.SMS_STATUS);
|
|
||||||
String encode = URLEncoder.encode(smsStatuses[0], CharsetUtil.UTF_8);
|
|
||||||
List<Map<String, String>> paramList = JsonUtils.parseObject(encode, callbackType);
|
|
||||||
if (CollectionUtil.isNotEmpty(paramList)) {
|
|
||||||
return paramList.get(0);
|
|
||||||
}
|
|
||||||
throw new IllegalArgumentException("YunpianSmsClient getRequestParams fail! can't format RequestParam: "
|
|
||||||
+ JsonUtils.toJsonString(request.getParameterMap()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected SmsCommonResult<SmsReceiveRespDTO> doParseSmsReceiveStatus(String text) throws Throwable {
|
protected List<SmsReceiveRespDTO> doParseSmsReceiveStatus(String text) throws Throwable {
|
||||||
return null;
|
List<SmsReceiveStatus> statuses = JsonUtils.parseArray(text, SmsReceiveStatus.class);
|
||||||
|
return statuses.stream().map(status -> {
|
||||||
|
SmsReceiveRespDTO resp = new SmsReceiveRespDTO();
|
||||||
|
resp.setSuccess(Objects.equals(status.getReportStatus(), "SUCCESS"));
|
||||||
|
resp.setErrorCode(status.getErrorMsg()).setErrorMsg(status.getErrorDetail());
|
||||||
|
resp.setMobile(status.getMobile()).setReceiveTime(status.getUserReceiveTime());
|
||||||
|
resp.setSerialNo(String.valueOf(status.getSid())).setLogId(status.getUid());
|
||||||
|
return resp;
|
||||||
|
}).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -139,6 +122,24 @@ public class YunpianSmsClient extends AbstractSmsClient {
|
||||||
@Data
|
@Data
|
||||||
public static class SmsReceiveStatus {
|
public static class SmsReceiveStatus {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 接收状态
|
||||||
|
*
|
||||||
|
* 目前仅有 SUCCESS / FAIL,所以使用 Boolean 接收
|
||||||
|
*/
|
||||||
|
@JsonProperty("report_status")
|
||||||
|
private String reportStatus;
|
||||||
|
/**
|
||||||
|
* 接收手机号
|
||||||
|
*/
|
||||||
|
private String mobile;
|
||||||
|
/**
|
||||||
|
* 运营商返回的代码,如:"DB:0103"
|
||||||
|
*
|
||||||
|
* 由于不同运营商信息不同,此字段仅供参考;
|
||||||
|
*/
|
||||||
|
@JsonProperty("error_msg")
|
||||||
|
private String errorMsg;
|
||||||
/**
|
/**
|
||||||
* 运营商反馈代码的中文解释
|
* 运营商反馈代码的中文解释
|
||||||
*
|
*
|
||||||
|
@ -160,26 +161,8 @@ public class YunpianSmsClient extends AbstractSmsClient {
|
||||||
* 用户接收时间
|
* 用户接收时间
|
||||||
*/
|
*/
|
||||||
@JsonProperty("user_receive_time")
|
@JsonProperty("user_receive_time")
|
||||||
@JsonFormat(pattern = DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
@JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT)
|
||||||
private Date userReceiveTime;
|
private Date userReceiveTime;
|
||||||
/**
|
|
||||||
* 运营商返回的代码,如:"DB:0103"
|
|
||||||
*
|
|
||||||
* 由于不同运营商信息不同,此字段仅供参考;
|
|
||||||
*/
|
|
||||||
@JsonProperty("error_msg")
|
|
||||||
private String errorMsg;
|
|
||||||
/**
|
|
||||||
* 接收手机号
|
|
||||||
*/
|
|
||||||
private String mobile;
|
|
||||||
/**
|
|
||||||
* 接收状态
|
|
||||||
*
|
|
||||||
* 目前仅有 SUCCESS / FAIL,所以使用 Boolean 接收
|
|
||||||
*/
|
|
||||||
@JsonProperty("report_status")
|
|
||||||
private String reportStatus;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -152,7 +152,7 @@ public class SysSmsServiceImpl implements SysSmsService {
|
||||||
SmsClient smsClient = smsClientFactory.getSmsClient(channelCode);
|
SmsClient smsClient = smsClientFactory.getSmsClient(channelCode);
|
||||||
Assert.notNull(smsClient, String.format("短信客户端(%s) 不存在", channelCode));
|
Assert.notNull(smsClient, String.format("短信客户端(%s) 不存在", channelCode));
|
||||||
// 解析内容
|
// 解析内容
|
||||||
SmsCommonResult<SmsReceiveRespDTO> receiveResult = smsClient.parseSmsReceiveStatus(text);
|
List<SmsReceiveRespDTO> receiveResults = smsClient.parseSmsReceiveStatus(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,11 @@ import java.util.Date;
|
||||||
*/
|
*/
|
||||||
public class DateUtils {
|
public class DateUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 时区 - 默认
|
||||||
|
*/
|
||||||
|
public static final String TIME_ZONE_DEFAULT = "GMT+8";
|
||||||
|
|
||||||
public static final String FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND = "yyyy-MM-dd HH:mm:ss";
|
public static final String FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND = "yyyy-MM-dd HH:mm:ss";
|
||||||
|
|
||||||
public static Date addTime(Duration duration) {
|
public static Date addTime(Duration duration) {
|
||||||
|
|
|
@ -2,7 +2,6 @@ package cn.iocoder.dashboard.util.json;
|
||||||
|
|
||||||
import cn.hutool.core.util.ArrayUtil;
|
import cn.hutool.core.util.ArrayUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.iocoder.dashboard.framework.sms.core.client.impl.yunpian.YunpianSmsClient;
|
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.core.type.TypeReference;
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
@ -80,10 +79,4 @@ public class JsonUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
|
||||||
String text = "[{\"sid\":9527,\"uid\":null,\"user_receive_time\":\"2014-03-17 22:55:21\",\"error_msg\":\"\",\"mobile\":\"15205201314\",\"report_status\":\"SUCCESS\"},{\"sid\":9528,\"uid\":null,\"user_receive_time\":\"2014-03-17 22:55:23\",\"error_msg\":\"\",\"mobile\":\"15212341234\",\"report_status\":\"SUCCESS\"}]";
|
|
||||||
List<YunpianSmsClient.SmsReceiveStatus> result = parseArray(text, YunpianSmsClient.SmsReceiveStatus.class);
|
|
||||||
System.out.println(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ import java.util.List;
|
||||||
/**
|
/**
|
||||||
* {@link AliyunSmsClient} 的集成测试
|
* {@link AliyunSmsClient} 的集成测试
|
||||||
*/
|
*/
|
||||||
public class AliyunSmsClientTest {
|
public class AliyunSmsClientIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSend() {
|
public void testSend() {
|
|
@ -34,7 +34,7 @@ public class SysSmsServiceIntegrationTest extends BaseDbAndRedisIntegrationTest
|
||||||
private SysUserService userService;
|
private SysUserService userService;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSendSingleSms_云片发送成功() {
|
public void testSendSingleSms_yunpianSuccess() {
|
||||||
// 参数准备
|
// 参数准备
|
||||||
String mobile = "15601691399";
|
String mobile = "15601691399";
|
||||||
Long userId = 1L;
|
Long userId = 1L;
|
||||||
|
@ -50,7 +50,7 @@ public class SysSmsServiceIntegrationTest extends BaseDbAndRedisIntegrationTest
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSendSingleSms_阿里云发送成功() {
|
public void testSendSingleSms_aliyunSuccess() {
|
||||||
// 参数准备
|
// 参数准备
|
||||||
String mobile = "15601691399";
|
String mobile = "15601691399";
|
||||||
Long userId = 1L;
|
Long userId = 1L;
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
package cn.iocoder.dashboard.framework;
|
|
@ -0,0 +1,60 @@
|
||||||
|
package cn.iocoder.dashboard.framework.sms.core.client.impl.aliyun;
|
||||||
|
|
||||||
|
import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsReceiveRespDTO;
|
||||||
|
import cn.iocoder.dashboard.util.date.DateUtils;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link AliyunSmsClient} 的单元测试
|
||||||
|
*/
|
||||||
|
public class AliyunSmsClientTest {
|
||||||
|
|
||||||
|
@InjectMocks
|
||||||
|
private final AliyunSmsClient smsClient = new AliyunSmsClient(null);
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void doInit() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void doSendSms() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDoTParseSmsReceiveStatus() throws Throwable {
|
||||||
|
// 准备参数
|
||||||
|
String text = "[\n" +
|
||||||
|
" {\n" +
|
||||||
|
" \"phone_number\" : \"13900000001\",\n" +
|
||||||
|
" \"send_time\" : \"2017-01-01 11:12:13\",\n" +
|
||||||
|
" \"report_time\" : \"2017-02-02 22:23:24\",\n" +
|
||||||
|
" \"success\" : true,\n" +
|
||||||
|
" \"err_code\" : \"DELIVERED\",\n" +
|
||||||
|
" \"err_msg\" : \"用户接收成功\",\n" +
|
||||||
|
" \"sms_size\" : \"1\",\n" +
|
||||||
|
" \"biz_id\" : \"12345\",\n" +
|
||||||
|
" \"out_id\" : \"67890\"\n" +
|
||||||
|
" }\n" +
|
||||||
|
"]";
|
||||||
|
// mock 方法
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
List<SmsReceiveRespDTO> statuses = smsClient.doParseSmsReceiveStatus(text);
|
||||||
|
// 断言
|
||||||
|
assertEquals(1, statuses.size());
|
||||||
|
assertTrue(statuses.get(0).getSuccess());
|
||||||
|
assertEquals("DELIVERED", statuses.get(0).getErrorCode());
|
||||||
|
assertEquals("用户接收成功", statuses.get(0).getErrorMsg());
|
||||||
|
assertEquals("13900000001", statuses.get(0).getMobile());
|
||||||
|
assertEquals(DateUtils.buildTime(2017, 2, 2, 22, 23, 24), statuses.get(0).getReceiveTime());
|
||||||
|
assertEquals("12345", statuses.get(0).getSerialNo());
|
||||||
|
assertEquals(67890L, statuses.get(0).getLogId());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
package cn.iocoder.dashboard.framework.sms.core.client.impl.yunpian;
|
||||||
|
|
||||||
|
import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsReceiveRespDTO;
|
||||||
|
import cn.iocoder.dashboard.util.date.DateUtils;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对 {@link YunpianSmsClient} 的单元测试
|
||||||
|
*/
|
||||||
|
public class YunpianSmsClientTest {
|
||||||
|
|
||||||
|
@InjectMocks
|
||||||
|
private final YunpianSmsClient smsClient = new YunpianSmsClient(null);
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void doInit() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void doSendSms() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testDoParseSmsReceiveStatus() throws Throwable {
|
||||||
|
// 准备参数
|
||||||
|
String text = "[{\"sid\":9527,\"uid\":1024,\"user_receive_time\":\"2014-03-17 22:55:21\",\"error_msg\":\"\",\"mobile\":\"15205201314\",\"report_status\":\"SUCCESS\"}]";
|
||||||
|
// mock 方法
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
|
||||||
|
// 断言
|
||||||
|
// 调用
|
||||||
|
List<SmsReceiveRespDTO> statuses = smsClient.doParseSmsReceiveStatus(text);
|
||||||
|
// 断言
|
||||||
|
assertEquals(1, statuses.size());
|
||||||
|
assertTrue(statuses.get(0).getSuccess());
|
||||||
|
assertEquals("", statuses.get(0).getErrorCode());
|
||||||
|
assertNull(statuses.get(0).getErrorMsg());
|
||||||
|
assertEquals("15205201314", statuses.get(0).getMobile());
|
||||||
|
assertEquals(DateUtils.buildTime(2014, 3, 17, 22, 55, 21), statuses.get(0).getReceiveTime());
|
||||||
|
assertEquals("9527", statuses.get(0).getSerialNo());
|
||||||
|
assertEquals(1024L, statuses.get(0).getLogId());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue