@@ -0,0 +1,52 @@ | |||
###################################################################### | |||
# Build Tools | |||
.gradle | |||
/build/ | |||
!gradle/wrapper/gradle-wrapper.jar | |||
target/ | |||
xueyi-ui/ | |||
!.mvn/wrapper/maven-wrapper.jar | |||
###################################################################### | |||
# IDE | |||
### STS ### | |||
.apt_generated | |||
.classpath | |||
.factorypath | |||
.project | |||
.settings | |||
.springBeans | |||
### IntelliJ IDEA ### | |||
.idea/ | |||
.vscode/ | |||
*.iws | |||
*.iml | |||
*.ipr | |||
### JRebel ### | |||
rebel.xml | |||
### NetBeans ### | |||
nbproject/private/ | |||
build/* | |||
nbbuild/ | |||
dist/ | |||
nbdist/ | |||
.nb-gradle/ | |||
###################################################################### | |||
# Others | |||
*.log | |||
*.xml.versionsBackup | |||
*.swp | |||
.DS_Store | |||
.idea/ | |||
!*/build/*.java | |||
!*/build/*.html | |||
!*/build/*.xml | |||
logs/ | |||
**/target */ |
@@ -0,0 +1,9 @@ | |||
FROM openjdk:8 | |||
MAINTAINER yangkai | |||
ADD target/sms-msg-sender-1.0-SNAPSHOT.jar sms-msg-sender.jar | |||
COPY application.yml / | |||
RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime | |||
EXPOSE 8080 | |||
ENTRYPOINT ["java","-jar","sms-msg-sender.jar","--spring.config.location=/application.yml"] | |||
# docker run -d --restart=always --name dg-sms-sender -p 9950:9950 dg-sms-sender:v1 //运行镜像 |
@@ -0,0 +1,126 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<project xmlns="http://maven.apache.org/POM/4.0.0" | |||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | |||
<modelVersion>4.0.0</modelVersion> | |||
<groupId>org.example</groupId> | |||
<artifactId>sms-msg-sender</artifactId> | |||
<version>1.0-SNAPSHOT</version> | |||
<properties> | |||
<maven.compiler.source>8</maven.compiler.source> | |||
<maven.compiler.target>8</maven.compiler.target> | |||
<revision>0.2.10</revision> | |||
<nacos-config-spring-boot.version>0.2.1</nacos-config-spring-boot.version> | |||
</properties> | |||
<dependencies> | |||
<dependency> | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-starter-web</artifactId> | |||
<version>2.0.3.RELEASE</version> | |||
<exclusions> | |||
<exclusion> | |||
<groupId>com.fasterxml.jackson.core</groupId> | |||
<artifactId>jackson-databind</artifactId> | |||
</exclusion> | |||
</exclusions> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.projectlombok</groupId> | |||
<artifactId>lombok</artifactId> | |||
<scope>provided</scope> | |||
<optional>true</optional> | |||
<version>1.16.22</version> | |||
</dependency> | |||
<!-- Testing Dependencies --> | |||
<dependency> | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-starter-test</artifactId> | |||
<scope>test</scope> | |||
<version>2.0.6.RELEASE</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>redis.clients</groupId> | |||
<artifactId>jedis</artifactId> | |||
<version>3.3.0</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>com.github.binarywang</groupId> | |||
<artifactId>weixin-java-mp</artifactId> | |||
<version>4.1.0</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>com.aliyun</groupId> | |||
<artifactId>dysmsapi20170525</artifactId> | |||
<version>2.0.5</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>com.alibaba</groupId> | |||
<artifactId>fastjson</artifactId> | |||
<version>1.2.44</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>com.alibaba.cloud</groupId> | |||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> | |||
<version>2.0.1.RELEASE</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.springframework.cloud</groupId> | |||
<artifactId>spring-cloud-starter-config</artifactId> | |||
<version>2.0.1.RELEASE</version> | |||
</dependency> | |||
</dependencies> | |||
<build> | |||
<resources> | |||
<resource> | |||
<directory>src/main/resources</directory> | |||
<filtering>true</filtering> | |||
</resource> | |||
</resources> | |||
<plugins> | |||
<plugin> | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-maven-plugin</artifactId> | |||
<version>2.0.6.RELEASE</version> | |||
<executions> | |||
<execution> | |||
<goals> | |||
<goal>repackage</goal> | |||
</goals> | |||
</execution> | |||
</executions> | |||
</plugin> | |||
</plugins> | |||
</build> | |||
<profiles> | |||
<profile> | |||
<id>dev</id> | |||
<activation> | |||
<activeByDefault>true</activeByDefault> | |||
</activation> | |||
<properties> | |||
<spring.profiles.active>dev</spring.profiles.active> | |||
</properties> | |||
</profile> | |||
<profile> | |||
<id>prod</id> | |||
<properties> | |||
<spring.profiles.active>prod</spring.profiles.active> | |||
</properties> | |||
</profile> | |||
</profiles> | |||
</project> |
@@ -0,0 +1,13 @@ | |||
package com.lecoo.wechat; | |||
import org.springframework.boot.SpringApplication; | |||
import org.springframework.boot.autoconfigure.SpringBootApplication; | |||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient; | |||
@SpringBootApplication | |||
@EnableDiscoveryClient | |||
public class App { | |||
public static void main(String[] args) { | |||
SpringApplication.run(App.class,args); | |||
} | |||
} |
@@ -0,0 +1,17 @@ | |||
package com.lecoo.wechat.builder; | |||
import me.chanjar.weixin.mp.api.WxMpService; | |||
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; | |||
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
/** | |||
* @author Binary Wang(https://github.com/binarywang) | |||
*/ | |||
public abstract class AbstractBuilder { | |||
protected final Logger logger = LoggerFactory.getLogger(getClass()); | |||
public abstract WxMpXmlOutMessage build(String content, | |||
WxMpXmlMessage wxMessage, WxMpService service); | |||
} |
@@ -0,0 +1,22 @@ | |||
package com.lecoo.wechat.builder; | |||
import me.chanjar.weixin.mp.api.WxMpService; | |||
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; | |||
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; | |||
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutTextMessage; | |||
/** | |||
* @author Binary Wang(https://github.com/binarywang) | |||
*/ | |||
public class TextBuilder extends AbstractBuilder { | |||
@Override | |||
public WxMpXmlOutMessage build(String content, WxMpXmlMessage wxMessage, | |||
WxMpService service) { | |||
WxMpXmlOutTextMessage m = WxMpXmlOutMessage.TEXT().content(content) | |||
.fromUser(wxMessage.getToUser()).toUser(wxMessage.getFromUser()) | |||
.build(); | |||
return m; | |||
} | |||
} |
@@ -0,0 +1,33 @@ | |||
package com.lecoo.wechat.config; | |||
import com.alibaba.nacos.api.config.ConfigType; | |||
import com.alibaba.nacos.api.config.annotation.NacosConfigurationProperties; | |||
import lombok.Data; | |||
import org.springframework.boot.context.properties.ConfigurationProperties; | |||
import org.springframework.stereotype.Component; | |||
/** | |||
* sms properties | |||
*/ | |||
@Data | |||
@Component | |||
@ConfigurationProperties(prefix = "sys.mms") | |||
//@NacosConfigurationProperties(prefix = "sys.mms", dataId = "ali-sms",type = ConfigType.YAML, groupId = "DEFAULT_GROUP", autoRefreshed = true) | |||
public class SmsProperties { | |||
private String accessKeyId; | |||
private String accessKeySecrect; | |||
private String endpoint; | |||
private String signName; | |||
private String signNameFront; | |||
private String signNameVisitor; | |||
private String template; | |||
private String carTemplate; | |||
private String fixedTemplate; | |||
private String codeTemplate; | |||
private String meetingOrderTemplate; | |||
private String meetingQuitTemplate; | |||
private String meetingRemindTemplate; | |||
private String defaultRemindTemplate; | |||
private String robotName; | |||
private String receptionPhones; | |||
} |
@@ -0,0 +1,129 @@ | |||
package com.lecoo.wechat.config; | |||
import com.lecoo.wechat.handler.*; | |||
import lombok.AllArgsConstructor; | |||
import me.chanjar.weixin.common.redis.JedisWxRedisOps; | |||
import me.chanjar.weixin.mp.api.WxMpMessageRouter; | |||
import me.chanjar.weixin.mp.api.WxMpService; | |||
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl; | |||
import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl; | |||
import me.chanjar.weixin.mp.config.impl.WxMpRedisConfigImpl; | |||
import org.springframework.boot.context.properties.EnableConfigurationProperties; | |||
import org.springframework.context.annotation.Bean; | |||
import org.springframework.context.annotation.Configuration; | |||
import redis.clients.jedis.JedisPool; | |||
import redis.clients.jedis.JedisPoolConfig; | |||
import java.util.List; | |||
import java.util.stream.Collectors; | |||
import static me.chanjar.weixin.common.api.WxConsts.EventType; | |||
import static me.chanjar.weixin.common.api.WxConsts.EventType.SUBSCRIBE; | |||
import static me.chanjar.weixin.common.api.WxConsts.EventType.UNSUBSCRIBE; | |||
import static me.chanjar.weixin.common.api.WxConsts.XmlMsgType; | |||
import static me.chanjar.weixin.common.api.WxConsts.XmlMsgType.EVENT; | |||
import static me.chanjar.weixin.mp.constant.WxMpEventConstants.CustomerService.*; | |||
import static me.chanjar.weixin.mp.constant.WxMpEventConstants.POI_CHECK_NOTIFY; | |||
/** | |||
* wechat mp configuration | |||
* | |||
* @author Binary Wang(https://github.com/binarywang) | |||
*/ | |||
@AllArgsConstructor | |||
@Configuration | |||
@EnableConfigurationProperties(WxMpProperties.class) | |||
public class WxMpConfiguration { | |||
private final LogHandler logHandler; | |||
private final NullHandler nullHandler; | |||
private final KfSessionHandler kfSessionHandler; | |||
private final StoreCheckNotifyHandler storeCheckNotifyHandler; | |||
private final LocationHandler locationHandler; | |||
private final MenuHandler menuHandler; | |||
private final MsgHandler msgHandler; | |||
private final UnsubscribeHandler unsubscribeHandler; | |||
private final SubscribeHandler subscribeHandler; | |||
private final ScanHandler scanHandler; | |||
private final WxMpProperties properties; | |||
@Bean | |||
public WxMpService wxMpService() { | |||
// 代码里 getConfigs()处报错的同学,请注意仔细阅读项目说明,你的IDE需要引入lombok插件!!!! | |||
final List<WxMpProperties.MpConfig> configs = this.properties.getConfigs(); | |||
if (configs == null) { | |||
throw new RuntimeException("大哥,拜托先看下项目首页的说明(readme文件),添加下相关配置,注意别配错了!"); | |||
} | |||
WxMpService service = new WxMpServiceImpl(); | |||
service.setMultiConfigStorages(configs | |||
.stream().map(a -> { | |||
WxMpDefaultConfigImpl configStorage; | |||
if (this.properties.isUseRedis()) { | |||
final WxMpProperties.RedisConfig redisConfig = this.properties.getRedisConfig(); | |||
JedisPoolConfig poolConfig = new JedisPoolConfig(); | |||
JedisPool jedisPool = new JedisPool(poolConfig, redisConfig.getHost(), redisConfig.getPort(), | |||
redisConfig.getTimeout(), redisConfig.getPassword()); | |||
configStorage = new WxMpRedisConfigImpl(new JedisWxRedisOps(jedisPool), a.getAppId()); | |||
} else { | |||
configStorage = new WxMpDefaultConfigImpl(); | |||
} | |||
configStorage.setAppId(a.getAppId()); | |||
configStorage.setSecret(a.getSecret()); | |||
configStorage.setToken(a.getToken()); | |||
configStorage.setAesKey(a.getAesKey()); | |||
return configStorage; | |||
}).collect(Collectors.toMap(WxMpDefaultConfigImpl::getAppId, a -> a, (o, n) -> o))); | |||
return service; | |||
} | |||
@Bean | |||
public WxMpMessageRouter messageRouter(WxMpService wxMpService) { | |||
final WxMpMessageRouter newRouter = new WxMpMessageRouter(wxMpService); | |||
// 记录所有事件的日志 (异步执行) | |||
newRouter.rule().handler(this.logHandler).next(); | |||
// 接收客服会话管理事件 | |||
newRouter.rule().async(false).msgType(EVENT).event(KF_CREATE_SESSION) | |||
.handler(this.kfSessionHandler).end(); | |||
newRouter.rule().async(false).msgType(EVENT).event(KF_CLOSE_SESSION) | |||
.handler(this.kfSessionHandler).end(); | |||
newRouter.rule().async(false).msgType(EVENT).event(KF_SWITCH_SESSION) | |||
.handler(this.kfSessionHandler).end(); | |||
// 门店审核事件 | |||
newRouter.rule().async(false).msgType(EVENT).event(POI_CHECK_NOTIFY).handler(this.storeCheckNotifyHandler).end(); | |||
// 自定义菜单事件 | |||
newRouter.rule().async(false).msgType(EVENT).event(EventType.CLICK).handler(this.menuHandler).end(); | |||
// 点击菜单连接事件 | |||
newRouter.rule().async(false).msgType(EVENT).event(EventType.VIEW).handler(this.nullHandler).end(); | |||
// 关注事件 | |||
newRouter.rule().async(false).msgType(EVENT).event(SUBSCRIBE).handler(this.subscribeHandler).end(); | |||
// 取消关注事件 | |||
newRouter.rule().async(false).msgType(EVENT).event(UNSUBSCRIBE).handler(this.unsubscribeHandler).end(); | |||
// 上报地理位置事件 | |||
newRouter.rule().async(false).msgType(EVENT).event(EventType.LOCATION).handler(this.locationHandler).end(); | |||
// 接收地理位置消息 | |||
newRouter.rule().async(false).msgType(XmlMsgType.LOCATION).handler(this.locationHandler).end(); | |||
// 扫码事件 | |||
newRouter.rule().async(false).msgType(EVENT).event(EventType.SCAN).handler(this.scanHandler).end(); | |||
// 默认 | |||
newRouter.rule().async(false).handler(this.msgHandler).end(); | |||
return newRouter; | |||
} | |||
public WxMpProperties getWxMpProperties(){ | |||
return this.properties; | |||
} | |||
} |
@@ -0,0 +1,105 @@ | |||
package com.lecoo.wechat.config; | |||
import com.alibaba.nacos.api.config.ConfigType; | |||
import com.alibaba.nacos.api.config.annotation.NacosConfigurationProperties; | |||
import lombok.Data; | |||
import org.springframework.boot.context.properties.ConfigurationProperties; | |||
import java.util.List; | |||
/** | |||
* wechat mp properties | |||
* | |||
* @author Binary Wang(https://github.com/binarywang) | |||
*/ | |||
@Data | |||
@ConfigurationProperties(prefix = "wx.mp") | |||
//@NacosConfigurationProperties(prefix = "wx.mp", dataId = "ali-sms",type = ConfigType.YAML, groupId = "DEFAULT_GROUP", autoRefreshed = true) | |||
public class WxMpProperties { | |||
/** | |||
* 是否使用redis存储access token | |||
*/ | |||
private boolean useRedis; | |||
/** | |||
* redis 配置 | |||
*/ | |||
private RedisConfig redisConfig; | |||
@Data | |||
public static class RedisConfig { | |||
/** | |||
* redis服务器 主机地址 | |||
*/ | |||
private String host; | |||
/** | |||
* redis服务器 端口号 | |||
*/ | |||
private Integer port; | |||
/** | |||
* redis服务器 密码 | |||
*/ | |||
private String password; | |||
/** | |||
* redis 服务连接超时时间 | |||
*/ | |||
private Integer timeout; | |||
} | |||
/** | |||
* 多个公众号配置信息 | |||
*/ | |||
private List<MpConfig> configs; | |||
@Data | |||
public static class MpConfig { | |||
/** | |||
* 设置微信公众号的appid | |||
*/ | |||
private String appId; | |||
/** | |||
* 设置微信公众号的app secret | |||
*/ | |||
private String secret; | |||
/** | |||
* 设置微信公众号的token | |||
*/ | |||
private String token; | |||
/** | |||
* 设置微信公众号的EncodingAESKey | |||
*/ | |||
private String aesKey; | |||
private String auditTemplateId; | |||
private String pushMsgTemplateId; | |||
private String regAuditTemplateId; | |||
private String url; | |||
} | |||
@Override | |||
public String toString() { | |||
return ""; | |||
} | |||
public List<MpConfig> getConfigs() { | |||
return configs; | |||
} | |||
public boolean isUseRedis() { | |||
return useRedis; | |||
} | |||
public RedisConfig getRedisConfig() { | |||
return redisConfig; | |||
} | |||
} |
@@ -0,0 +1,74 @@ | |||
package com.lecoo.wechat.controller; | |||
import com.alibaba.fastjson.JSONObject; | |||
import com.aliyun.dysmsapi20170525.models.SendSmsResponse; | |||
import com.lecoo.wechat.entity.SmsReqEntity; | |||
import com.lecoo.wechat.entity.WxMsgReqEntity; | |||
import com.lecoo.wechat.service.SmsService; | |||
import com.lecoo.wechat.utils.SendUtil; | |||
import me.chanjar.weixin.common.error.WxErrorException; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import org.springframework.web.bind.annotation.RequestBody; | |||
import org.springframework.web.bind.annotation.RequestMapping; | |||
import org.springframework.web.bind.annotation.RequestMethod; | |||
import org.springframework.web.bind.annotation.RestController; | |||
@RestController | |||
@RequestMapping("/notification/api") | |||
public class IndexController { | |||
@Autowired | |||
SendUtil sendUtil; | |||
@Autowired | |||
SmsService smsService; | |||
@RequestMapping(value = "/sendMsg", method = RequestMethod.POST, produces = "application/json;charset=UTF-8") | |||
public JSONObject sendMsg(@RequestBody WxMsgReqEntity wxMsgReqEntity) { | |||
JSONObject json = wxMsgReqEntity.toJson(); | |||
System.err.println(json); | |||
JSONObject result = new JSONObject(); | |||
result.put("status", 0); | |||
result.put("message", "send success!"); | |||
try { | |||
sendUtil.sendWxTemplateMsg(json); | |||
} catch (WxErrorException e) { | |||
result.put("status", -1); | |||
result.put("message", e.getMessage()); | |||
e.printStackTrace(); | |||
} | |||
return result; | |||
} | |||
@RequestMapping(value = "/sendSms", method = RequestMethod.POST, produces = "application/json;charset=UTF-8") | |||
public JSONObject sendSms(@RequestBody SmsReqEntity smsReqEntity) { | |||
System.err.println("receive a new req for send sms"); | |||
JSONObject result = new JSONObject(); | |||
result.put("status", 0); | |||
result.put("message", "send success!"); | |||
System.err.println(smsReqEntity.toJson().toJSONString()); | |||
try { | |||
SendSmsResponse sendSmsResponse = smsService.sendTempMmsMeeting(smsReqEntity); | |||
System.err.println(sendSmsResponse.getBody().getMessage()); | |||
System.err.println(sendSmsResponse.getBody().getCode()); | |||
System.err.println(sendSmsResponse.getBody().getCode()); | |||
if (sendSmsResponse.getBody().code.equalsIgnoreCase("ok")) { | |||
return result; | |||
} else { | |||
result.put("status", -1); | |||
result.put("message", sendSmsResponse.getBody().getMessage()); | |||
return result; | |||
} | |||
} catch (Exception e) { | |||
result.put("status", -1); | |||
result.put("message", e.getMessage()); | |||
e.printStackTrace(); | |||
} | |||
System.err.println(result.toJSONString()); | |||
System.err.println("send sms end..."); | |||
return result; | |||
} | |||
} |
@@ -0,0 +1,39 @@ | |||
package com.lecoo.wechat.entity; | |||
import com.alibaba.fastjson.JSONObject; | |||
import com.lecoo.wechat.utils.JsonUtils; | |||
import lombok.Data; | |||
import javax.validation.constraints.NotBlank; | |||
import java.util.Map; | |||
@Data | |||
public class SmsReqEntity { | |||
@NotBlank(message = "phone不能为空") | |||
private String phone; | |||
@NotBlank(message = "template不能为空") | |||
private String template; | |||
private String dataMap; | |||
public JSONObject toJson(){ | |||
JSONObject json = new JSONObject(true); | |||
json.put("phone", phone); | |||
json.put("template", template); | |||
if(dataMap!= null && dataMap.length() > 0){ | |||
JSONObject jsonObject = JSONObject.parseObject(dataMap); | |||
jsonObject.forEach((key, item)->{ | |||
json.put(key, item); | |||
}); | |||
} | |||
return json; | |||
} | |||
public String mapToString(){ | |||
JSONObject jsonObject = JSONObject.parseObject(dataMap); | |||
return jsonObject ==null ? "" : jsonObject.toJSONString(); | |||
} | |||
} |
@@ -0,0 +1,42 @@ | |||
package com.lecoo.wechat.entity; | |||
import com.alibaba.fastjson.JSONObject; | |||
import lombok.Data; | |||
import javax.validation.constraints.NotBlank; | |||
@Data | |||
public class WxMsgReqEntity { | |||
@NotBlank(message = "openid不能为空") | |||
private String openid; | |||
@NotBlank(message = "url不能为空") | |||
private String url; | |||
@NotBlank(message = "templateId不能为空") | |||
private String templateId; | |||
private String first; | |||
private String second; | |||
private String three; | |||
private String four; | |||
private String five; | |||
private String six; | |||
public JSONObject toJson(){ | |||
JSONObject json = new JSONObject(true); | |||
json.put("openid", openid); | |||
json.put("url", url); | |||
json.put("templateId", templateId); | |||
if (null != first) | |||
json.put("first", first); | |||
if (null != second) | |||
json.put("second", second); | |||
if (null != three) | |||
json.put("three", three); | |||
if (null != four) | |||
json.put("four", four); | |||
if (null != five) | |||
json.put("five", five); | |||
if (null != six) | |||
json.put("six", six); | |||
return json; | |||
} | |||
} |
@@ -0,0 +1,12 @@ | |||
package com.lecoo.wechat.handler; | |||
import me.chanjar.weixin.mp.api.WxMpMessageHandler; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
/** | |||
* @author Binary Wang(https://github.com/binarywang) | |||
*/ | |||
public abstract class AbstractHandler implements WxMpMessageHandler { | |||
protected Logger logger = LoggerFactory.getLogger(getClass()); | |||
} |
@@ -0,0 +1,52 @@ | |||
package com.lecoo.wechat.handler; | |||
import com.alibaba.fastjson.JSONObject; | |||
import org.springframework.http.HttpStatus; | |||
import org.springframework.validation.BindException; | |||
import org.springframework.validation.FieldError; | |||
import org.springframework.web.bind.MethodArgumentNotValidException; | |||
import org.springframework.web.bind.annotation.ControllerAdvice; | |||
import org.springframework.web.bind.annotation.ExceptionHandler; | |||
import org.springframework.web.bind.annotation.ResponseBody; | |||
import org.springframework.web.bind.annotation.ResponseStatus; | |||
@ControllerAdvice | |||
public class ControllerExceptionHandler { | |||
@ExceptionHandler(Exception.class) | |||
@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR) | |||
@ResponseBody | |||
public JSONObject exceptionHandler(Exception exception) { | |||
exception.printStackTrace(); | |||
JSONObject jsonObject = new JSONObject(); | |||
if (exception instanceof MethodArgumentNotValidException) { | |||
JSONObject temp = new JSONObject(); | |||
((MethodArgumentNotValidException) exception).getBindingResult().getAllErrors().forEach((error) -> { | |||
String fieldName = ((FieldError) error).getField(); | |||
String errorMessage = error.getDefaultMessage(); | |||
temp.put(fieldName, errorMessage); | |||
}); | |||
jsonObject.put("status", 500); | |||
jsonObject.put("errors", temp); | |||
return jsonObject; | |||
} else if (exception instanceof BindException) { | |||
JSONObject temp = new JSONObject(); | |||
((BindException) exception).getBindingResult().getAllErrors().forEach((error) -> { | |||
String fieldName = ((FieldError) error).getField(); | |||
String errorMessage = error.getDefaultMessage(); | |||
temp.put(fieldName, errorMessage); | |||
}); | |||
jsonObject.put("status", 500); | |||
jsonObject.put("errors", temp); | |||
return jsonObject; | |||
} else { | |||
} | |||
JSONObject temp = new JSONObject(); | |||
temp.put("message", exception.getMessage()); | |||
jsonObject.put("status", 500); | |||
jsonObject.put("errors", temp); | |||
return jsonObject; | |||
} | |||
} |
@@ -0,0 +1,25 @@ | |||
package com.lecoo.wechat.handler; | |||
import me.chanjar.weixin.common.session.WxSessionManager; | |||
import me.chanjar.weixin.mp.api.WxMpService; | |||
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; | |||
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; | |||
import org.springframework.stereotype.Component; | |||
import java.util.Map; | |||
/** | |||
* @author Binary Wang(https://github.com/binarywang) | |||
*/ | |||
@Component | |||
public class KfSessionHandler extends AbstractHandler { | |||
@Override | |||
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, | |||
Map<String, Object> context, WxMpService wxMpService, | |||
WxSessionManager sessionManager) { | |||
//TODO 对会话做处理 | |||
return null; | |||
} | |||
} |
@@ -0,0 +1,44 @@ | |||
package com.lecoo.wechat.handler; | |||
import com.lecoo.wechat.builder.TextBuilder; | |||
import me.chanjar.weixin.common.session.WxSessionManager; | |||
import me.chanjar.weixin.mp.api.WxMpService; | |||
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; | |||
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; | |||
import org.springframework.stereotype.Component; | |||
import java.util.Map; | |||
import static me.chanjar.weixin.common.api.WxConsts.XmlMsgType; | |||
/** | |||
* @author Binary Wang(https://github.com/binarywang) | |||
*/ | |||
@Component | |||
public class LocationHandler extends AbstractHandler { | |||
@Override | |||
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, | |||
Map<String, Object> context, WxMpService wxMpService, | |||
WxSessionManager sessionManager) { | |||
if (wxMessage.getMsgType().equals(XmlMsgType.LOCATION)) { | |||
//TODO 接收处理用户发送的地理位置消息 | |||
try { | |||
String content = "感谢反馈,您的的地理位置已收到!"; | |||
return new TextBuilder().build(content, wxMessage, null); | |||
} catch (Exception e) { | |||
this.logger.error("位置消息接收处理失败", e); | |||
return null; | |||
} | |||
} | |||
//上报地理位置事件 | |||
this.logger.info("上报地理位置,纬度 : {},经度 : {},精度 : {}", | |||
wxMessage.getLatitude(), wxMessage.getLongitude(), String.valueOf(wxMessage.getPrecision())); | |||
//TODO 可以将用户地理位置信息保存到本地数据库,以便以后使用 | |||
return null; | |||
} | |||
} |
@@ -0,0 +1,25 @@ | |||
package com.lecoo.wechat.handler; | |||
import com.lecoo.wechat.utils.JsonUtils; | |||
import me.chanjar.weixin.common.session.WxSessionManager; | |||
import me.chanjar.weixin.mp.api.WxMpService; | |||
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; | |||
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; | |||
import org.springframework.stereotype.Component; | |||
import java.util.Map; | |||
/** | |||
* @author Binary Wang(https://github.com/binarywang) | |||
*/ | |||
@Component | |||
public class LogHandler extends AbstractHandler { | |||
@Override | |||
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, | |||
Map<String, Object> context, WxMpService wxMpService, | |||
WxSessionManager sessionManager) { | |||
this.logger.info("\n接收到请求消息,内容:{}", JsonUtils.toJson(wxMessage)); | |||
return null; | |||
} | |||
} |
@@ -0,0 +1,35 @@ | |||
package com.lecoo.wechat.handler; | |||
import me.chanjar.weixin.common.session.WxSessionManager; | |||
import me.chanjar.weixin.mp.api.WxMpService; | |||
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; | |||
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; | |||
import org.springframework.stereotype.Component; | |||
import java.util.Map; | |||
import static me.chanjar.weixin.common.api.WxConsts.EventType; | |||
/** | |||
* @author Binary Wang(https://github.com/binarywang) | |||
*/ | |||
@Component | |||
public class MenuHandler extends AbstractHandler { | |||
@Override | |||
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, | |||
Map<String, Object> context, WxMpService weixinService, | |||
WxSessionManager sessionManager) { | |||
String msg = String.format("type:%s, event:%s, key:%s", | |||
wxMessage.getMsgType(), wxMessage.getEvent(), | |||
wxMessage.getEventKey()); | |||
if (EventType.VIEW.equals(wxMessage.getEvent())) { | |||
return null; | |||
} | |||
return WxMpXmlOutMessage.TEXT().content(msg) | |||
.fromUser(wxMessage.getToUser()).toUser(wxMessage.getFromUser()) | |||
.build(); | |||
} | |||
} |
@@ -0,0 +1,51 @@ | |||
package com.lecoo.wechat.handler; | |||
import com.lecoo.wechat.builder.TextBuilder; | |||
import me.chanjar.weixin.common.error.WxErrorException; | |||
import me.chanjar.weixin.common.session.WxSessionManager; | |||
import me.chanjar.weixin.mp.api.WxMpService; | |||
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; | |||
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; | |||
import org.apache.commons.lang3.StringUtils; | |||
import org.springframework.stereotype.Component; | |||
import java.util.Map; | |||
import static me.chanjar.weixin.common.api.WxConsts.XmlMsgType; | |||
/** | |||
* @author Binary Wang(https://github.com/binarywang) | |||
*/ | |||
@Component | |||
public class MsgHandler extends AbstractHandler { | |||
@Override | |||
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, | |||
Map<String, Object> context, WxMpService weixinService, | |||
WxSessionManager sessionManager) { | |||
if (!wxMessage.getMsgType().equals(XmlMsgType.EVENT)) { | |||
//TODO 可以选择将消息保存到本地 | |||
} | |||
//当用户输入关键词如“你好”,“客服”等,并且有客服在线时,把消息转发给在线客服 | |||
try { | |||
if (StringUtils.startsWithAny(wxMessage.getContent(), "你好", "客服") | |||
&& weixinService.getKefuService().kfOnlineList() | |||
.getKfOnlineList().size() > 0) { | |||
return WxMpXmlOutMessage.TRANSFER_CUSTOMER_SERVICE() | |||
.fromUser(wxMessage.getToUser()) | |||
.toUser(wxMessage.getFromUser()).build(); | |||
} | |||
} catch (WxErrorException e) { | |||
e.printStackTrace(); | |||
} | |||
//TODO 组装回复消息 | |||
String content = "收到信息内容:好的,已收到您的回复"; | |||
return new TextBuilder().build(content, wxMessage, weixinService); | |||
} | |||
} |
@@ -0,0 +1,24 @@ | |||
package com.lecoo.wechat.handler; | |||
import me.chanjar.weixin.common.session.WxSessionManager; | |||
import me.chanjar.weixin.mp.api.WxMpService; | |||
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; | |||
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; | |||
import org.springframework.stereotype.Component; | |||
import java.util.Map; | |||
/** | |||
* @author Binary Wang(https://github.com/binarywang) | |||
*/ | |||
@Component | |||
public class NullHandler extends AbstractHandler { | |||
@Override | |||
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, | |||
Map<String, Object> context, WxMpService wxMpService, | |||
WxSessionManager sessionManager) { | |||
return null; | |||
} | |||
} |
@@ -0,0 +1,24 @@ | |||
package com.lecoo.wechat.handler; | |||
import me.chanjar.weixin.common.error.WxErrorException; | |||
import me.chanjar.weixin.common.session.WxSessionManager; | |||
import me.chanjar.weixin.mp.api.WxMpService; | |||
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; | |||
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; | |||
import org.springframework.stereotype.Component; | |||
import java.util.Map; | |||
/** | |||
* @author Binary Wang(https://github.com/binarywang) | |||
*/ | |||
@Component | |||
public class ScanHandler extends AbstractHandler { | |||
@Override | |||
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMpXmlMessage, Map<String, Object> map, | |||
WxMpService wxMpService, WxSessionManager wxSessionManager) throws WxErrorException { | |||
// 扫码事件处理 | |||
return null; | |||
} | |||
} |
@@ -0,0 +1,27 @@ | |||
package com.lecoo.wechat.handler; | |||
import me.chanjar.weixin.common.session.WxSessionManager; | |||
import me.chanjar.weixin.mp.api.WxMpService; | |||
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; | |||
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; | |||
import org.springframework.stereotype.Component; | |||
import java.util.Map; | |||
/** | |||
* 门店审核事件处理 | |||
* | |||
* @author Binary Wang(https://github.com/binarywang) | |||
*/ | |||
@Component | |||
public class StoreCheckNotifyHandler extends AbstractHandler { | |||
@Override | |||
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, | |||
Map<String, Object> context, WxMpService wxMpService, | |||
WxSessionManager sessionManager) { | |||
// TODO 处理门店审核事件 | |||
return null; | |||
} | |||
} |
@@ -0,0 +1,71 @@ | |||
package com.lecoo.wechat.handler; | |||
import com.lecoo.wechat.builder.TextBuilder; | |||
import me.chanjar.weixin.common.error.WxErrorException; | |||
import me.chanjar.weixin.common.session.WxSessionManager; | |||
import me.chanjar.weixin.mp.api.WxMpService; | |||
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; | |||
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; | |||
import me.chanjar.weixin.mp.bean.result.WxMpUser; | |||
import org.springframework.stereotype.Component; | |||
import java.util.Map; | |||
/** | |||
* @author Binary Wang(https://github.com/binarywang) | |||
*/ | |||
@Component | |||
public class SubscribeHandler extends AbstractHandler { | |||
@Override | |||
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, | |||
Map<String, Object> context, WxMpService weixinService, | |||
WxSessionManager sessionManager) throws WxErrorException { | |||
this.logger.info("新关注用户 OPENID: " + wxMessage.getFromUser()); | |||
// 获取微信用户基本信息 | |||
try { | |||
WxMpUser userWxInfo = weixinService.getUserService() | |||
.userInfo(wxMessage.getFromUser(), null); | |||
if (userWxInfo != null) { | |||
// TODO 可以添加关注用户到本地数据库 | |||
System.out.println(userWxInfo); | |||
} | |||
} catch (WxErrorException e) { | |||
if (e.getError().getErrorCode() == 48001) { | |||
this.logger.info("该公众号没有获取用户信息权限!"); | |||
} | |||
} | |||
WxMpXmlOutMessage responseResult = null; | |||
try { | |||
responseResult = this.handleSpecial(wxMessage); | |||
} catch (Exception e) { | |||
this.logger.error(e.getMessage(), e); | |||
} | |||
if (responseResult != null) { | |||
return responseResult; | |||
} | |||
try { | |||
return new TextBuilder().build("感谢关注", wxMessage, weixinService); | |||
} catch (Exception e) { | |||
this.logger.error(e.getMessage(), e); | |||
} | |||
return null; | |||
} | |||
/** | |||
* 处理特殊请求,比如如果是扫码进来的,可以做相应处理 | |||
*/ | |||
private WxMpXmlOutMessage handleSpecial(WxMpXmlMessage wxMessage) | |||
throws Exception { | |||
//TODO | |||
return null; | |||
} | |||
} |
@@ -0,0 +1,27 @@ | |||
package com.lecoo.wechat.handler; | |||
import me.chanjar.weixin.common.session.WxSessionManager; | |||
import me.chanjar.weixin.mp.api.WxMpService; | |||
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; | |||
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; | |||
import org.springframework.stereotype.Component; | |||
import java.util.Map; | |||
/** | |||
* @author Binary Wang(https://github.com/binarywang) | |||
*/ | |||
@Component | |||
public class UnsubscribeHandler extends AbstractHandler { | |||
@Override | |||
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, | |||
Map<String, Object> context, WxMpService wxMpService, | |||
WxSessionManager sessionManager) { | |||
String openId = wxMessage.getFromUser(); | |||
this.logger.info("取消关注用户 OPENID: " + openId); | |||
// TODO 可以更新本地数据库为取消关注状态 | |||
return null; | |||
} | |||
} |
@@ -0,0 +1,234 @@ | |||
package com.lecoo.wechat.service; | |||
import com.alibaba.fastjson.JSONObject; | |||
import com.aliyun.dysmsapi20170525.models.SendSmsRequest; | |||
import com.aliyun.dysmsapi20170525.models.SendSmsResponse; | |||
import com.aliyun.teaopenapi.models.Config; | |||
import com.lecoo.wechat.config.SmsProperties; | |||
import com.lecoo.wechat.entity.SmsReqEntity; | |||
import lombok.AllArgsConstructor; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import org.springframework.stereotype.Component; | |||
import java.util.Map; | |||
import java.util.Set; | |||
/** | |||
* spring sms 工具类 | |||
* | |||
* @author xueyi | |||
**/ | |||
@Component | |||
@AllArgsConstructor | |||
@SuppressWarnings(value = {"unchecked", "rawtypes"}) | |||
public class SmsService { | |||
@Autowired | |||
private SmsProperties sendMmsProperties; | |||
public String getReceptionPhones(){ | |||
return sendMmsProperties.getReceptionPhones(); | |||
} | |||
public SendSmsResponse sendTempMms(String phone, String paramStr, boolean hasCar) throws Exception { | |||
Config config = new Config() | |||
// 您的AccessKey ID | |||
.setAccessKeyId(sendMmsProperties.getAccessKeyId()) | |||
// 您的AccessKey Secret | |||
.setAccessKeySecret(sendMmsProperties.getAccessKeySecrect()); | |||
// 访问的域名 | |||
config.endpoint = sendMmsProperties.getEndpoint(); | |||
com.aliyun.dysmsapi20170525.Client client = new com.aliyun.dysmsapi20170525.Client(config); | |||
SendSmsRequest sendSmsRequest = new SendSmsRequest() | |||
.setPhoneNumbers(phone) | |||
.setSignName(sendMmsProperties.getSignNameVisitor()) | |||
.setTemplateCode(hasCar?sendMmsProperties.getCarTemplate():sendMmsProperties.getTemplate()) | |||
.setTemplateParam(paramStr); | |||
// 复制代码运行请自行打印 API 的返回值 | |||
SendSmsResponse res = client.sendSms(sendSmsRequest); | |||
return res; | |||
} | |||
public SendSmsResponse sendTempMmsFixed(String phone, String paramStr) throws Exception { | |||
Config config = new Config() | |||
// 您的AccessKey ID | |||
.setAccessKeyId(sendMmsProperties.getAccessKeyId()) | |||
// 您的AccessKey Secret | |||
.setAccessKeySecret(sendMmsProperties.getAccessKeySecrect()); | |||
// 访问的域名 | |||
config.endpoint = sendMmsProperties.getEndpoint(); | |||
com.aliyun.dysmsapi20170525.Client client = new com.aliyun.dysmsapi20170525.Client(config); | |||
SendSmsRequest sendSmsRequest = new SendSmsRequest() | |||
.setPhoneNumbers(phone) | |||
.setSignName(sendMmsProperties.getSignNameVisitor()) | |||
.setTemplateCode(sendMmsProperties.getFixedTemplate()) | |||
.setTemplateParam(paramStr); | |||
// 复制代码运行请自行打印 API 的返回值 | |||
SendSmsResponse res = client.sendSms(sendSmsRequest); | |||
return res; | |||
} | |||
public SendSmsResponse sendTempMmsCode(String phone, String code) throws Exception { | |||
Config config = new Config() | |||
// 您的AccessKey ID | |||
.setAccessKeyId(sendMmsProperties.getAccessKeyId()) | |||
// 您的AccessKey Secret | |||
.setAccessKeySecret(sendMmsProperties.getAccessKeySecrect()); | |||
// 访问的域名 | |||
config.endpoint = sendMmsProperties.getEndpoint(); | |||
com.aliyun.dysmsapi20170525.Client client = new com.aliyun.dysmsapi20170525.Client(config); | |||
JSONObject json = new JSONObject(); | |||
json.put("code", code); | |||
SendSmsRequest sendSmsRequest = new SendSmsRequest() | |||
.setPhoneNumbers(phone) | |||
.setSignName(sendMmsProperties.getSignName()) | |||
.setTemplateCode(sendMmsProperties.getCodeTemplate()) | |||
.setTemplateParam(json.toJSONString()); | |||
// 复制代码运行请自行打印 API 的返回值 | |||
SendSmsResponse res = client.sendSms(sendSmsRequest); | |||
return res; | |||
} | |||
public void test(){ | |||
System.out.println(sendMmsProperties); | |||
} | |||
public SendSmsResponse sendTempMmsMeeting(String phone, Integer type, Map<String, String> dataMap) throws Exception { | |||
Config config = new Config() | |||
// 您的AccessKey ID | |||
.setAccessKeyId(sendMmsProperties.getAccessKeyId()) | |||
// 您的AccessKey Secret | |||
.setAccessKeySecret(sendMmsProperties.getAccessKeySecrect()); | |||
// 访问的域名 | |||
config.endpoint = sendMmsProperties.getEndpoint(); | |||
com.aliyun.dysmsapi20170525.Client client = new com.aliyun.dysmsapi20170525.Client(config); | |||
String template = ""; | |||
if (type == 1) { | |||
template = sendMmsProperties.getMeetingOrderTemplate(); | |||
} else if (type == 2) { | |||
template = sendMmsProperties.getMeetingQuitTemplate(); | |||
} else { | |||
template = sendMmsProperties.getMeetingRemindTemplate(); | |||
} | |||
JSONObject json = new JSONObject(); | |||
Set<String> kSet = dataMap.keySet(); | |||
for (String key : kSet) { | |||
json.put(key, dataMap.get(key)); | |||
} | |||
// json.put("name", meetingRoomOrder.getOrderByEmp()); | |||
// json.put("dateStr", meetingRoomOrder.getOrderData()); | |||
json.put("rebotName", sendMmsProperties.getRobotName()); | |||
SendSmsRequest sendSmsRequest = new SendSmsRequest() | |||
.setPhoneNumbers(phone) | |||
.setSignName(sendMmsProperties.getSignName()) | |||
.setTemplateCode(template) | |||
.setTemplateParam(json.toJSONString()); | |||
// 复制代码运行请自行打印 API 的返回值 | |||
SendSmsResponse res = client.sendSms(sendSmsRequest); | |||
return res; | |||
} | |||
public SendSmsResponse sendTempMmsMeeting(SmsReqEntity smsReqEntity) throws Exception { | |||
Config config = new Config() | |||
// 您的AccessKey ID | |||
.setAccessKeyId(sendMmsProperties.getAccessKeyId()) | |||
// 您的AccessKey Secret | |||
.setAccessKeySecret(sendMmsProperties.getAccessKeySecrect()); | |||
// 访问的域名 | |||
config.endpoint = sendMmsProperties.getEndpoint(); | |||
com.aliyun.dysmsapi20170525.Client client = new com.aliyun.dysmsapi20170525.Client(config); | |||
String template = smsReqEntity.getTemplate(); | |||
SendSmsRequest sendSmsRequest = new SendSmsRequest() | |||
.setPhoneNumbers(smsReqEntity.getPhone()) | |||
.setSignName(sendMmsProperties.getSignName()) | |||
.setTemplateCode(template) | |||
.setTemplateParam(smsReqEntity.mapToString()); | |||
// 复制代码运行请自行打印 API 的返回值 | |||
SendSmsResponse res = client.sendSms(sendSmsRequest); | |||
return res; | |||
} | |||
/*public SendSmsResponse sendTempMmsMeeting(String phone, MeetingRoomOrder meetingRoomOrder, Integer type) throws Exception { | |||
Config config = new Config() | |||
// 您的AccessKey ID | |||
.setAccessKeyId(sendMmsProperties.getAccessKeyId()) | |||
// 您的AccessKey Secret | |||
.setAccessKeySecret(sendMmsProperties.getAccessKeySecrect()); | |||
// 访问的域名 | |||
config.endpoint = sendMmsProperties.getEndpoint(); | |||
com.aliyun.dysmsapi20170525.Client client = new com.aliyun.dysmsapi20170525.Client(config); | |||
String template = ""; | |||
if (type == 1) { | |||
template = sendMmsProperties.getMeetingOrderTemplate(); | |||
} else if (type == 2) { | |||
template = sendMmsProperties.getMeetingQuitTemplate(); | |||
} else { | |||
template = sendMmsProperties.getMeetingRemindTemplate(); | |||
} | |||
JSONObject json = new JSONObject(); | |||
json.put("name", meetingRoomOrder.getOrderByEmp()); | |||
json.put("dateStr", meetingRoomOrder.getOrderData()); | |||
json.put("rebotName", sendMmsProperties.getRobotName()); | |||
SendSmsRequest sendSmsRequest = new SendSmsRequest() | |||
.setPhoneNumbers(phone) | |||
.setSignName(sendMmsProperties.getSignName()) | |||
.setTemplateCode(template) | |||
.setTemplateParam(json.toJSONString()); | |||
// 复制代码运行请自行打印 API 的返回值 | |||
SendSmsResponse res = client.sendSms(sendSmsRequest); | |||
return res; | |||
}*/ | |||
public SendSmsResponse sendMmsToDefault(String phone) throws Exception{ | |||
Config config = new Config() | |||
// 您的AccessKey ID | |||
.setAccessKeyId(sendMmsProperties.getAccessKeyId()) | |||
// 您的AccessKey Secret | |||
.setAccessKeySecret(sendMmsProperties.getAccessKeySecrect()); | |||
// 访问的域名 | |||
config.endpoint = sendMmsProperties.getEndpoint(); | |||
com.aliyun.dysmsapi20170525.Client client = new com.aliyun.dysmsapi20170525.Client(config); | |||
String template = sendMmsProperties.getDefaultRemindTemplate(); | |||
JSONObject json = new JSONObject(); | |||
SendSmsRequest sendSmsRequest = new SendSmsRequest() | |||
.setPhoneNumbers(phone) | |||
.setSignName(sendMmsProperties.getSignName()) | |||
.setTemplateCode(template) | |||
.setTemplateParam(json.toJSONString()); | |||
// 复制代码运行请自行打印 API 的返回值 | |||
SendSmsResponse res = client.sendSms(sendSmsRequest); | |||
return res; | |||
} | |||
} | |||
@@ -0,0 +1,17 @@ | |||
package com.lecoo.wechat.utils; | |||
import com.google.gson.Gson; | |||
import com.google.gson.GsonBuilder; | |||
/** | |||
* @author Binary Wang(https://github.com/binarywang) | |||
*/ | |||
public class JsonUtils { | |||
public static String toJson(Object obj) { | |||
Gson gson = new GsonBuilder() | |||
.setPrettyPrinting() | |||
.disableHtmlEscaping() | |||
.create(); | |||
return gson.toJson(obj); | |||
} | |||
} |
@@ -0,0 +1,61 @@ | |||
/** | |||
* @project AppService | |||
* @filename SignUtil.java | |||
* @date 2016年8月31日 | |||
* @author KeShanqiang | |||
*/ | |||
package com.lecoo.wechat.utils; | |||
import com.alibaba.fastjson.JSONObject; | |||
import com.lecoo.wechat.config.WxMpProperties; | |||
import lombok.AllArgsConstructor; | |||
import me.chanjar.weixin.common.error.WxErrorException; | |||
import me.chanjar.weixin.mp.api.WxMpService; | |||
import me.chanjar.weixin.mp.bean.template.WxMpTemplateData; | |||
import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import org.springframework.stereotype.Component; | |||
import java.util.Set; | |||
@AllArgsConstructor | |||
@Component | |||
public class SendUtil { | |||
@Autowired | |||
private final WxMpService wxService; | |||
public String sendWxTemplateMsg(JSONObject jsonObject) throws WxErrorException { | |||
if (jsonObject.size()<4) { | |||
return "不合法的参数。。。。"; | |||
} | |||
Set keySet = jsonObject.keySet(); | |||
Object[] keyAry = keySet.toArray(); | |||
Integer i = 0, j = 1; | |||
String openid = (String) jsonObject.get(keyAry[i++]); | |||
String url = (String) jsonObject.get(keyAry[i++]); | |||
String templateId = (String) jsonObject.get(keyAry[i++]); | |||
WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder() | |||
.toUser(openid) | |||
.templateId(templateId) | |||
.url(url) | |||
.build(); | |||
templateMessage.addData(new WxMpTemplateData("first", (String) jsonObject.get(keyAry[i++]), "#FF00FF")); | |||
while (i<keyAry.length && j<6) { | |||
templateMessage.addData(new WxMpTemplateData("keyword"+(j++), (String) jsonObject.get(keyAry[i++]), "#000")); | |||
} | |||
templateMessage.addData(new WxMpTemplateData("remark", (String) jsonObject.get(keyAry[keyAry.length-1]), "#000")); | |||
String msgId = this.wxService.getTemplateMsgService().sendTemplateMsg(templateMessage); | |||
return msgId; | |||
} | |||
} |
@@ -0,0 +1,63 @@ | |||
server: | |||
port: 9950 | |||
nacos: | |||
config: | |||
server-addr: 127.0.0.1:8848 | |||
# namespace: 6d0ee265-2a92-44cc-a6de-f34b3ea104e6 | |||
enabled: true | |||
file-extension: yaml | |||
blocking-queue-size: 5000 | |||
sys: | |||
baseUrl: http://dev.hjkjg.top | |||
mms: | |||
receptionPhones: 18910801519 | |||
# accessKeyId: LTAI5tR67Z2jD21XdjZppe2E | |||
# accessKeySecrect: 1q8QkQEzc8UZ3JmH8nt73tP1etO5Px | |||
accessKeyId: LTAI5tBxoXcHTkMZv1jUwCT8 | |||
accessKeySecrect: E8i2eWczpxOIcYGtX9D0lNJtHApmh2 | |||
endpoint: dysmsapi.aliyuncs.com | |||
signName: 缔智元 | |||
signNameVisitor: 缔智元 | |||
template: SMS_228835440 | |||
carTemplate: SMS_228850376 | |||
fixedTemplate: SMS_228835443 | |||
codeTemplate: SMS_229300003 | |||
meetingOrderTemplate: SMS_460710519 | |||
meetingQuitTemplate: SMS_460685561 | |||
meetingRemindTemplate: SMS_460655546 | |||
defaultRemindTemplate: SMS_460715556 | |||
visitorTemplate: SMS_461045124 | |||
robotName: 小酷 | |||
wx: | |||
mp: | |||
useRedis: false | |||
redisConfig: | |||
host: 127.0.0.1 | |||
port: 6379 | |||
configs: | |||
- appId: wxde105494dd27c1ac # 第一个公众号的appid | |||
secret: f81e44ef5a1ed2235ce471f0ee3d1445 # 公众号的appsecret | |||
token: 83u4h # 接口配置里的Token值 | |||
pushMsgTemplateId: BQlE4WmvD6C2YG6aMYUxlSztBYbiSFe_KjQaneTWrHY | |||
auditTemplateId: Y1qGJ7SjY4GFky9V101dV8rYQzDR1uZ8g3e6d16M1Ts | |||
regAuditTemplateId: RYDfkUjIRHnCWSy_O1XfDaFT9uE-jYqDAtrpkp49350 | |||
url: ${sys.baseUrl}/f/wx/oauth2 | |||
spring: | |||
application: | |||
name: sms-msg-sender # 业务服务的名称,用于注册到nacos中 | |||
cloud: | |||
nacos: | |||
discovery: | |||
server-addr: 127.0.0.1:18848 # nacos的服务地址 | |||
config: | |||
server-addr: 127.0.0.1:18848 # nacos的配置地址 | |||
file-extension: yml # 配置文件扩展名,默认为yml | |||
data-id: ali-sms.yml # 配置文件名称,可以自定义 | |||