Merge branch 'master' of https://gitee.com/zhijiantianya/onemall
This commit is contained in:
commit
124315b1cc
@ -3,6 +3,8 @@ package cn.iocoder.mall.admin.api;
|
|||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 短信平台
|
* 短信平台
|
||||||
*
|
*
|
||||||
@ -81,4 +83,34 @@ public interface SmsPlatform {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
Result deleteTemplate(String tplId);
|
Result deleteTemplate(String tplId);
|
||||||
|
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
class SendResult {
|
||||||
|
|
||||||
|
private Boolean hasSuccess;
|
||||||
|
|
||||||
|
private Integer code;
|
||||||
|
|
||||||
|
private String message;
|
||||||
|
|
||||||
|
private List<String> success;
|
||||||
|
|
||||||
|
private List<String> fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 短信发送 - 单个
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
SendResult singleSend(String mobile, String template);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 短信发送 - 批量
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
SendResult batchSend(List<String> mobileList, String template);
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,8 @@ package cn.iocoder.mall.admin.api;
|
|||||||
import cn.iocoder.mall.admin.api.bo.sms.SmsSignBO;
|
import cn.iocoder.mall.admin.api.bo.sms.SmsSignBO;
|
||||||
import cn.iocoder.mall.admin.api.bo.sms.SmsTemplateBO;
|
import cn.iocoder.mall.admin.api.bo.sms.SmsTemplateBO;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 短信服务
|
* 短信服务
|
||||||
*
|
*
|
||||||
@ -11,6 +13,8 @@ import cn.iocoder.mall.admin.api.bo.sms.SmsTemplateBO;
|
|||||||
*/
|
*/
|
||||||
public interface SmsService {
|
public interface SmsService {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 签名 - 创建
|
* 签名 - 创建
|
||||||
*
|
*
|
||||||
@ -64,4 +68,19 @@ public interface SmsService {
|
|||||||
* @param id
|
* @param id
|
||||||
*/
|
*/
|
||||||
void deleteTemplate(Integer id);
|
void deleteTemplate(Integer id);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 短信发送 - 单个
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
void singleSend(String mobile, Integer smsTemplateId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 短信发送 - 批量
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
void batchSend(List<String> mobileList, Integer smsTemplateId);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,53 @@
|
|||||||
|
package cn.iocoder.mall.admin.api.bo.sms;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @author Sin
|
||||||
|
* @time 2019/5/19 4:23 PM
|
||||||
|
*/
|
||||||
|
public class SmsPage implements IPage {
|
||||||
|
@Override
|
||||||
|
public List getRecords() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IPage setRecords(List records) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getTotal() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IPage setTotal(long total) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getSize() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IPage setSize(long size) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getCurrent() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IPage setCurrent(long current) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -51,7 +51,7 @@ public enum AdminErrorCodeEnum {
|
|||||||
DATA_DICT_NOT_EXISTS(1002005001, "该数据字典不存在"),
|
DATA_DICT_NOT_EXISTS(1002005001, "该数据字典不存在"),
|
||||||
|
|
||||||
// ========== 短信模板 1002006000 ==========
|
// ========== 短信模板 1002006000 ==========
|
||||||
SMS_PLATFORM_FAIL(1002006000, "短信模板添加失败"),
|
SMS_PLATFORM_FAIL(1002006000, "短信平台调用失败【具体错误会动态替换】"),
|
||||||
SMS_SIGN_NOT_EXISTENT(1002006001, "短信签名不存在"),
|
SMS_SIGN_NOT_EXISTENT(1002006001, "短信签名不存在"),
|
||||||
SMS_SIGN_IS_EXISTENT(1002006002, "短信签名已存在"),
|
SMS_SIGN_IS_EXISTENT(1002006002, "短信签名已存在"),
|
||||||
SMS_TEMPLATE_NOT_EXISTENT(1002006020, "短信签名不存在"),
|
SMS_TEMPLATE_NOT_EXISTENT(1002006020, "短信签名不存在"),
|
||||||
|
@ -21,6 +21,7 @@ import org.springframework.stereotype.Service;
|
|||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 短信
|
* 短信
|
||||||
@ -203,4 +204,40 @@ public class SmsServiceImpl implements SmsService {
|
|||||||
smsTemplateMapper.delete(new UpdateWrapper<SmsTemplateDO>()
|
smsTemplateMapper.delete(new UpdateWrapper<SmsTemplateDO>()
|
||||||
.set("deleted", DeletedStatusEnum.DELETED_YES).eq("id", id));
|
.set("deleted", DeletedStatusEnum.DELETED_YES).eq("id", id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void singleSend(String mobile, Integer smsTemplateId) {
|
||||||
|
SmsTemplateDO smsTemplateDO = smsTemplateMapper.selectOne(
|
||||||
|
new QueryWrapper<SmsTemplateDO>().eq("id", smsTemplateId));
|
||||||
|
|
||||||
|
if (smsTemplateDO == null
|
||||||
|
|| smsTemplateDO.getDeleted().equals(DeletedStatusEnum.DELETED_YES.getValue())) {
|
||||||
|
throw new ServiceException(AdminErrorCodeEnum.SMS_TEMPLATE_NOT_EXISTENT.getCode(),
|
||||||
|
AdminErrorCodeEnum.SMS_TEMPLATE_NOT_EXISTENT.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
SmsSignDO smsSignDO = smsSignMapper.selectOne(
|
||||||
|
new QueryWrapper<SmsSignDO>().eq("id", smsTemplateDO.getSmsSignId()));
|
||||||
|
|
||||||
|
smsPlatform.singleSend(mobile,
|
||||||
|
String.format(SMS_TEMPLATE, smsSignDO.getSign(), smsTemplateDO.getTemplate()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void batchSend(List<String> mobileList, Integer smsTemplateId) {
|
||||||
|
SmsTemplateDO smsTemplateDO = smsTemplateMapper.selectOne(
|
||||||
|
new QueryWrapper<SmsTemplateDO>().eq("id", smsTemplateId));
|
||||||
|
|
||||||
|
if (smsTemplateDO == null
|
||||||
|
|| smsTemplateDO.getDeleted().equals(DeletedStatusEnum.DELETED_YES.getValue())) {
|
||||||
|
throw new ServiceException(AdminErrorCodeEnum.SMS_TEMPLATE_NOT_EXISTENT.getCode(),
|
||||||
|
AdminErrorCodeEnum.SMS_TEMPLATE_NOT_EXISTENT.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
SmsSignDO smsSignDO = smsSignMapper.selectOne(
|
||||||
|
new QueryWrapper<SmsSignDO>().eq("id", smsTemplateDO.getSmsSignId()));
|
||||||
|
|
||||||
|
smsPlatform.batchSend(mobileList,
|
||||||
|
String.format(SMS_TEMPLATE, smsSignDO.getSign(), smsTemplateDO.getTemplate()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,15 +16,13 @@ import org.apache.http.impl.client.CloseableHttpClient;
|
|||||||
import org.apache.http.impl.client.HttpClients;
|
import org.apache.http.impl.client.HttpClients;
|
||||||
import org.apache.http.message.BasicNameValuePair;
|
import org.apache.http.message.BasicNameValuePair;
|
||||||
import org.apache.http.util.EntityUtils;
|
import org.apache.http.util.EntityUtils;
|
||||||
|
import org.assertj.core.util.Lists;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 云片 短信平台
|
* 云片 短信平台
|
||||||
@ -44,8 +42,6 @@ public class SmsYunPianPlatform implements SmsPlatform {
|
|||||||
"https://sms.yunpian.com/v2/user/get.json";
|
"https://sms.yunpian.com/v2/user/get.json";
|
||||||
|
|
||||||
//智能匹配模板发送接口的http地址
|
//智能匹配模板发送接口的http地址
|
||||||
private static final String URI_SEND_SMS =
|
|
||||||
"https://sms.yunpian.com/v2/sms/single_send.json";
|
|
||||||
|
|
||||||
//模板发送接口的http地址
|
//模板发送接口的http地址
|
||||||
private static final String URI_TPL_SEND_SMS =
|
private static final String URI_TPL_SEND_SMS =
|
||||||
@ -91,6 +87,15 @@ public class SmsYunPianPlatform implements SmsPlatform {
|
|||||||
* 模板 - 删除
|
* 模板 - 删除
|
||||||
*/
|
*/
|
||||||
private static final String URL_TEMPLATE_DELETE = "https://sms.yunpian.com/v2/tpl/del.json";
|
private static final String URL_TEMPLATE_DELETE = "https://sms.yunpian.com/v2/tpl/del.json";
|
||||||
|
/**
|
||||||
|
* 短信发送 - 单个
|
||||||
|
*/
|
||||||
|
private static final String URL_SEND_SINGLE = "https://sms.yunpian.com/v2/sms/single_send.json";
|
||||||
|
/**
|
||||||
|
* 短信发送 - 批量
|
||||||
|
*/
|
||||||
|
private static final String URL_SEND_BATCH = "https://sms.yunpian.com/v2/sms/batch_send.json";
|
||||||
|
|
||||||
|
|
||||||
//编码格式。发送编码格式统一用UTF-8
|
//编码格式。发送编码格式统一用UTF-8
|
||||||
private static String ENCODING = "UTF-8";
|
private static String ENCODING = "UTF-8";
|
||||||
@ -266,6 +271,88 @@ public class SmsYunPianPlatform implements SmsPlatform {
|
|||||||
return new Result().setId(tplId).setApplyStatus(null).setApplyMessage(null);
|
return new Result().setId(tplId).setApplyStatus(null).setApplyMessage(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SendResult singleSend(String mobile, String template) {
|
||||||
|
Map<String, String> params = new LinkedHashMap<>();
|
||||||
|
params.put("apikey", apiKey);
|
||||||
|
params.put("mobile", mobile);
|
||||||
|
params.put("text", template);
|
||||||
|
// TODO: 2019/5/19 sin 运营商发送报告 回调
|
||||||
|
// params.put("callback_url", template);
|
||||||
|
String result = post(URL_TEMPLATE_DELETE, params);
|
||||||
|
JSONObject jsonObject = JSON.parseObject(result);
|
||||||
|
if (jsonObject.containsKey("code")
|
||||||
|
&& !(jsonObject.getInteger("code") == SUCCESS_CODE)) {
|
||||||
|
throw new ServiceException(AdminErrorCodeEnum.SMS_PLATFORM_FAIL.getCode(),
|
||||||
|
jsonObject.getString("detail"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return new SendResult()
|
||||||
|
.setHasSuccess(SUCCESS_CODE == jsonObject.getInteger("code"))
|
||||||
|
.setCode(jsonObject.getInteger("code"))
|
||||||
|
.setMessage(jsonObject.getString("detail"))
|
||||||
|
.setSuccess(Lists.newArrayList(mobile))
|
||||||
|
.setFail(Collections.EMPTY_LIST);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SendResult batchSend(List<String> mobileList, String template) {
|
||||||
|
|
||||||
|
// 最大发送数为 1000,我们设置为 500 个, 分段发送
|
||||||
|
int maxSendSize = 500;
|
||||||
|
int maxSendSizeCount = mobileList.size() % maxSendSize;
|
||||||
|
int j = 0;
|
||||||
|
int j2 = maxSendSize;
|
||||||
|
|
||||||
|
List<String> successList = new ArrayList<>();
|
||||||
|
List<String> failList = new ArrayList<>();
|
||||||
|
for (int i = 0; i < maxSendSizeCount; i++) {
|
||||||
|
StringBuffer sendMobileStr = new StringBuffer();
|
||||||
|
for (int k = j; k < j2; k++) {
|
||||||
|
sendMobileStr.append(",");
|
||||||
|
sendMobileStr.append(mobileList.get(k));
|
||||||
|
}
|
||||||
|
|
||||||
|
String dividedMobile = sendMobileStr.toString().substring(1);
|
||||||
|
|
||||||
|
// 发送手机号
|
||||||
|
Map<String, String> params = new LinkedHashMap<>();
|
||||||
|
params.put("apikey", apiKey);
|
||||||
|
params.put("mobile", dividedMobile);
|
||||||
|
params.put("text", template);
|
||||||
|
// TODO: 2019/5/19 sin 运营商发送报告 回调
|
||||||
|
// params.put("callback_url", template);
|
||||||
|
String result = post(URL_SEND_BATCH, params);
|
||||||
|
JSONObject jsonObject = JSON.parseObject(result);
|
||||||
|
if (jsonObject.containsKey("code")
|
||||||
|
&& !(jsonObject.getInteger("code") == SUCCESS_CODE)) {
|
||||||
|
throw new ServiceException(AdminErrorCodeEnum.SMS_PLATFORM_FAIL.getCode(),
|
||||||
|
jsonObject.getString("detail"));
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONArray jsonArray = jsonObject.getJSONArray("data");
|
||||||
|
for (Object o : jsonArray) {
|
||||||
|
JSONObject dataJSONObject = (JSONObject) o;
|
||||||
|
if (SUCCESS_CODE == dataJSONObject.getInteger("code")) {
|
||||||
|
successList.add(dataJSONObject.getString("mobile"));
|
||||||
|
} else {
|
||||||
|
failList.add(dataJSONObject.getString("mobile"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 用于递增 maxSendSize
|
||||||
|
j = j2;
|
||||||
|
j2 = j + maxSendSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new SendResult()
|
||||||
|
.setHasSuccess(true)
|
||||||
|
.setCode(SUCCESS_CODE)
|
||||||
|
.setMessage(null)
|
||||||
|
.setSuccess(successList)
|
||||||
|
.setFail(failList);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 短信 status 和 云片状态 映射关系
|
* 短信 status 和 云片状态 映射关系
|
||||||
*
|
*
|
||||||
|
@ -66,4 +66,10 @@ public class SmsServiceImplTest {
|
|||||||
public void deleteTemplateTest() {
|
public void deleteTemplateTest() {
|
||||||
smsService.deleteTemplate(3);
|
smsService.deleteTemplate(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void singleSendTest() {
|
||||||
|
String mobile = "13302926050";
|
||||||
|
smsService.singleSend(mobile, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user