@@ -1,9 +1,9 @@ | |||||
package com.github.niefy.common.utils; | package com.github.niefy.common.utils; | ||||
import com.alibaba.fastjson.JSONObject; | import com.alibaba.fastjson.JSONObject; | ||||
import com.aliyuncs.CommonRequest; | import com.aliyuncs.CommonRequest; | ||||
import com.aliyuncs.CommonResponse; | import com.aliyuncs.CommonResponse; | ||||
import com.aliyuncs.DefaultAcsClient; | import com.aliyuncs.DefaultAcsClient; | ||||
import com.aliyuncs.IAcsClient; | |||||
import com.aliyuncs.exceptions.ClientException; | import com.aliyuncs.exceptions.ClientException; | ||||
import com.aliyuncs.exceptions.ServerException; | import com.aliyuncs.exceptions.ServerException; | ||||
import com.aliyuncs.http.MethodType; | import com.aliyuncs.http.MethodType; | ||||
@@ -14,18 +14,18 @@ import org.springframework.stereotype.Component; | |||||
@Component | @Component | ||||
public class SmsUtils { | public class SmsUtils { | ||||
@Value("${sms.accessKeyId}") | @Value("${sms.accessKeyId}") | ||||
public static String accessKeyId; | |||||
public String accessKeyId; | |||||
@Value("${sms.secret}") | @Value("${sms.secret}") | ||||
public static String secret; | |||||
public String secret; | |||||
@Value("${sms.signName}") | @Value("${sms.signName}") | ||||
public static String signName; // 短信签名 | |||||
public String signName; // 短信签名 | |||||
@Value("${sms.templateCode}") | @Value("${sms.templateCode}") | ||||
public static String templateCode; //短信模板 | |||||
public String templateCode; //短信模板 | |||||
@Value("${sms.regionId}") | @Value("${sms.regionId}") | ||||
public static String regionId; // 短信服务器区域 | |||||
public String regionId; // 短信服务器区域 | |||||
//平台信息 | //平台信息 | ||||
public static String sendNoteMessgae(String phoneNumbers, String code) { | |||||
DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, secret); | |||||
public String sendNoteMessgae(String phoneNumbers, String code) { | |||||
DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, secret); | |||||
DefaultAcsClient client = new DefaultAcsClient(profile); | DefaultAcsClient client = new DefaultAcsClient(profile); | ||||
CommonRequest request = new CommonRequest(); | CommonRequest request = new CommonRequest(); | ||||
@@ -33,7 +33,6 @@ public class SmsUtils { | |||||
//下面两个不能动 | //下面两个不能动 | ||||
request.setSysProduct("Dysmsapi"); | request.setSysProduct("Dysmsapi"); | ||||
request.setSysDomain("dysmsapi.aliyuncs.com"); | request.setSysDomain("dysmsapi.aliyuncs.com"); | ||||
request.setSysVersion("2017-05-25"); | request.setSysVersion("2017-05-25"); | ||||
request.setSysAction("SendSms"); | request.setSysAction("SendSms"); | ||||
//自定义参数(手机号,验证码,签名,模板) | //自定义参数(手机号,验证码,签名,模板) | ||||
@@ -44,6 +44,7 @@ public class ShiroConfig { | |||||
filterMap.put("/sys/login", "anon"); | filterMap.put("/sys/login", "anon"); | ||||
filterMap.put("/sms/**", "anon");//短信相关 | filterMap.put("/sms/**", "anon");//短信相关 | ||||
filterMap.put("/manage/wxUser/findByPhone/**", "anon"); | filterMap.put("/manage/wxUser/findByPhone/**", "anon"); | ||||
filterMap.put("/manage/templateMsg/sendTemplateMsg/**", "anon"); // 消息推送接口 | |||||
filterMap.put("/sys/**", "oauth2"); | filterMap.put("/sys/**", "oauth2"); | ||||
filterMap.put("/manage/**", "oauth2"); | filterMap.put("/manage/**", "oauth2"); | ||||
filterMap.put("/wx/**", "anon"); | filterMap.put("/wx/**", "anon"); | ||||
@@ -1,6 +1,7 @@ | |||||
package com.github.niefy.modules.wx.manage; | package com.github.niefy.modules.wx.manage; | ||||
import com.github.niefy.common.utils.R; | import com.github.niefy.common.utils.R; | ||||
import com.github.niefy.common.utils.SmsUtils; | |||||
import com.github.niefy.common.utils.StringUtils; | import com.github.niefy.common.utils.StringUtils; | ||||
import com.github.niefy.modules.wx.entity.SMS; | import com.github.niefy.modules.wx.entity.SMS; | ||||
import com.github.niefy.modules.wx.entity.WxUser; | import com.github.niefy.modules.wx.entity.WxUser; | ||||
@@ -24,6 +25,8 @@ public class SmsController { | |||||
@Autowired | @Autowired | ||||
private WxUserService userService; | private WxUserService userService; | ||||
@Autowired | |||||
private SmsUtils smsUtils; | |||||
@PostMapping(value = "/code") | @PostMapping(value = "/code") | ||||
@ApiOperation(value = "获取短信验证码", notes = "获取短信验证码") | @ApiOperation(value = "获取短信验证码", notes = "获取短信验证码") | ||||
@@ -35,13 +38,13 @@ public class SmsController { | |||||
} | } | ||||
Random random = new Random(); | Random random = new Random(); | ||||
StringBuffer smscode = new StringBuffer(); | StringBuffer smscode = new StringBuffer(); | ||||
smscode.append("123456"); | |||||
// for (int i = 0; i < 6; i++) { | |||||
// smscode.append(random.nextInt(10)); | |||||
// } | |||||
// smscode.append("123456"); | |||||
for (int i = 0; i < 6; i++) { | |||||
smscode.append(random.nextInt(10)); | |||||
} | |||||
//发送短信 | //发送短信 | ||||
// String code = SmsUtils.sendNoteMessgae(mobile, String.valueOf(smscode)); | |||||
String code = "OK"; | |||||
String code = smsUtils.sendNoteMessgae(mobile, String.valueOf(smscode)); | |||||
// String code = "OK"; | |||||
if ("OK".equals(code)) { | if ("OK".equals(code)) { | ||||
//返回验证码和发送时间 | //返回验证码和发送时间 | ||||
return R.ok().put("smsCode", String.valueOf(smscode) + new Date().getTime()); | return R.ok().put("smsCode", String.valueOf(smscode) + new Date().getTime()); | ||||
@@ -1,30 +1,22 @@ | |||||
package com.github.niefy.modules.wx.manage; | package com.github.niefy.modules.wx.manage; | ||||
import com.alibaba.fastjson.JSONObject; | |||||
import com.github.niefy.common.utils.PageUtils; | |||||
import com.github.niefy.common.utils.R; | |||||
import com.github.niefy.common.utils.StringUtils; | import com.github.niefy.common.utils.StringUtils; | ||||
import com.github.niefy.config.TaskExcutor; | import com.github.niefy.config.TaskExcutor; | ||||
import com.github.niefy.modules.wx.entity.TemplateMsgLog; | |||||
import com.github.niefy.modules.wx.entity.WxUser; | import com.github.niefy.modules.wx.entity.WxUser; | ||||
import com.github.niefy.modules.wx.service.TemplateMsgLogService; | |||||
import com.github.niefy.modules.wx.service.TemplateMsgService; | import com.github.niefy.modules.wx.service.TemplateMsgService; | ||||
import com.github.niefy.modules.wx.service.WxUserService; | import com.github.niefy.modules.wx.service.WxUserService; | ||||
import io.swagger.annotations.Api; | import io.swagger.annotations.Api; | ||||
import io.swagger.annotations.ApiOperation; | import io.swagger.annotations.ApiOperation; | ||||
import me.chanjar.weixin.mp.api.WxMpService; | |||||
import me.chanjar.weixin.mp.bean.template.WxMpTemplateData; | import me.chanjar.weixin.mp.bean.template.WxMpTemplateData; | ||||
import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage; | import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage; | ||||
import me.chanjar.weixin.mp.enums.WxMpApiUrl; | |||||
import me.chanjar.weixin.mp.util.WxMpConfigStorageHolder; | |||||
import org.apache.shiro.authz.annotation.RequiresPermissions; | |||||
import org.springframework.beans.factory.annotation.Autowired; | import org.springframework.beans.factory.annotation.Autowired; | ||||
import org.springframework.web.bind.annotation.*; | |||||
import org.springframework.web.bind.annotation.PostMapping; | |||||
import org.springframework.web.bind.annotation.RequestMapping; | |||||
import org.springframework.web.bind.annotation.RequestParam; | |||||
import org.springframework.web.bind.annotation.RestController; | |||||
import java.util.ArrayList; | import java.util.ArrayList; | ||||
import java.util.Arrays; | |||||
import java.util.List; | import java.util.List; | ||||
import java.util.Map; | |||||
/** | /** | ||||
@@ -51,35 +43,29 @@ public class TemplateMsgManageController { | |||||
* eg:{"phones":"18811408841,18811408841","datas":"dept-威海市乳山市|dept-威海市乳山市","appid":"公众号appid","templateId":"模板IDtemplateId","url":"url"} | * eg:{"phones":"18811408841,18811408841","datas":"dept-威海市乳山市|dept-威海市乳山市","appid":"公众号appid","templateId":"模板IDtemplateId","url":"url"} | ||||
* 使用固定线程的线程池 | * 使用固定线程的线程池 | ||||
*/ | */ | ||||
@GetMapping("/sendTemplateMsg/{templateMsg}") | |||||
@PostMapping("/sendTemplateMsg") | |||||
@ApiOperation(value = "外部接口-发送模板信息") | @ApiOperation(value = "外部接口-发送模板信息") | ||||
public void sendTemplateMsg(@PathVariable("templateMsg") String templateMsg) { | |||||
TaskExcutor.submit(() -> { | |||||
JSONObject templateMsgObject = JSONObject.parseObject(templateMsg); | |||||
String phones = templateMsgObject.getString("phones");//所有手机号 | |||||
String phoness[] = phones.split(","); | |||||
for (String phone:phoness) { | |||||
WxUser wxUser = userService.findByPhone(phone); | |||||
if(StringUtils.isNotNull(wxUser)){ | |||||
String datas = templateMsgObject.getString("datas");//所有模板内容 | |||||
String appid = templateMsgObject.getString("appid"); | |||||
String templateId = templateMsgObject.getString("templateId"); | |||||
String url = templateMsgObject.getString("url"); | |||||
String datass[] = datas.split("\\|"); | |||||
List<WxMpTemplateData> data = new ArrayList<>(); | |||||
for (String data_z:datass) { | |||||
String data_zz[] = data_z.split("-"); | |||||
data.add(new WxMpTemplateData(data_zz[0], data_zz[1])); | |||||
} | |||||
WxMpTemplateMessage wxMpTemplateMessage = WxMpTemplateMessage.builder() | |||||
.templateId(templateId) | |||||
.url(url) | |||||
.toUser(wxUser.getOpenid()) | |||||
.data(data) | |||||
.build(); | |||||
templateMsgService.sendTemplateMsg(wxMpTemplateMessage,appid); | |||||
public void sendTemplateMsg(@RequestParam("phones") String phones, @RequestParam("datas") String datas, | |||||
@RequestParam("appid") String appid, @RequestParam("templateId") String templateId, | |||||
@RequestParam("url") String url) { | |||||
String phoness[] = phones.split(","); | |||||
for (String phone : phoness) { | |||||
WxUser wxUser = userService.findByPhone(phone); | |||||
if (StringUtils.isNotNull(wxUser)) { | |||||
String datass[] = datas.split(","); | |||||
List<WxMpTemplateData> data = new ArrayList<>(); | |||||
for (String data_z : datass) { | |||||
String data_zz[] = data_z.split("-"); | |||||
data.add(new WxMpTemplateData(data_zz[0], data_zz[1])); | |||||
} | } | ||||
WxMpTemplateMessage wxMpTemplateMessage = WxMpTemplateMessage.builder() | |||||
.templateId(templateId) | |||||
.url(url) | |||||
.toUser(wxUser.getOpenid()) | |||||
.data(data) | |||||
.build(); | |||||
templateMsgService.sendTemplateMsg(wxMpTemplateMessage, appid); | |||||
} | } | ||||
}); | |||||
} | |||||
} | } | ||||
} | } |
@@ -36,59 +36,59 @@ public class TemplateMsgServiceImpl implements TemplateMsgService { | |||||
@Autowired | @Autowired | ||||
MsgTemplateService msgTemplateService; | MsgTemplateService msgTemplateService; | ||||
@Autowired | @Autowired | ||||
WxUserService wxUserService; | |||||
WxUserService wxUserService; | |||||
/** | /** | ||||
* 发送微信模版消息,使用固定线程的线程池 | * 发送微信模版消息,使用固定线程的线程池 | ||||
*/ | */ | ||||
@Override | @Override | ||||
@Async | @Async | ||||
public void sendTemplateMsg(WxMpTemplateMessage msg,String appid) { | |||||
TaskExcutor.submit(() -> { | |||||
String result; | |||||
try { | |||||
wxService.switchover(appid); | |||||
result = wxService.getTemplateMsgService().sendTemplateMsg(msg); | |||||
} catch (WxErrorException e) { | |||||
result = e.getMessage(); | |||||
} | |||||
public void sendTemplateMsg(WxMpTemplateMessage msg, String appid) { | |||||
// TaskExcutor.submit(() -> { | |||||
String result; | |||||
try { | |||||
wxService.switchover(appid); | |||||
result = wxService.getTemplateMsgService().sendTemplateMsg(msg); | |||||
} catch (WxErrorException e) { | |||||
result = e.getMessage(); | |||||
} | |||||
//保存发送日志 | |||||
TemplateMsgLog log = new TemplateMsgLog(msg,appid, result); | |||||
templateMsgLogService.addLog(log); | |||||
}); | |||||
//保存发送日志 | |||||
TemplateMsgLog log = new TemplateMsgLog(msg, appid, result); | |||||
templateMsgLogService.addLog(log); | |||||
// }); | |||||
} | } | ||||
@Override | @Override | ||||
@Async | |||||
@Async | |||||
public void sendMsgBatch(TemplateMsgBatchForm form, String appid) { | public void sendMsgBatch(TemplateMsgBatchForm form, String appid) { | ||||
logger.info("批量发送模板消息任务开始,参数:{}",form.toString()); | |||||
logger.info("批量发送模板消息任务开始,参数:{}", form.toString()); | |||||
wxService.switchover(appid); | wxService.switchover(appid); | ||||
WxMpTemplateMessage.WxMpTemplateMessageBuilder builder = WxMpTemplateMessage.builder() | |||||
.templateId(form.getTemplateId()) | |||||
.url(form.getUrl()) | |||||
.miniProgram(form.getMiniprogram()) | |||||
.data(form.getData()); | |||||
Map<String, Object> filterParams = form.getWxUserFilterParams(); | |||||
if(filterParams==null) { | |||||
filterParams=new HashMap<>(8); | |||||
WxMpTemplateMessage.WxMpTemplateMessageBuilder builder = WxMpTemplateMessage.builder() | |||||
.templateId(form.getTemplateId()) | |||||
.url(form.getUrl()) | |||||
.miniProgram(form.getMiniprogram()) | |||||
.data(form.getData()); | |||||
Map<String, Object> filterParams = form.getWxUserFilterParams(); | |||||
if (filterParams == null) { | |||||
filterParams = new HashMap<>(8); | |||||
} | } | ||||
long currentPage=1L,totalPages=Long.MAX_VALUE; | |||||
filterParams.put("appid",appid); | |||||
filterParams.put("limit","500"); | |||||
while (currentPage<=totalPages){ | |||||
filterParams.put("page",String.valueOf(currentPage)); | |||||
long currentPage = 1L, totalPages = Long.MAX_VALUE; | |||||
filterParams.put("appid", appid); | |||||
filterParams.put("limit", "500"); | |||||
while (currentPage <= totalPages) { | |||||
filterParams.put("page", String.valueOf(currentPage)); | |||||
//按条件查询用户 | //按条件查询用户 | ||||
IPage<WxUser> wxUsers = wxUserService.queryPage(filterParams); | |||||
logger.info("批量发送模板消息任务,使用查询条件,处理第{}页,总用户数:{}",currentPage,wxUsers.getTotal()); | |||||
wxUsers.getRecords().forEach(user->{ | |||||
WxMpTemplateMessage msg = builder.toUser(user.getOpenid()).build(); | |||||
this.sendTemplateMsg(msg,appid); | |||||
}); | |||||
currentPage=wxUsers.getCurrent()+1L; | |||||
totalPages=wxUsers.getPages(); | |||||
} | |||||
logger.info("批量发送模板消息任务结束"); | |||||
IPage<WxUser> wxUsers = wxUserService.queryPage(filterParams); | |||||
logger.info("批量发送模板消息任务,使用查询条件,处理第{}页,总用户数:{}", currentPage, wxUsers.getTotal()); | |||||
wxUsers.getRecords().forEach(user -> { | |||||
WxMpTemplateMessage msg = builder.toUser(user.getOpenid()).build(); | |||||
this.sendTemplateMsg(msg, appid); | |||||
}); | |||||
currentPage = wxUsers.getCurrent() + 1L; | |||||
totalPages = wxUsers.getPages(); | |||||
} | |||||
logger.info("批量发送模板消息任务结束"); | |||||
} | } | ||||
} | } |
@@ -1,7 +1,7 @@ | |||||
spring: | spring: | ||||
datasource: | datasource: | ||||
driver-class-name: com.mysql.cj.jdbc.Driver | driver-class-name: com.mysql.cj.jdbc.Driver | ||||
url: jdbc:mysql://${MYSQL_IP:localhost}:${MYSQL_PORT:3318}/wx?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai | |||||
url: jdbc:mysql://${MYSQL_IP:116.255.223.226}:${MYSQL_PORT:3318}/wx?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai | |||||
username: ${MYSQL_USERNAME:gly} | username: ${MYSQL_USERNAME:gly} | ||||
password: ${MYSQL_PASSWORD:glyadmin} | password: ${MYSQL_PASSWORD:glyadmin} | ||||
@@ -4,7 +4,7 @@ server: | |||||
uri-encoding: UTF-8 | uri-encoding: UTF-8 | ||||
max-threads: 1000 | max-threads: 1000 | ||||
min-spare-threads: 30 | min-spare-threads: 30 | ||||
port: ${SERVER_PORT:8088} | |||||
port: ${SERVER_PORT:9090} | |||||
connection-timeout: 5000ms | connection-timeout: 5000ms | ||||
servlet: | servlet: | ||||
context-path: /wx | context-path: /wx | ||||
@@ -71,4 +71,12 @@ wx: | |||||
task: | task: | ||||
corePoolSize: 5 #核心线程数 | corePoolSize: 5 #核心线程数 | ||||
maximumPoolSize: 30 #最大线程数 | maximumPoolSize: 30 #最大线程数 | ||||
keepAliveTime: 60 #线程最大空闲时间 | |||||
keepAliveTime: 60 #线程最大空闲时间 | |||||
sms: | |||||
# 短信平台 | |||||
accessKeyId: LTAI5tM4VsSNgjUZCcDwxRPZ | |||||
secret: IFmNCBE8IeAS8I8NiIxGjxpD3DrKCR | |||||
signName: 农燊高科 | |||||
templateCode: SMS_218160192 | |||||
regionId: cn-hangzhou |