@@ -1,9 +1,9 @@ | |||
package com.github.niefy.common.utils; | |||
import com.alibaba.fastjson.JSONObject; | |||
import com.aliyuncs.CommonRequest; | |||
import com.aliyuncs.CommonResponse; | |||
import com.aliyuncs.DefaultAcsClient; | |||
import com.aliyuncs.IAcsClient; | |||
import com.aliyuncs.exceptions.ClientException; | |||
import com.aliyuncs.exceptions.ServerException; | |||
import com.aliyuncs.http.MethodType; | |||
@@ -14,18 +14,18 @@ import org.springframework.stereotype.Component; | |||
@Component | |||
public class SmsUtils { | |||
@Value("${sms.accessKeyId}") | |||
public static String accessKeyId; | |||
public String accessKeyId; | |||
@Value("${sms.secret}") | |||
public static String secret; | |||
public String secret; | |||
@Value("${sms.signName}") | |||
public static String signName; // 短信签名 | |||
public String signName; // 短信签名 | |||
@Value("${sms.templateCode}") | |||
public static String templateCode; //短信模板 | |||
public String templateCode; //短信模板 | |||
@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); | |||
CommonRequest request = new CommonRequest(); | |||
@@ -33,7 +33,6 @@ public class SmsUtils { | |||
//下面两个不能动 | |||
request.setSysProduct("Dysmsapi"); | |||
request.setSysDomain("dysmsapi.aliyuncs.com"); | |||
request.setSysVersion("2017-05-25"); | |||
request.setSysAction("SendSms"); | |||
//自定义参数(手机号,验证码,签名,模板) | |||
@@ -44,6 +44,7 @@ public class ShiroConfig { | |||
filterMap.put("/sys/login", "anon"); | |||
filterMap.put("/sms/**", "anon");//短信相关 | |||
filterMap.put("/manage/wxUser/findByPhone/**", "anon"); | |||
filterMap.put("/manage/templateMsg/sendTemplateMsg/**", "anon"); // 消息推送接口 | |||
filterMap.put("/sys/**", "oauth2"); | |||
filterMap.put("/manage/**", "oauth2"); | |||
filterMap.put("/wx/**", "anon"); | |||
@@ -1,6 +1,7 @@ | |||
package com.github.niefy.modules.wx.manage; | |||
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.modules.wx.entity.SMS; | |||
import com.github.niefy.modules.wx.entity.WxUser; | |||
@@ -24,6 +25,8 @@ public class SmsController { | |||
@Autowired | |||
private WxUserService userService; | |||
@Autowired | |||
private SmsUtils smsUtils; | |||
@PostMapping(value = "/code") | |||
@ApiOperation(value = "获取短信验证码", notes = "获取短信验证码") | |||
@@ -35,13 +38,13 @@ public class SmsController { | |||
} | |||
Random random = new Random(); | |||
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)) { | |||
//返回验证码和发送时间 | |||
return R.ok().put("smsCode", String.valueOf(smscode) + new Date().getTime()); | |||
@@ -1,30 +1,22 @@ | |||
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.config.TaskExcutor; | |||
import com.github.niefy.modules.wx.entity.TemplateMsgLog; | |||
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.WxUserService; | |||
import io.swagger.annotations.Api; | |||
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.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.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.Arrays; | |||
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"} | |||
* 使用固定线程的线程池 | |||
*/ | |||
@GetMapping("/sendTemplateMsg/{templateMsg}") | |||
@PostMapping("/sendTemplateMsg") | |||
@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 | |||
MsgTemplateService msgTemplateService; | |||
@Autowired | |||
WxUserService wxUserService; | |||
WxUserService wxUserService; | |||
/** | |||
* 发送微信模版消息,使用固定线程的线程池 | |||
*/ | |||
@Override | |||
@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 | |||
@Async | |||
@Async | |||
public void sendMsgBatch(TemplateMsgBatchForm form, String appid) { | |||
logger.info("批量发送模板消息任务开始,参数:{}",form.toString()); | |||
logger.info("批量发送模板消息任务开始,参数:{}", form.toString()); | |||
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: | |||
datasource: | |||
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} | |||
password: ${MYSQL_PASSWORD:glyadmin} | |||
@@ -4,7 +4,7 @@ server: | |||
uri-encoding: UTF-8 | |||
max-threads: 1000 | |||
min-spare-threads: 30 | |||
port: ${SERVER_PORT:8088} | |||
port: ${SERVER_PORT:9090} | |||
connection-timeout: 5000ms | |||
servlet: | |||
context-path: /wx | |||
@@ -71,4 +71,12 @@ wx: | |||
task: | |||
corePoolSize: 5 #核心线程数 | |||
maximumPoolSize: 30 #最大线程数 | |||
keepAliveTime: 60 #线程最大空闲时间 | |||
keepAliveTime: 60 #线程最大空闲时间 | |||
sms: | |||
# 短信平台 | |||
accessKeyId: LTAI5tM4VsSNgjUZCcDwxRPZ | |||
secret: IFmNCBE8IeAS8I8NiIxGjxpD3DrKCR | |||
signName: 农燊高科 | |||
templateCode: SMS_218160192 | |||
regionId: cn-hangzhou |