| @@ -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 | |||