Authored by linlong

短信发送优化

... ... @@ -73,6 +73,8 @@ public class ChannelGroupServiceImpl implements IChannelGroupService {
public static final int BATCH_MESSAGE_NUMBER = 500;
public static final int INSERT_MESSAGE_NUMBER = 500;
public static final short SMS_STATUS_SUCCESS = 1; //短信发送成功状态
public static final short SMS_STATUS_FAIL = 0;
... ... @@ -159,125 +161,6 @@ public class ChannelGroupServiceImpl implements IChannelGroupService {
return pageChannelGroupRspBO;
}
// @Override
// public int sendMessage(ChannelMessageRequestBO channelGroupRequestBO, int sendUserId) {
// logger.info("enter sendMessage. param channelGroupRequestBO{}", channelGroupRequestBO);
// int groupId = channelGroupRequestBO.getGroupId();
// String content = channelGroupRequestBO.getContent();
//
// //1.根据groupId查询条件
// List<ChannelGroupCondition> conditions = channelGroupConditionDAO.selectByGroupId(groupId);
// logger.info("sendMessage:conditions is {}", conditions);
// Map<String, Object> params = conditions.stream().collect(Collectors.toMap(ChannelGroupCondition::getKey, ChannelGroupCondition::getValue));
//
// //2.根据条件分批查询手机号
// int total = channelUserDAO.selectCount(params);
// if (total == 0) {
// logger.info("not find users to send message,param channelGroupRequestBO{}", channelGroupRequestBO);
// return 0;
// }
// Set<String> mobileSet = Sets.newHashSet();
// //2.1分批从数据库中查询,每次1000,使用mobileSet去重
// for (int i = 0; i < total; i += BATCH_MESSAGE_NUMBER) {
// List<ChannelUser> channelUsers = channelUserDAO.selectPage(params, i, i + BATCH_MESSAGE_NUMBER);
// Set<String> channelMobiles = channelUsers.stream().map(ChannelUser::getMobile).collect(Collectors.toSet());
// mobileSet.addAll(channelMobiles);
// }
//
// //2.2查询出来的手机号剔除黑名单数据
// List<String> blackList = channelSmsBlackDAO.selectAll();
// mobileSet.removeAll(blackList);
//
// //2.3添加默认运营的号码
// List<String> businessMobileList = Arrays.asList(businessMobile.split(","));
// mobileSet.addAll(businessMobileList);
//
// //剔除黑名单后,发送手机号为空,返回
//// if (CollectionUtils.isEmpty(mobileSet)) {
//// logger.info("not find users to send message,param channelGroupRequestBO{}", channelGroupRequestBO);
//// return 0;
//// }
//
// //3.记录分组批次表
// int sendTime = DateUtils.getCurrentTimeSecond();
//
// UserInfoBO userInfoBO = null;
//
// try {
// userInfoBO = erpApiServiceHelper.getUserByPid(String.valueOf(sendUserId));
// } catch (Exception e) {
// logger.warn("call erpApiServiceHelper.getUserByPid occurs Exception,e is {}", e.getMessage());
// }
//
// String sendUserName = userInfoBO != null ? userInfoBO.getAccount() : "";
// ChannelGroupBatch channelGroupBatch = new ChannelGroupBatch(groupId, content, sendTime, sendUserId, sendUserName);
// channelGroupBatchDAO.insertSelective(channelGroupBatch);
// logger.info("sendMessage:insert channelGroupBatch,channelGroupBatch ={}", channelGroupBatch);
// int groupBatchId = channelGroupBatch.getId();
//
// List<String> mobileList = Lists.newArrayList(mobileSet);
// List<ChannelSmsDetail> smsDetails = Lists.newArrayList();
// //4.用户去重、黑名单后,分批发送短信
// List<String> mobiles = null;
// int successCount = 0;
// for (int i = 0; i < mobileList.size(); i += BATCH_MESSAGE_NUMBER) {
// if (i + BATCH_MESSAGE_NUMBER > mobileList.size()) {
// mobiles = mobileList.subList(i, mobileList.size());
// } else {
// mobiles = mobileList.subList(i, i + BATCH_MESSAGE_NUMBER);
// }
// String mobile = StringUtils.join(mobiles.toArray(), ",");
// //调用SDK发送短信接口
// SendMessageRspBo sendMessageRspBo = null;
//
// try {
// sendMessageRspBo = sendCrmMessage.generalSceneMsg(mobile, content);
// logger.info("sendMessage:call generalSceneMsg,sendMessageRspBo is {}", sendMessageRspBo);
// } catch (Exception e) {
// logger.warn("sendMessage:call generalSceneMsg occurs Exception,e is {}", e.getMessage());
// }
//
//
// //4.1短信发送成功,记录短信日志表(状态为1)
// if (sendMessageRspBo != null && sendMessageRspBo.getCode() == 200 && sendMessageRspBo.getMessage().equals("SUCCESS")) {
// for (String sms : mobiles) {
// ChannelSmsDetail channelSmsDetail = new ChannelSmsDetail(sms, groupBatchId, SMS_STATUS_SUCCESS, sendTime);
// smsDetails.add(channelSmsDetail);
// successCount++;
// }
// } else {
// //4.2短信发送失败,打印日志,记录短信日志表(状态为0)和分组批次表
// for (String sms : mobiles) {
// ChannelSmsDetail channelSmsDetail = new ChannelSmsDetail(sms, groupBatchId, SMS_STATUS_FAIL, sendTime);
// smsDetails.add(channelSmsDetail);
// }
// }
// }
//
// //异步记录日志表,以后查询日志方便
// try {
// saveSmsDetail(smsDetails);
// } catch (Exception e) {
// logger.error("", e);
// }
// logger.info("sendMessage:insert channelSmsDetai,smsDetails is {}", smsDetails);
//
// //5.修改分组表的分组人数、发送时间、修改时间、内容、发送人
// ChannelGroup channelGroup = new ChannelGroup();
// channelGroup.setId(groupId);
// channelGroup.setUpdateTime(sendTime);
// channelGroup.setGroupNumber(mobileSet.size());
// channelGroup.setSuccessCount(successCount);
// channelGroup.setSendTime(sendTime);
// channelGroup.setContent(content);
// channelGroup.setSendUserName(sendUserName);
// channelGroup.setSendUser(sendUserId);
// channelGroup.setSmsNumber(groupBatchId);
// channelGroup.setStatus(1);
// int count = channelGroupDAO.updateByPrimaryKeySelective(channelGroup);
// logger.info("sendMessage:update channelGroup,channelGroup is {}", channelGroup);
// return count;
// }
@Override
public int sendMessage(ChannelMessageRequestBO channelGroupRequestBO, int sendUserId) {
... ... @@ -300,6 +183,7 @@ public class ChannelGroupServiceImpl implements IChannelGroupService {
channelGroup.setContent(content);
channelGroup.setSendUserName(sendUserName);
channelGroup.setSendUser(sendUserId);
channelGroup.setSendTime(DateUtils.getCurrentTimeSecond());
channelGroup.setStatus(2); //状态2:发送中
int count = channelGroupDAO.updateByPrimaryKeySelective(channelGroup);
logger.info("sendMessage:sending message,channelGroup is {}", channelGroup);
... ... @@ -334,7 +218,7 @@ public class ChannelGroupServiceImpl implements IChannelGroupService {
}
Set<String> mobileSet = Sets.newHashSet();
//2.1分批从数据库中查询,每次500,使用mobileSet去重
int queryCount = 0; //查询失败手机号
for (int i = 0; i < total; i += BATCH_MESSAGE_NUMBER) {
try{
List<ChannelUser> channelUsers = channelUserDAO.selectPage(params, i, i + BATCH_MESSAGE_NUMBER);
... ... @@ -342,12 +226,26 @@ public class ChannelGroupServiceImpl implements IChannelGroupService {
mobileSet.addAll(channelMobiles);
}catch (Exception e){
//查询超时等异常
if(total-i>BATCH_MESSAGE_NUMBER){
queryCount +=BATCH_MESSAGE_NUMBER;
}else{
//最后一次查询出现异常,失败数不是批量值
queryCount = queryCount+total-i;
}
logger.warn("sendMessage:query users fail.");
}
}
//2.2查询出来的手机号剔除黑名单数据
List<String> blackList = channelSmsBlackDAO.selectAll();
//2.2查询出来的手机号剔除黑名单数据,也分批查询黑名单
Integer blackTotal = channelSmsBlackDAO.selectCount();
List<String> blackList = Lists.newArrayList();
if(blackTotal!=null){
for (int i = 0; i < blackTotal; i += BATCH_MESSAGE_NUMBER) {
List<String> temp = channelSmsBlackDAO.selectAll(i,i+BATCH_MESSAGE_NUMBER);
blackList.addAll(temp);
}
}
mobileSet.removeAll(blackList);
//2.3添加默认运营的号码
... ... @@ -366,8 +264,9 @@ public class ChannelGroupServiceImpl implements IChannelGroupService {
//4.用户去重、黑名单后,分批发送短信
List<String> mobiles = null;
int successCount = 0;
int failCount = 0;
int successCount = 0; //发送成功短信数
int failCount = 0; //发送失败短信数
for (int i = 0; i < mobileList.size(); i += BATCH_MESSAGE_NUMBER) {
if (i + BATCH_MESSAGE_NUMBER > mobileList.size()) {
mobiles = mobileList.subList(i, mobileList.size());
... ... @@ -386,7 +285,7 @@ public class ChannelGroupServiceImpl implements IChannelGroupService {
}
//4.1短信发送成功,记录短信日志表(状态为1)
// 4.1短信发送成功,记录短信日志表(状态为1)
if (sendMessageRspBo != null && sendMessageRspBo.getCode() == 200 && sendMessageRspBo.getMessage().equals("SUCCESS")) {
for (String sms : mobiles) {
ChannelSmsDetail channelSmsDetail = new ChannelSmsDetail(sms, groupBatchId, SMS_STATUS_SUCCESS, sendTime);
... ... @@ -403,22 +302,32 @@ public class ChannelGroupServiceImpl implements IChannelGroupService {
}
}
//5.记录短信明细表
channelSmsDetailDAO.batchInsert(smsDetails);
logger.info("sendMessage:end insert channelSmsDetai,smsDetails is {}", smsDetails);
//6.发送成功更新发送人、发送时间、状态等
//5.发送成功更新发送人、发送时间、状态等
ChannelGroup channelGroup = new ChannelGroup();
channelGroup.setId(groupId);
channelGroup.setUpdateTime(sendTime);
channelGroup.setGroupNumber(mobileSet.size());
channelGroup.setSuccessCount(successCount);
channelGroup.setSendTime(sendTime);
channelGroup.setSmsNumber(groupBatchId);
channelGroup.setStatus(1);
channelGroup.setFailCount(failCount);
channelGroup.setQueryCount(queryCount);
channelGroupDAO.updateByPrimaryKeySelective(channelGroup);
//6.最后再更新日志表,批量更新一次1000
List<ChannelSmsDetail> temp = null;
for(int i=0;i<smsDetails.size();i++){
if (i + INSERT_MESSAGE_NUMBER > mobileList.size()) {
temp = smsDetails.subList(i, mobileList.size());
} else {
temp = smsDetails.subList(i, i + INSERT_MESSAGE_NUMBER);
}
channelSmsDetailDAO.batchInsert(temp);
}
logger.info("sendMessage:end insert channelSmsDetai,smsDetails is {}", smsDetails);
logger.info("sendMessage:end sendSmsDetail,groupId={},content={},sendUserId={},sendUserName={}", groupId,content,sendUserId,sendUserName);
}
});
... ...
... ... @@ -26,7 +26,13 @@ public interface IChannelSmsBlackDAO {
* 查询所有的黑名单
* @return
*/
List<String> selectAll();
List<String> selectAll(@Param("offset") int offset, @Param("rows") int rows);
/**
* 查询黑名单总数
* @return
*/
Integer selectCount();
/**
* 批量添加黑名单
... ...
... ... @@ -35,6 +35,16 @@ public class ChannelGroup {
private Integer failCount;
private Integer queryCount;
public Integer getQueryCount() {
return queryCount;
}
public void setQueryCount(Integer queryCount) {
this.queryCount = queryCount;
}
public Integer getSendTime() {
return sendTime;
}
... ...
... ... @@ -17,9 +17,10 @@
<result column="send_userName" property="sendUserName" jdbcType="VARCHAR" />
<result column="update_time" property="updateTime" jdbcType="INTEGER" />
<result column="fail_count" property="failCount" jdbcType="INTEGER" />
<result column="query_count" property="queryCount" jdbcType="INTEGER" />
</resultMap>
<sql id="Base_Column_List" >
id, name, group_number,sms_number,success_count, create_time, create_user, create_userName, content,status,send_time,send_user,send_userName,update_time,fail_count
id, name, group_number,sms_number,success_count, create_time, create_user, create_userName, content,status,send_time,send_user,send_userName,update_time,fail_count,query_count
</sql>
<select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
select
... ... @@ -33,11 +34,11 @@
</delete>
<insert id="insert" parameterType="com.yoho.unions.dal.model.ChannelGroup" keyProperty="id" useGeneratedKeys="true" >
insert into channel_group (id, name, content,group_number,sms_number,success_count,
create_time, create_user, create_userName,status,send_time,send_user,send_userName,update_time,fail_count
create_time, create_user, create_userName,status,send_time,send_user,send_userName,update_time,fail_count,query_count
)
values (#{id,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR}, #{content,jdbcType=VARCHAR},#{groupNumber,jdbcType=INTEGER},#{smsNumber,jdbcType=INTEGER},#{successCount,jdbcType=INTEGER},
#{createTime,jdbcType=INTEGER}, #{createUser,jdbcType=INTEGER}, #{createUserName,jdbcType=VARCHAR}, #{status,jdbcType=INTEGER},
#{sendTime,jdbcType=INTEGER}, #{sendUser,jdbcType=INTEGER}, #{sendUserName,jdbcType=VARCHAR}, #{updateTime,jdbcType=INTEGER},#{failCount,jdbcType=INTEGER}
#{sendTime,jdbcType=INTEGER}, #{sendUser,jdbcType=INTEGER}, #{sendUserName,jdbcType=VARCHAR}, #{updateTime,jdbcType=INTEGER},#{failCount,jdbcType=INTEGER},#{queryCount,jdbcType=INTEGER}
)
</insert>
<insert id="insertSelective" parameterType="com.yoho.unions.dal.model.ChannelGroup" keyProperty="id" useGeneratedKeys="true">
... ... @@ -64,6 +65,9 @@
<if test="failCount != null" >
fail_count,
</if>
<if test="queryCount != null" >
query_count,
</if>
<if test="createTime != null" >
create_time,
</if>
... ... @@ -111,6 +115,9 @@
<if test="failCount != null" >
#{failCount,jdbcType=INTEGER},
</if>
<if test="queryCount != null" >
#{queryCount,jdbcType=INTEGER},
</if>
<if test="createTime != null" >
#{createTime,jdbcType=INTEGER},
</if>
... ... @@ -158,6 +165,9 @@
<if test="failCount != null" >
fail_count = #{failCount,jdbcType=INTEGER},
</if>
<if test="queryCount != null" >
query_count = #{failCount,jdbcType=INTEGER},
</if>
<if test="createTime != null" >
create_time = #{createTime,jdbcType=INTEGER},
</if>
... ... @@ -200,7 +210,8 @@
send_user = #{sendUser,jdbcType=INTEGER},
send_userName = #{sendUserName,jdbcType=VARCHAR},
update_time = #{updateTime,jdbcType=INTEGER},
fail_count = #{failCount,jdbcType=INTEGER}
fail_count = #{failCount,jdbcType=INTEGER},
query_count = #{queryCount,jdbcType=INTEGER},
where id = #{id,jdbcType=INTEGER}
</update>
<select id ="selectListCountByParam" resultType="java.lang.Integer">
... ... @@ -219,7 +230,7 @@
and create_userName LIKE CONCAT('%',#{createUserName,jdbcType=VARCHAR},'%')
</if>
<if test="status != null" >
and status = #{status,jdbcType=INTEGER}
and status !=0
</if>
<if test="smsNumber != null" >
and sms_number = #{smsNumber,jdbcType=INTEGER}
... ... @@ -252,7 +263,7 @@
and create_userName LIKE CONCAT('%',#{createUserName,jdbcType=VARCHAR},'%')
</if>
<if test="status != null" >
and status = #{status,jdbcType=INTEGER}
and status !=0
</if>
<if test="smsNumber != null" >
and sms_number = #{smsNumber,jdbcType=INTEGER}
... ...
... ... @@ -24,6 +24,12 @@
<select id="selectAll" resultType="java.lang.String">
select mobile
from channel_sms_black
ORDER BY create_time DESC
limit #{offset}, #{rows}
</select>
<select id="selectCount" resultType="java.lang.Integer">
select count(1)
from channel_sms_black
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer" >
delete from channel_sms_black
... ...
<!DOCTYPE html>
<html >
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="/union/js/include.js"></script>
<script src="/union/js/ajaxfileupload.js"></script>
</head>
<body>
<table style="width: 100%;padding: 30px 30px 0px 30px">
<tbody>
<tr>
<td style="width:200px;">上传文件:</td>
<td>
<div id="batchImportDiv"></div>
</td>
</tr>
</tbody>
</table>
<div id="matchDiv" style="padding:30px;"></div>
</body>
<script type="text/javascript">
$(function () {
$("#batchImportDiv").fileUpload({
text: "请选择文件", //按钮文字
uploadInputName: "file", //上传文件的控件名称
url: contextPath + "/batch/import", //提交到后端的url
queryParams: {
type: "deviceIdMatchImport"
}, //提交到后端额外参数
showFileName: false, //上传成功后,是否显示文件名
onLoadSuccess: function (fileName, data) {
$.messager.show({
title: "提示",
msg: "匹配完成",
height: 250
});
var match = data.data;
var output = "匹配的内容</br>" ;
for(var i=0;i<match.length;i++){
output += match[i]+"</br>";
}
$("#matchDiv").append(output);
}
});
});
</script>
</html>
\ No newline at end of file
... ... @@ -164,11 +164,13 @@
width: 140,
align: "center",
formatter: function (value, rowData, rowIndex) {
if(rowData.status==2){
return "发送中,稍后刷新重试!"
}
if (rowData.content == null || rowData.content == '') {
return "";
} else {
var fail = rowData.groupNumber - value;
return "成功数" + value + ",失败数" + fail;
return "成功数" + value + ",失败数" + rowData.failCount + "查询失败数:" + rowData.queryCount;
}
}
}, {
... ... @@ -180,8 +182,8 @@
var str = "";
if (rowData.content == null || rowData.content == '') {
str = "<a role='send' dataId='" + rowData.id + "' dataContent='" + rowData.content + "' style='margin-left:10px'>发送短信</a>";
}else{
str = "<a role='send' dataId='" + rowData.id + "' dataContent='" + rowData.content + "' style='margin-left:10px'>再次发送</a>";
} else {
str = "<a role='send' dataId='" + rowData.id + "' dataContent='" + rowData.content + "' style='margin-left:10px' >再次发送</a>";
}
str += "<a role='delete' dataId='" + rowData.id + "' style='margin-left:10px'>删除</a>";
return str;
... ... @@ -197,13 +199,26 @@
checkOnSelect: false,
onLoadSuccess: function (data) {
getCondition(data);
$(this).myDatagrid("getPanel").find("a[role='send']").linkbutton({
iconCls: "icon-more",
onClick: function () {
sendMessage($(this).attr("dataId"),$(this).attr("dataContent"));
sendMessage($(this).attr("dataId"), $(this).attr("dataContent"));
}
});
var currentDate = getNowFormatDate();
for (var i = 0; i < data.list.length; i++) {
var obj = data.list[i].sendTime;
if(obj!=""){
obj = obj.substring(0,10);
}
if(currentDate == obj){
var btn = $(this).myDatagrid("getPanel").find("a[role='send']")[i];
$(btn).linkbutton("disable")
}
}
$(this).myDatagrid("getPanel").find("a[role='delete']").linkbutton({
iconCls: "icon-more",
onClick: function () {
... ... @@ -271,18 +286,18 @@
function showblackList() {
var div = $("<div>").appendTo($(window.self.document.body));
window.self.$(div).myDialog({
modal : true,
collapsible : true,
cache : false,
title : "黑名单列表",
modal: true,
collapsible: true,
cache: false,
title: "黑名单列表",
width: 600,
height: 600,
href: contextPath + "/html/channel/blackList.html",
buttons : [{
id : "closeBtn",
text : "关闭",
iconCls : "icon-cancel",
handler : function() {
buttons: [{
id: "closeBtn",
text: "关闭",
iconCls: "icon-cancel",
handler: function () {
window.self.$(div).dialog('close');
}
}]
... ... @@ -315,7 +330,7 @@
});
}
function sendMessage(id,content) {
function sendMessage(id, content) {
window.paramObject.sms = content;
var div = $("<div>").appendTo($(document.body));
var title = "发送短信";
... ... @@ -337,7 +352,7 @@
iconCls: "icon-save",
handler: function () {
var content = $("#content").val();
if(content.length>250){
if (content.length > 250) {
window.self.$.messager.alert("提示消息", "短信字数不能超过250!");
}
$.post(contextPath + "/channel/sendMessage", {groupId: id, content: content}, function (data) {
... ... @@ -403,7 +418,22 @@
addTooltip(content[id], 'condition-' + i);
}
});
}
function getNowFormatDate() {
var date = new Date();
var seperator1 = "-";
var year = date.getFullYear();
var month = date.getMonth() + 1;
var strDate = date.getDate();
if (month >= 1 && month <= 9) {
month = "0" + month;
}
if (strDate >= 0 && strDate <= 9) {
strDate = "0" + strDate;
}
var currentdate = year + seperator1 + month + seperator1 + strDate;
return currentdate;
}
</script>
... ...