diff --git a/doc/开发规范/命名规范.txt b/doc/开发规范/命名规范.txt
new file mode 100644
index 0000000000..684d4b35ef
--- /dev/null
+++ b/doc/开发规范/命名规范.txt
@@ -0,0 +1,19 @@
+dao层:
+1、结果集是集合用selectListXXX
+2、结果集为一个实例用selectOneXXX
+3、更新:updateXXX
+4、插入:insertXXX
+5、删除:deleteXXX
+6、获取统计值的方法用 selectCount
+service层:
+1、结果集是集合:listXXX
+2、结果集是一个实例:getXXX
+3、插入:saveXXX
+5、修改:modifyXXX
+4、删除:removeXXX
+5、获取统计值的方法用 countXXX
+
+
+数据传输对象:xxxDTO,xxx 为业务领域相关的名称
+
+controller层根据接口定义来取名,接口定的什么就取什么
diff --git a/doc/开发规范/阿里巴巴java开发规范1.4.pdf b/doc/开发规范/阿里巴巴java开发规范1.4.pdf
new file mode 100644
index 0000000000..35865f0599
Binary files /dev/null and b/doc/开发规范/阿里巴巴java开发规范1.4.pdf differ
diff --git a/epmet-auth/pom.xml b/epmet-auth/pom.xml
index 60da2cf0de..ed67039a6c 100644
--- a/epmet-auth/pom.xml
+++ b/epmet-auth/pom.xml
@@ -105,6 +105,15 @@
false
+
+
+ wx3ef8f2cd12a19fcb
+ 948aa2f21dbaa3943288ea5b119ac6f2
+ 111
+ 111
+
+ wxdd8530c5f4926766
+ 5bf4fb813145431b3493a10aa7e041e9
diff --git a/epmet-auth/src/main/resources/bootstrap.yml b/epmet-auth/src/main/resources/bootstrap.yml
index c8cf9d6c75..dc2f8aef3b 100644
--- a/epmet-auth/src/main/resources/bootstrap.yml
+++ b/epmet-auth/src/main/resources/bootstrap.yml
@@ -92,3 +92,34 @@ jwt:
secret: f4e2e52034348f86b67cde5[www.renren.io]
#token有效时长,默认7天,单位秒
expire: 604800
+wx:
+ mp:
+ configs:
+ - appId: @wx.mp.configs.appId@
+ secret: @wx.mp.configs.secret@
+ token: @wx.mp.configs.token@
+ aesKey: @wx.mp.configs.aesKey@
+ ma:
+ configs:
+ - appid: @resi.wx.ma.appId@
+ secret: @resi.wx.ma.secret@
+ token: #微信小程序消息服务器配置的token
+ aesKey: #微信小程序消息服务器配置的EncodingAESKey
+ msgDataFormat: JSON
+# - appid: @gov.wx.ma.appId@
+# secret: @gov.wx.ma.secret@
+# token: #微信小程序消息服务器配置的token
+# aesKey: #微信小程序消息服务器配置的EncodingAESKey
+# msgDataFormat: JSON
+# - appid: @oper.wx.ma.appId@
+# secret: @oper.wx.ma.secret@
+# token: #微信小程序消息服务器配置的token
+# aesKey: #微信小程序消息服务器配置的EncodingAESKey
+# msgDataFormat: JSON
+ appId:
+ # 党群e事通-居民端小程序配置appId
+ resi: @resi.wx.ma.appId@
+ # 党群e事通-政府端小程序配置的appId
+ #gov: @gov.wx.ma.appId@
+ # 党群e事通-运营端小程序配置的appId
+ #oper: @oper.wx.ma.appId@
diff --git a/epmet-commons/epmet-common-clienttoken/pom.xml b/epmet-commons/epmet-common-clienttoken/pom.xml
new file mode 100644
index 0000000000..66221b888c
--- /dev/null
+++ b/epmet-commons/epmet-common-clienttoken/pom.xml
@@ -0,0 +1,125 @@
+
+
+
+ epmet-commons
+ com.epmet
+ 2.0.0
+
+ 4.0.0
+
+ epmet-common-clienttoken
+ jar
+
+ epmet-common-clienttoken
+ http://www.example.com
+ 客户端token
+
+
+
+ com.epmet
+ epmet-commons-tools
+ ${project.version}
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+ provided
+
+
+
+ org.springframework.boot
+ spring-boot-starter-aop
+ provided
+
+
+
+ org.springframework.boot
+ spring-boot-configuration-processor
+ true
+
+
+ com.vaadin.external.google
+ android-json
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-autoconfigure
+ compile
+
+
+
+ org.springframework.boot
+ spring-boot-autoconfigure-processor
+ compile
+ true
+
+
+
+ org.springframework.boot
+ spring-boot-starter-log4j2
+ provided
+
+
+
+ io.jsonwebtoken
+ jjwt
+ 0.7.0
+
+
+
+
+ ${project.artifactId}
+
+
+
+ maven-clean-plugin
+
+
+
+ maven-resources-plugin
+
+
+ maven-compiler-plugin
+
+ true
+ ${maven.compiler.source}
+ ${maven.compiler.target}
+ ${project.build.sourceEncoding}
+
+
+
+ maven-surefire-plugin
+
+
+ maven-war-plugin
+
+
+ maven-install-plugin
+
+
+ maven-deploy-plugin
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ 2.4
+
+
+
+ true
+
+
+
+
+
+
+ ${project.basedir}/src/main/java
+
+
diff --git a/epmet-commons/epmet-common-clienttoken/src/main/java/com/epmet/common/token/annotation/Login.java b/epmet-commons/epmet-common-clienttoken/src/main/java/com/epmet/common/token/annotation/Login.java
new file mode 100644
index 0000000000..e5a19a10c5
--- /dev/null
+++ b/epmet-commons/epmet-common-clienttoken/src/main/java/com/epmet/common/token/annotation/Login.java
@@ -0,0 +1,31 @@
+/**
+ * Copyright 2018 人人开源 http://www.renren.io
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.epmet.common.token.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * 登录效验
+ * @author chenshun
+ * @email sunlightcs@gmail.com
+ * @date 2017/9/23 14:30
+ */
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface Login {
+}
diff --git a/epmet-commons/epmet-common-clienttoken/src/main/java/com/epmet/common/token/annotation/LoginUser.java b/epmet-commons/epmet-common-clienttoken/src/main/java/com/epmet/common/token/annotation/LoginUser.java
new file mode 100644
index 0000000000..068ea84c2d
--- /dev/null
+++ b/epmet-commons/epmet-common-clienttoken/src/main/java/com/epmet/common/token/annotation/LoginUser.java
@@ -0,0 +1,35 @@
+/**
+ * Copyright 2018 人人开源 http://www.renren.io
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.epmet.common.token.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 登录用户信息
+ *
+ * @author chenshun
+ * @email sunlightcs@gmail.com
+ * @date 2017-03-23 20:39
+ */
+@Target(ElementType.PARAMETER)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface LoginUser {
+
+}
diff --git a/epmet-commons/epmet-common-clienttoken/src/main/java/com/epmet/common/token/annotation/NeedClientToken.java b/epmet-commons/epmet-common-clienttoken/src/main/java/com/epmet/common/token/annotation/NeedClientToken.java
new file mode 100644
index 0000000000..4c2cd0b553
--- /dev/null
+++ b/epmet-commons/epmet-common-clienttoken/src/main/java/com/epmet/common/token/annotation/NeedClientToken.java
@@ -0,0 +1,13 @@
+package com.epmet.common.token.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.CLASS)//生命注释保留时长,这里无需反射使用,使用CLASS级别
+@Target(ElementType.METHOD)//生命可以使用此注解的元素级别类型(如类、方法变量等)
+public @interface NeedClientToken {
+
+ boolean value() default true;
+}
diff --git a/epmet-commons/epmet-common-clienttoken/src/main/java/com/epmet/common/token/dto/DeptDataScopeDTO.java b/epmet-commons/epmet-common-clienttoken/src/main/java/com/epmet/common/token/dto/DeptDataScopeDTO.java
new file mode 100644
index 0000000000..423f31fb62
--- /dev/null
+++ b/epmet-commons/epmet-common-clienttoken/src/main/java/com/epmet/common/token/dto/DeptDataScopeDTO.java
@@ -0,0 +1,32 @@
+package com.epmet.common.token.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ *
+ * 用户所有角色权限信息
+ *
+ * @Author:liuchuang
+ * @Date:2019/11/19 23:48
+ */
+@Data
+public class DeptDataScopeDTO implements Serializable {
+ private static final long serialVersionUID = -6319876948812713836L;
+
+ /**
+ * 部门ID
+ */
+ private Long deptId;
+
+ /**
+ * 部门名称
+ */
+ private String deptName;
+
+ /**
+ * 部门类型
+ */
+ private String typeKey;
+}
diff --git a/epmet-commons/epmet-common-clienttoken/src/main/java/com/epmet/common/token/dto/TokenDto.java b/epmet-commons/epmet-common-clienttoken/src/main/java/com/epmet/common/token/dto/TokenDto.java
new file mode 100644
index 0000000000..b0989145e7
--- /dev/null
+++ b/epmet-commons/epmet-common-clienttoken/src/main/java/com/epmet/common/token/dto/TokenDto.java
@@ -0,0 +1,52 @@
+package com.elink.esua.epdc.common.token.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 用户token
+ *
+ * @author rongchao
+ * @Date 18-10-31
+ */
+@Data
+public class TokenDto implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 用户ID
+ */
+ private String userId;
+
+ /**
+ * 昵称
+ */
+ private String nickname;
+
+ /**
+ * 用户头像
+ */
+ private String faceImg;
+
+ /**
+ * 手机号
+ */
+ private String mobile;
+
+ /**
+ * 真实姓名
+ */
+ private String realName;
+
+ /**
+ * 网格ID
+ */
+ private Long gridId;
+
+ /**
+ * 党员标识 0:否、1:是
+ */
+ private String partyFlag;
+}
diff --git a/epmet-commons/epmet-common-clienttoken/src/main/java/com/epmet/common/token/dto/WorkUserAuthorizationDTO.java b/epmet-commons/epmet-common-clienttoken/src/main/java/com/epmet/common/token/dto/WorkUserAuthorizationDTO.java
new file mode 100644
index 0000000000..a3de3102ea
--- /dev/null
+++ b/epmet-commons/epmet-common-clienttoken/src/main/java/com/epmet/common/token/dto/WorkUserAuthorizationDTO.java
@@ -0,0 +1,48 @@
+package com.epmet.common.token.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ *
+ * 工作端用户授权信息
+ *
+ * @Author:liuchuang
+ * @Date:2019/11/19 20:17
+ */
+@Data
+public class WorkUserAuthorizationDTO implements Serializable {
+ private static final long serialVersionUID = -4230190448906007120L;
+
+ /**
+ * 令牌
+ */
+ private String token;
+
+ /**
+ * 过期时长,单位秒
+ */
+ private Integer expire;
+
+ /**
+ * 部门名称
+ */
+ private String deptName;
+
+ /**
+ * 用户标签key
+ */
+ private String userTagKey;
+
+ /**
+ * 注册状态 0-未注册,1-已注册
+ */
+ private String registerState;
+
+ /**
+ * 用户所有角色权限信息
+ */
+ private List deptDataScopeList;
+}
diff --git a/epmet-commons/epmet-common-clienttoken/src/main/java/com/epmet/common/token/dto/WorkUserLoginDTO.java b/epmet-commons/epmet-common-clienttoken/src/main/java/com/epmet/common/token/dto/WorkUserLoginDTO.java
new file mode 100644
index 0000000000..4f2e9a64c2
--- /dev/null
+++ b/epmet-commons/epmet-common-clienttoken/src/main/java/com/epmet/common/token/dto/WorkUserLoginDTO.java
@@ -0,0 +1,29 @@
+package com.epmet.common.token.dto;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import java.io.Serializable;
+
+/**
+ *
+ * 工作端用户登录信息
+ *
+ * @Author:liuchuang
+ * @Date:2019/11/19 20:19
+ */
+@Data
+public class WorkUserLoginDTO implements Serializable {
+ private static final long serialVersionUID = 1905641243346550379L;
+
+ @NotBlank(message="用户名不能为空")
+ private String username;
+
+ @NotBlank(message="密码不能为空")
+ private String password;
+
+ @NotBlank(message="微信code不能为空")
+ private String wxCode;
+
+ private String openId;
+}
diff --git a/epmet-commons/epmet-common-clienttoken/src/main/java/com/epmet/common/token/dto/WorkUserTokenFormDTO.java b/epmet-commons/epmet-common-clienttoken/src/main/java/com/epmet/common/token/dto/WorkUserTokenFormDTO.java
new file mode 100644
index 0000000000..7b303528c1
--- /dev/null
+++ b/epmet-commons/epmet-common-clienttoken/src/main/java/com/epmet/common/token/dto/WorkUserTokenFormDTO.java
@@ -0,0 +1,25 @@
+package com.epmet.common.token.dto;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+
+/**
+ *
+ * 工作端获取token Form DTO
+ *
+ * @Author:liuchuang
+ * @Date:2019/11/19 20:35
+ */
+@Data
+public class WorkUserTokenFormDTO implements Serializable {
+ private static final long serialVersionUID = -2239027109939769097L;
+
+ @NotNull(message = "用户ID不能为空")
+ private Long id;
+
+ @NotBlank(message = "用户名不能为空")
+ private String username;
+}
diff --git a/epmet-commons/epmet-common-clienttoken/src/main/java/com/epmet/common/token/enums/ErrorCode.java b/epmet-commons/epmet-common-clienttoken/src/main/java/com/epmet/common/token/enums/ErrorCode.java
new file mode 100644
index 0000000000..f312ed9b8c
--- /dev/null
+++ b/epmet-commons/epmet-common-clienttoken/src/main/java/com/epmet/common/token/enums/ErrorCode.java
@@ -0,0 +1,47 @@
+package com.epmet.common.token.enums;
+
+
+import com.epmet.common.token.error.IErrorCode;
+
+/**
+ * client token错误码
+ *
+ * @author rongchao
+ * @Date 18-11-24
+ */
+public enum ErrorCode implements IErrorCode {
+
+ SUCCESS(0, "请求成功"),
+
+ ERR10001(10001, "clientToken不合法或者已过期"),
+ ERR10002(10002, "无法获取当前用户的信息,无法生成clientToken。"),
+ ERR10003(10003, "clientToken生成失败,请重试。"),
+ ERR10004(10004, "返回的Object类型不是EsuaResponse,无法添加token!"),
+ ERR10005(10005, "clentToken不能为空"),
+
+ ERR500(500, "Internal Server Error"),
+ ERR501(501, "参数绑定异常"),
+
+ ERR(ErrorCode.COMMON_ERR_CODE, "其他异常");
+
+ private int code;
+
+ private String msg;
+
+ ErrorCode(final int code, final String msg) {
+ this.code = code;
+ this.msg = msg;
+ }
+
+ public static final int COMMON_ERR_CODE = -1;
+
+ @Override
+ public int getCode() {
+ return code;
+ }
+
+ @Override
+ public String getMsg() {
+ return msg;
+ }
+}
diff --git a/epmet-commons/epmet-common-clienttoken/src/main/java/com/epmet/common/token/error/IErrorCode.java b/epmet-commons/epmet-common-clienttoken/src/main/java/com/epmet/common/token/error/IErrorCode.java
new file mode 100644
index 0000000000..9b58ccc96e
--- /dev/null
+++ b/epmet-commons/epmet-common-clienttoken/src/main/java/com/epmet/common/token/error/IErrorCode.java
@@ -0,0 +1,11 @@
+package com.epmet.common.token.error;
+
+/**
+ * @author rongchao
+ * @Date 18-11-20
+ */
+public interface IErrorCode {
+ int getCode();
+
+ String getMsg();
+}
diff --git a/epmet-commons/epmet-common-clienttoken/src/main/java/com/epmet/common/token/property/TokenPropertise.java b/epmet-commons/epmet-common-clienttoken/src/main/java/com/epmet/common/token/property/TokenPropertise.java
new file mode 100644
index 0000000000..1552871f39
--- /dev/null
+++ b/epmet-commons/epmet-common-clienttoken/src/main/java/com/epmet/common/token/property/TokenPropertise.java
@@ -0,0 +1,23 @@
+package com.epmet.common.token.property;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author rongchao
+ * @Date 18-12-3
+ */
+@Component
+@ConfigurationProperties(prefix = "token")
+public class TokenPropertise {
+
+ private long expire = 7200L;
+
+ public long getExpire() {
+ return expire;
+ }
+
+ public void setExpire(long expire) {
+ this.expire = expire;
+ }
+}
diff --git a/epmet-commons/epmet-common-clienttoken/src/main/java/com/epmet/common/token/util/CpUserDetailRedis.java b/epmet-commons/epmet-common-clienttoken/src/main/java/com/epmet/common/token/util/CpUserDetailRedis.java
new file mode 100644
index 0000000000..d036773660
--- /dev/null
+++ b/epmet-commons/epmet-common-clienttoken/src/main/java/com/epmet/common/token/util/CpUserDetailRedis.java
@@ -0,0 +1,94 @@
+/**
+ * Copyright (c) 2018 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package com.epmet.common.token.util;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.map.MapUtil;
+import com.elink.esua.epdc.common.token.dto.TokenDto;
+import com.epmet.commons.tools.redis.RedisKeys;
+import com.epmet.commons.tools.redis.RedisUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.Map;
+
+/**
+ * CP用户Redis
+ *
+ * @author rongchao
+ * @since 1.0.0
+ */
+@Component
+public class CpUserDetailRedis {
+
+ @Autowired
+ private RedisUtils redisUtils;
+
+ public void set(TokenDto user, long expire) {
+ if (user == null) {
+ return;
+ }
+ String key = RedisKeys.getCpUserKey(user.getUserId());
+ //bean to map
+ Map map = BeanUtil.beanToMap(user, false, true);
+ redisUtils.hMSet(key, map, expire);
+ }
+
+ /**
+ * 获取token信息
+ *
+ * @param userId
+ * @return
+ */
+ public TokenDto get(String userId) {
+ String key = RedisKeys.getCpUserKey(userId);
+
+ Map map = redisUtils.hGetAll(key);
+ if (MapUtil.isEmpty(map)) {
+ return null;
+ }
+
+ //map to bean
+ TokenDto user = BeanUtil.mapToBean(map, TokenDto.class, true);
+
+ return user;
+ }
+
+ /**
+ * 删除用户信息
+ *
+ * @param userId
+ */
+ public void logout(String userId) {
+ redisUtils.delete(RedisKeys.getCpUserKey(userId));
+ }
+
+ /**
+ * 设置redis时间
+ *
+ * @param userId
+ * @param expire
+ * @author rongchao
+ */
+ public boolean expire(String userId, long expire) {
+ return redisUtils.expire(RedisKeys.getCpUserKey(userId), expire);
+ }
+
+ /**
+ * 查询token剩余时间
+ *
+ * @param userId
+ * @return long
+ * @author yujintao
+ * @date 2019/9/9 14:18
+ */
+ public long getExpire(String userId) {
+ return redisUtils.getExpire(RedisKeys.getCpUserKey(userId));
+ }
+}
diff --git a/epmet-commons/epmet-common-clienttoken/src/main/java/com/epmet/common/token/util/TokenUtil.java b/epmet-commons/epmet-common-clienttoken/src/main/java/com/epmet/common/token/util/TokenUtil.java
new file mode 100644
index 0000000000..d11af40dd6
--- /dev/null
+++ b/epmet-commons/epmet-common-clienttoken/src/main/java/com/epmet/common/token/util/TokenUtil.java
@@ -0,0 +1,51 @@
+package com.epmet.common.token.util;
+
+import com.elink.esua.epdc.common.token.dto.TokenDto;
+import com.epmet.common.token.property.TokenPropertise;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+/**
+ * token服务类
+ *
+ * @author rongchao
+ * @Date 18-10-31
+ */
+@Component
+public class TokenUtil {
+
+ private Logger logger = LoggerFactory.getLogger(getClass());
+
+ @Autowired
+ private TokenPropertise tokenPropertise;
+
+ @Autowired
+ private CpUserDetailRedis redisUtils;
+
+ public TokenDto getTokenInfo(String userId) {
+ TokenDto tokenDto = redisUtils.get(userId);
+ return tokenDto;
+ }
+
+ public void expireToken(String userId) {
+ redisUtils.logout(userId);
+ }
+
+ public boolean delayToken(String userId) {
+ return redisUtils.expire(userId, tokenPropertise.getExpire());
+ }
+
+ /**
+ * 获取token过期时间
+ *
+ * @param userId
+ * @return long
+ * @author yujintao
+ * @date 2019/9/9 14:19
+ */
+ public long getExpire(String userId) {
+ return redisUtils.getExpire(userId);
+ }
+}
diff --git a/epmet-commons/epmet-common-clienttoken/src/main/java/com/epmet/common/token/util/UserUtil.java b/epmet-commons/epmet-common-clienttoken/src/main/java/com/epmet/common/token/util/UserUtil.java
new file mode 100644
index 0000000000..68965da7b6
--- /dev/null
+++ b/epmet-commons/epmet-common-clienttoken/src/main/java/com/epmet/common/token/util/UserUtil.java
@@ -0,0 +1,55 @@
+package com.epmet.common.token.util;
+
+import com.elink.esua.epdc.common.token.dto.TokenDto;
+import com.epmet.commons.tools.constant.Constant;
+import com.epmet.commons.tools.utils.WebUtil;
+
+/**
+ * 用户工具类
+ *
+ * @author rongchao
+ * @Date 18-11-20
+ */
+public class UserUtil {
+
+ /**
+ * 获取当前用户信息
+ *
+ * @return
+ */
+ public static TokenDto getCurrentUser() {
+ return (TokenDto) WebUtil.getAttributesFromRequest(Constant.APP_USER_KEY);
+ }
+
+ /**
+ * 获取当前用户信息
+ *
+ * @return com.elink.esua.common.token.dto.UserTokenDto
+ * @author yujintao
+ * @date 2018/12/5 9:24
+ */
+ public static TokenDto getCurrentUserInfo() {
+ TokenDto tokenDto = getCurrentUser();
+ if (tokenDto == null) {
+ return null;
+ }
+ return tokenDto;
+ }
+
+ /**
+ * 获取当前用户ID
+ *
+ * @return
+ */
+ public static String getCurrentUserId() {
+ TokenDto tokenDto = getCurrentUser();
+ if (tokenDto == null) {
+ return null;
+ }
+ return tokenDto.getUserId();
+ }
+
+ public static void setCurrentUser(TokenDto user) {
+ WebUtil.setAttributesFromRequest(Constant.APP_USER_KEY, user);
+ }
+}
diff --git a/epmet-commons/epmet-commons-tools-phone/pom.xml b/epmet-commons/epmet-commons-tools-phone/pom.xml
new file mode 100644
index 0000000000..7e8d052ee8
--- /dev/null
+++ b/epmet-commons/epmet-commons-tools-phone/pom.xml
@@ -0,0 +1,41 @@
+
+
+
+ epmet-commons
+ com.epmet
+ 2.0.0
+
+ 4.0.0
+
+ epmet-commons-tools-phone
+ jar
+
+
+
+ com.googlecode.libphonenumber
+ libphonenumber
+ 8.8.8
+
+
+ com.googlecode.libphonenumber
+ carrier
+ 1.75
+
+
+ com.googlecode.libphonenumber
+ geocoder
+ 2.85
+
+
+ com.googlecode.libphonenumber
+ prefixmapper
+ 2.85
+
+
+
+
+ ${project.artifactId}
+
+
diff --git a/epmet-commons/epmet-commons-tools-phone/src/main/java/com/epmet/commons/tools/utils/PhoneDto.java b/epmet-commons/epmet-commons-tools-phone/src/main/java/com/epmet/commons/tools/utils/PhoneDto.java
new file mode 100644
index 0000000000..8bc240a16e
--- /dev/null
+++ b/epmet-commons/epmet-commons-tools-phone/src/main/java/com/epmet/commons/tools/utils/PhoneDto.java
@@ -0,0 +1,79 @@
+package com.epmet.commons.tools.utils;
+
+/**
+ * 电话DTO
+ *
+ * @author rongchao
+ * @Date 18-12-11
+ */
+public class PhoneDto {
+
+ /**
+ * 省份名称
+ */
+ private String provinceName;
+
+ /**
+ * 城市名称
+ */
+ private String cityName;
+
+ /**
+ * 运营商:移动/电信/联通
+ */
+ private String carrier;
+
+ /**
+ * 省份名称
+ *
+ * @return 获取provinceName属性值
+ */
+ public String getProvinceName() {
+ return provinceName;
+ }
+
+ /**
+ * 省份名称
+ *
+ * @param provinceName 设置 provinceName 属性值为参数值 provinceName
+ */
+ public void setProvinceName(String provinceName) {
+ this.provinceName = provinceName;
+ }
+
+ /**
+ * 城市名称
+ *
+ * @return 获取cityName属性值
+ */
+ public String getCityName() {
+ return cityName;
+ }
+
+ /**
+ * 城市名称
+ *
+ * @param cityName 设置 cityName 属性值为参数值 cityName
+ */
+ public void setCityName(String cityName) {
+ this.cityName = cityName;
+ }
+
+ /**
+ * 运营商:移动/电信/联通
+ *
+ * @return 获取carrier属性值
+ */
+ public String getCarrier() {
+ return carrier;
+ }
+
+ /**
+ * 运营商:移动/电信/联通
+ *
+ * @param carrier 设置 carrier 属性值为参数值 carrier
+ */
+ public void setCarrier(String carrier) {
+ this.carrier = carrier;
+ }
+}
diff --git a/epmet-commons/epmet-commons-tools-phone/src/main/java/com/epmet/commons/tools/utils/PhoneUtil.java b/epmet-commons/epmet-commons-tools-phone/src/main/java/com/epmet/commons/tools/utils/PhoneUtil.java
new file mode 100644
index 0000000000..022525592c
--- /dev/null
+++ b/epmet-commons/epmet-commons-tools-phone/src/main/java/com/epmet/commons/tools/utils/PhoneUtil.java
@@ -0,0 +1,178 @@
+package com.epmet.commons.tools.utils;
+
+/**
+ * @author rongchao
+ * @Date 18-12-11
+ */
+
+
+
+import com.google.i18n.phonenumbers.PhoneNumberToCarrierMapper;
+import com.google.i18n.phonenumbers.PhoneNumberUtil;
+import com.google.i18n.phonenumbers.Phonenumber;
+import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber;
+import com.google.i18n.phonenumbers.geocoding.PhoneNumberOfflineGeocoder;
+
+import java.util.Locale;
+
+/**
+ * 手机号归属地查询
+ * jar依赖:com.googlecode.libphonenumber(Libphonenumber、Geocoder、Prefixmapper
+ * 、Carrier) pom依赖:http://mvnrepository.com/search?q=libphonenumber
+ * 项目地址:https://github.com/googlei18n/libphonenumber
+ *
+ * @author rongchao
+ * @Date 18-12-11
+ */
+public class PhoneUtil {
+
+ /**
+ * 直辖市
+ */
+ private final static String[] MUNICIPALITY = {"北京市", "天津市", "上海市", "重庆市"};
+
+ /**
+ * 自治区
+ */
+ private final static String[] AUTONOMOUS_REGION = {"新疆", "内蒙古", "西藏", "宁夏", "广西"};
+
+ private static PhoneNumberUtil phoneNumberUtil = PhoneNumberUtil
+ .getInstance();
+
+ /**
+ * 提供与电话号码相关的运营商信息
+ */
+ private static PhoneNumberToCarrierMapper carrierMapper = PhoneNumberToCarrierMapper
+ .getInstance();
+
+ /**
+ * 提供与电话号码有关的地理信息
+ */
+ private static PhoneNumberOfflineGeocoder geocoder = PhoneNumberOfflineGeocoder
+ .getInstance();
+
+ /**
+ * 中国大陆区区号
+ */
+ private final static int COUNTRY_CODE = 86;
+
+ /**
+ * 根据手机号 判断手机号是否有效
+ *
+ * @param phoneNumber 手机号码
+ * @return true-有效 false-无效
+ */
+ public static boolean checkPhoneNumber(String phoneNumber) {
+ long phone = Long.parseLong(phoneNumber);
+
+ PhoneNumber pn = new PhoneNumber();
+ pn.setCountryCode(COUNTRY_CODE);
+ pn.setNationalNumber(phone);
+
+ return phoneNumberUtil.isValidNumber(pn);
+
+ }
+
+ /**
+ * 根据手机号 判断手机运营商
+ *
+ * @param phoneNumber 手机号码
+ * @return 如:广东省广州市移动
+ */
+ public static String getCarrier(String phoneNumber) {
+
+ long phone = Long.parseLong(phoneNumber);
+
+ PhoneNumber pn = new PhoneNumber();
+ pn.setCountryCode(COUNTRY_CODE);
+ pn.setNationalNumber(phone);
+ // 返回结果只有英文,自己转成成中文
+ String carrierEn = carrierMapper.getNameForNumber(pn, Locale.ENGLISH);
+ String carrierZh = "";
+ switch (carrierEn) {
+ case "China Mobile":
+ carrierZh += "移动";
+ break;
+ case "China Unicom":
+ carrierZh += "联通";
+ break;
+ case "China Telecom":
+ carrierZh += "电信";
+ break;
+ default:
+ break;
+ }
+ return carrierZh;
+ }
+
+ /**
+ * 根据手机号 获取手机归属地
+ *
+ * @param phoneNumber 手机号码
+ * @return 如:广东省广州市
+ */
+ public static String getGeo(String phoneNumber) {
+ long phone = Long.parseLong(phoneNumber);
+
+ Phonenumber.PhoneNumber pn = new Phonenumber.PhoneNumber();
+ pn.setCountryCode(COUNTRY_CODE);
+ pn.setNationalNumber(phone);
+ return geocoder.getDescriptionForNumber(pn, Locale.CHINESE);
+ }
+
+ /**
+ * 根据手机号 获取手机信息模型
+ *
+ *
+ * 若返回值为null,则说明该号码无效
+ *
+ *
+ * @param phoneNumber 手机号码
+ * @return 手机信息模型PhoneModel
+ */
+ public static PhoneDto getPhoneDto(String phoneNumber) {
+ if (checkPhoneNumber(phoneNumber)) {
+ String geo = getGeo(phoneNumber);
+ PhoneDto phoneDto = new PhoneDto();
+ String carrier = getCarrier(phoneNumber);
+ phoneDto.setCarrier(carrier);
+ // 直辖市
+ for (String val : MUNICIPALITY) {
+ if (geo.equals(val)) {
+ phoneDto.setProvinceName(val.replace("市", ""));
+ phoneDto.setCityName(val);
+ return phoneDto;
+ }
+ }
+ // 自治区
+ for (String val : AUTONOMOUS_REGION) {
+ if (geo.startsWith(val)) {
+ phoneDto.setProvinceName(val);
+ phoneDto.setCityName(geo.replace(val, ""));
+ return phoneDto;
+ }
+ }
+
+ // 其它
+ String[] splitArr = geo.split("省");
+ if (splitArr != null && splitArr.length == 2) {
+ phoneDto.setProvinceName(splitArr[0]);
+ phoneDto.setCityName(splitArr[1]);
+ return phoneDto;
+ }
+ }
+ return null;
+ }
+
+ public static void main(String[] args) {
+ PhoneDto phoneDto = PhoneUtil.getPhoneDto("13701001254");
+ if (phoneDto != null) {
+ System.out.println(phoneDto.getProvinceName());
+ System.out.println(phoneDto.getCityName());
+ System.out.println(phoneDto.getCarrier());
+ } else {
+ System.err.println("该号码无效");
+ }
+ }
+
+}
diff --git a/epmet-commons/epmet-commons-tools-wx-ma/pom.xml b/epmet-commons/epmet-commons-tools-wx-ma/pom.xml
new file mode 100644
index 0000000000..7380ada9e3
--- /dev/null
+++ b/epmet-commons/epmet-commons-tools-wx-ma/pom.xml
@@ -0,0 +1,34 @@
+
+
+
+ epmet-commons
+ com.epmet
+ 2.0.0
+
+ 4.0.0
+
+ 1.0.0
+ epmet-commons-tools-wx-ma
+ jar
+
+
+
+ org.projectlombok
+ lombok
+ provided
+
+
+ org.springframework.boot
+ spring-boot-autoconfigure
+ compile
+
+
+ com.github.binarywang
+ weixin-java-miniapp
+ 3.6.0
+
+
+
+
diff --git a/epmet-commons/epmet-commons-tools-wx-ma/src/main/java/com/epmet/utils/WxMaServiceUtils.java b/epmet-commons/epmet-commons-tools-wx-ma/src/main/java/com/epmet/utils/WxMaServiceUtils.java
new file mode 100644
index 0000000000..05c8f51bcf
--- /dev/null
+++ b/epmet-commons/epmet-commons-tools-wx-ma/src/main/java/com/epmet/utils/WxMaServiceUtils.java
@@ -0,0 +1,63 @@
+package com.epmet.utils;
+
+import cn.binarywang.wx.miniapp.api.WxMaService;
+import com.epmet.wx.ma.WxMaConfig;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+/**
+ * 获取小程序业务工具
+ *
+ * @author work@yujt.net.cn
+ * @date 2019/11/25 13:29
+ */
+@Component
+public class WxMaServiceUtils {
+
+ @Value("${wx.ma.appId.resi}")
+ private String APPID_RESI;
+
+ @Value("${wx.ma.appId.gov}")
+ private String APPID_GOV;
+
+ @Value("${wx.ma.appId.oper}")
+ private String APPID_OPER;
+
+ /**
+ * 获取党群e事通-居民端小程序配置
+ *
+ * @return cn.binarywang.wx.miniapp.api.WxMaService
+ * @author yinzuomei
+ * @date 2020/03/13 10:44
+ */
+ public final WxMaService resiWxMaService() {
+ final WxMaService wxMaService = WxMaConfig.getMaService(APPID_RESI);
+ return wxMaService;
+ }
+
+ /**
+ * 获取党群e事通-政府端小程序配置
+ *
+ * @return cn.binarywang.wx.miniapp.api.WxMaService
+ * @author yinzuomei
+ * @date 2020/03/13 10:44
+ */
+ public final WxMaService govWxMaService() {
+ final WxMaService wxMaService = WxMaConfig.getMaService(APPID_GOV);
+ return wxMaService;
+ }
+
+ /**
+ *
+ * 获取党群e事通-运营端小程序配置
+ *
+ * @params []
+ * @return cn.binarywang.wx.miniapp.api.WxMaService
+ * @author yinzuomei
+ * @since 2020/03/13 10:44
+ */
+ public final WxMaService operWxMaService() {
+ final WxMaService wxMaService = WxMaConfig.getMaService(APPID_OPER);
+ return wxMaService;
+ }
+}
diff --git a/epmet-commons/epmet-commons-tools-wx-ma/src/main/java/com/epmet/wx/ma/WxMaConfig.java b/epmet-commons/epmet-commons-tools-wx-ma/src/main/java/com/epmet/wx/ma/WxMaConfig.java
new file mode 100644
index 0000000000..073b701bd2
--- /dev/null
+++ b/epmet-commons/epmet-commons-tools-wx-ma/src/main/java/com/epmet/wx/ma/WxMaConfig.java
@@ -0,0 +1,148 @@
+package com.epmet.wx.ma;
+
+import cn.binarywang.wx.miniapp.api.WxMaService;
+import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
+import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage;
+import cn.binarywang.wx.miniapp.bean.WxMaTemplateData;
+import cn.binarywang.wx.miniapp.bean.WxMaTemplateMessage;
+import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl;
+import cn.binarywang.wx.miniapp.message.WxMaMessageHandler;
+import cn.binarywang.wx.miniapp.message.WxMaMessageRouter;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
+import me.chanjar.weixin.common.error.WxErrorException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+import javax.annotation.PostConstruct;
+import java.io.File;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * @author Binary Wang
+ */
+@Configuration
+@EnableConfigurationProperties(WxMaProperties.class)
+public class WxMaConfig {
+
+ private WxMaProperties properties;
+
+ private static Map routers = Maps.newHashMap();
+ private static Map maServices = Maps.newHashMap();
+
+ @Autowired
+ public WxMaConfig(WxMaProperties properties) {
+ this.properties = properties;
+ }
+
+ public static WxMaService getMaService(String appid) {
+ WxMaService wxService = maServices.get(appid);
+ if (wxService == null) {
+ throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置,请核实!", appid));
+ }
+
+ return wxService;
+ }
+
+ public static WxMaMessageRouter getRouter(String appid) {
+ return routers.get(appid);
+ }
+
+ @PostConstruct
+ public void init() {
+ List configs = this.properties.getConfigs();
+ if (configs == null) {
+ throw new RuntimeException("大哥,拜托先看下项目首页的说明(readme文件),添加下相关配置,注意别配错了!");
+ }
+
+ maServices = configs.stream()
+ .map(a -> {
+ WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl();
+ config.setAppid(a.getAppid());
+ config.setSecret(a.getSecret());
+ config.setToken(a.getToken());
+ config.setAesKey(a.getAesKey());
+ config.setMsgDataFormat(a.getMsgDataFormat());
+
+ WxMaService service = new WxMaServiceImpl();
+ service.setWxMaConfig(config);
+ routers.put(a.getAppid(), this.newRouter(service));
+ return service;
+ }).collect(Collectors.toMap(s -> s.getWxMaConfig().getAppid(), a -> a));
+ }
+
+ private WxMaMessageRouter newRouter(WxMaService service) {
+ final WxMaMessageRouter router = new WxMaMessageRouter(service);
+ router
+ .rule().handler(logHandler).next()
+ .rule().async(false).content("模板").handler(templateMsgHandler).end()
+ .rule().async(false).content("文本").handler(textHandler).end()
+ .rule().async(false).content("图片").handler(picHandler).end()
+ .rule().async(false).content("二维码").handler(qrcodeHandler).end();
+ return router;
+ }
+
+ private final WxMaMessageHandler templateMsgHandler = (wxMessage, context, service, sessionManager) -> {
+ service.getMsgService().sendTemplateMsg(WxMaTemplateMessage.builder()
+ .templateId("此处更换为自己的模板id")
+ .formId("自己替换可用的formid")
+ .data(Lists.newArrayList(
+ new WxMaTemplateData("keyword1", "339208499", "#173177")))
+ .toUser(wxMessage.getFromUser())
+ .build());
+ return null;
+ };
+
+ private final WxMaMessageHandler logHandler = (wxMessage, context, service, sessionManager) -> {
+ System.out.println("收到消息:" + wxMessage.toString());
+ service.getMsgService().sendKefuMsg(WxMaKefuMessage.newTextBuilder().content("收到信息为:" + wxMessage.toJson())
+ .toUser(wxMessage.getFromUser()).build());
+ return null;
+ };
+
+ private final WxMaMessageHandler textHandler = (wxMessage, context, service, sessionManager) -> {
+ service.getMsgService().sendKefuMsg(WxMaKefuMessage.newTextBuilder().content("回复文本消息")
+ .toUser(wxMessage.getFromUser()).build());
+ return null;
+ };
+
+ private final WxMaMessageHandler picHandler = (wxMessage, context, service, sessionManager) -> {
+ try {
+ WxMediaUploadResult uploadResult = service.getMediaService()
+ .uploadMedia("image", "png",
+ ClassLoader.getSystemResourceAsStream("tmp.png"));
+ service.getMsgService().sendKefuMsg(
+ WxMaKefuMessage
+ .newImageBuilder()
+ .mediaId(uploadResult.getMediaId())
+ .toUser(wxMessage.getFromUser())
+ .build());
+ } catch (WxErrorException e) {
+ e.printStackTrace();
+ }
+
+ return null;
+ };
+
+ private final WxMaMessageHandler qrcodeHandler = (wxMessage, context, service, sessionManager) -> {
+ try {
+ final File file = service.getQrcodeService().createQrcode("123", 430);
+ WxMediaUploadResult uploadResult = service.getMediaService().uploadMedia("image", file);
+ service.getMsgService().sendKefuMsg(
+ WxMaKefuMessage
+ .newImageBuilder()
+ .mediaId(uploadResult.getMediaId())
+ .toUser(wxMessage.getFromUser())
+ .build());
+ } catch (WxErrorException e) {
+ e.printStackTrace();
+ }
+
+ return null;
+ };
+
+}
diff --git a/epmet-commons/epmet-commons-tools-wx-ma/src/main/java/com/epmet/wx/ma/WxMaProperties.java b/epmet-commons/epmet-commons-tools-wx-ma/src/main/java/com/epmet/wx/ma/WxMaProperties.java
new file mode 100644
index 0000000000..3d5dc33b4c
--- /dev/null
+++ b/epmet-commons/epmet-commons-tools-wx-ma/src/main/java/com/epmet/wx/ma/WxMaProperties.java
@@ -0,0 +1,48 @@
+package com.epmet.wx.ma;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+import java.util.List;
+
+/**
+ * 微信小程序框架配置类
+ *
+ * @author rongchao
+ * @Date 19-5-13
+ */
+@Data
+@ConfigurationProperties(prefix = "wx.ma")
+public class WxMaProperties {
+
+ private List configs;
+
+ @Data
+ public static class Config {
+ /**
+ * 设置微信小程序的appid
+ */
+ private String appid;
+
+ /**
+ * 设置微信小程序的Secret
+ */
+ private String secret;
+
+ /**
+ * 设置微信小程序消息服务器配置的token
+ */
+ private String token;
+
+ /**
+ * 设置微信小程序消息服务器配置的EncodingAESKey
+ */
+ private String aesKey;
+
+ /**
+ * 消息格式,XML或者JSON
+ */
+ private String msgDataFormat;
+ }
+
+}
diff --git a/epmet-commons/epmet-commons-tools-wx-mp/.editorconfig b/epmet-commons/epmet-commons-tools-wx-mp/.editorconfig
new file mode 100644
index 0000000000..775be5ba05
--- /dev/null
+++ b/epmet-commons/epmet-commons-tools-wx-mp/.editorconfig
@@ -0,0 +1,14 @@
+# EditorConfig: http://editorconfig.org/
+
+root = true
+
+[*]
+indent_style = space
+indent_size = 4
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+[*.md]
+trim_trailing_whitespace = false
diff --git a/epmet-commons/epmet-commons-tools-wx-mp/.travis.yml b/epmet-commons/epmet-commons-tools-wx-mp/.travis.yml
new file mode 100644
index 0000000000..5d2a7698b9
--- /dev/null
+++ b/epmet-commons/epmet-commons-tools-wx-mp/.travis.yml
@@ -0,0 +1,13 @@
+language: java
+jdk:
+ - openjdk8
+
+script: "mvn clean package -Dmaven.test.skip=true"
+
+branches:
+ only:
+ - master
+
+notifications:
+ email:
+ - binarywang@vip.qq.com
diff --git a/epmet-commons/epmet-commons-tools-wx-mp/README.md b/epmet-commons/epmet-commons-tools-wx-mp/README.md
new file mode 100644
index 0000000000..790d56ba1b
--- /dev/null
+++ b/epmet-commons/epmet-commons-tools-wx-mp/README.md
@@ -0,0 +1,58 @@
+[](https://gitee.com/binary/weixin-java-mp-demo-springboot)
+[](https://github.com/binarywang/weixin-java-mp-demo-springboot)
+[](https://travis-ci.org/binarywang/weixin-java-mp-demo-springboot)
+-----------------------
+
+### 本Demo基于Spring Boot构建,实现微信公众号后端开发功能。
+### 本项目为WxJava的Demo演示程序,更多Demo请[查阅此处](https://github.com/Wechat-Group/WxJava/blob/master/demo.md)。
+#### 如有问题请[【在此提问】](https://github.com/binarywang/weixin-java-mp-demo-springboot/issues),谢谢配合。
+
+
+
+## 使用步骤:
+1. 请注意,本demo为简化代码编译时加入了lombok支持,如果不了解lombok的话,请先学习下相关知识,比如可以阅读[此文章](https://mp.weixin.qq.com/s/cUc-bUcprycADfNepnSwZQ);
+1. 另外,新手遇到问题,请务必先阅读[【开发文档首页】](https://github.com/Wechat-Group/WxJava/wiki)的常见问题部分,可以少走很多弯路,节省不少时间。
+1. 配置:复制 `/src/main/resources/application.yml.template` 或修改其扩展名生成 `application.yml` 文件,根据自己需要填写相关配置(需要注意的是:yml文件内的属性冒号后面的文字之前需要加空格,可参考已有配置,否则属性会设置不成功);
+2. 主要配置说明如下:
+```
+wx:
+ mp:
+ configs:
+ - appId: 1111 (一个公众号的appid)
+ secret: 1111(公众号的appsecret)
+ token: 111 (接口配置里的Token值)
+ aesKey: 111 (接口配置里的EncodingAESKey值)
+ - appId: 2222 (另一个公众号的appid,以下同上)
+ secret: 1111
+ token: 111
+ aesKey: 111
+```
+3. 运行Java程序:`WxMpDemoApplication`;
+4. 配置微信公众号中的接口地址:http://公网可访问域名/wx/portal/xxxxx (注意,xxxxx为对应公众号的appid值);
+5. 根据自己需要修改各个handler的实现,加入自己的业务逻辑。
+
diff --git a/epmet-commons/epmet-commons-tools-wx-mp/pom.xml b/epmet-commons/epmet-commons-tools-wx-mp/pom.xml
new file mode 100644
index 0000000000..5f69e61f1e
--- /dev/null
+++ b/epmet-commons/epmet-commons-tools-wx-mp/pom.xml
@@ -0,0 +1,60 @@
+
+
+ 4.0.0
+
+
+ com.epmet
+ epmet-commons
+ 2.0.0
+
+
+ 1.0.0
+ epmet-commons-tools-wx-mp
+ jar
+
+
+
+
+
+ 3.6.0
+ 1.8
+ 1.8
+ UTF-8
+ UTF-8
+ zh_CN
+ wechat-mp-demo
+
+
+
+
+ com.github.binarywang
+ weixin-java-mp
+ ${weixin-java-mp.version}
+
+
+
+ org.projectlombok
+ lombok
+ provided
+
+
+
+ org.springframework.boot
+ spring-boot-autoconfigure
+ compile
+
+
+ org.springframework.boot
+ spring-boot-configuration-processor
+ compile
+ true
+
+
+ org.springframework.boot
+ spring-boot-autoconfigure-processor
+ compile
+ true
+
+
+
diff --git a/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/builder/AbstractBuilder.java b/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/builder/AbstractBuilder.java
new file mode 100644
index 0000000000..8dad467ffd
--- /dev/null
+++ b/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/builder/AbstractBuilder.java
@@ -0,0 +1,17 @@
+package com.epmet.wx.mp.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);
+}
diff --git a/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/builder/ImageBuilder.java b/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/builder/ImageBuilder.java
new file mode 100644
index 0000000000..8afe9679d9
--- /dev/null
+++ b/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/builder/ImageBuilder.java
@@ -0,0 +1,24 @@
+package com.epmet.wx.mp.builder;
+
+import me.chanjar.weixin.mp.api.WxMpService;
+import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
+import me.chanjar.weixin.mp.bean.message.WxMpXmlOutImageMessage;
+import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
+
+/**
+ * @author Binary Wang(https://github.com/binarywang)
+ */
+public class ImageBuilder extends AbstractBuilder {
+
+ @Override
+ public WxMpXmlOutMessage build(String content, WxMpXmlMessage wxMessage,
+ WxMpService service) {
+
+ WxMpXmlOutImageMessage m = WxMpXmlOutMessage.IMAGE().mediaId(content)
+ .fromUser(wxMessage.getToUser()).toUser(wxMessage.getFromUser())
+ .build();
+
+ return m;
+ }
+
+}
diff --git a/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/builder/TextBuilder.java b/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/builder/TextBuilder.java
new file mode 100644
index 0000000000..9486aef270
--- /dev/null
+++ b/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/builder/TextBuilder.java
@@ -0,0 +1,22 @@
+package com.epmet.wx.mp.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;
+ }
+
+}
diff --git a/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/config/WxMpConfiguration.java b/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/config/WxMpConfiguration.java
new file mode 100644
index 0000000000..f2df571c42
--- /dev/null
+++ b/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/config/WxMpConfiguration.java
@@ -0,0 +1,113 @@
+package com.epmet.wx.mp.config;
+
+import com.epmet.wx.mp.handler.*;
+import lombok.AllArgsConstructor;
+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 org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+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.MenuButtonType.CLICK;
+import static me.chanjar.weixin.common.api.WxConsts.MenuButtonType.VIEW;
+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 configs = this.properties.getConfigs();
+ if (configs == null) {
+ throw new RuntimeException("大哥,拜托先看下项目首页的说明(readme文件),添加下相关配置,注意别配错了!");
+ }
+
+ WxMpService service = new WxMpServiceImpl();
+ service.setMultiConfigStorages(configs
+ .stream().map(a -> {
+ WxMpDefaultConfigImpl 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(CLICK).handler(this.menuHandler).end();
+
+ // 点击菜单连接事件
+ newRouter.rule().async(false).msgType(EVENT).event(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;
+ }
+
+}
diff --git a/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/config/WxMpProperties.java b/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/config/WxMpProperties.java
new file mode 100644
index 0000000000..3e5c181948
--- /dev/null
+++ b/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/config/WxMpProperties.java
@@ -0,0 +1,46 @@
+package com.epmet.wx.mp.config;
+
+import com.epmet.wx.mp.utils.JsonUtils;
+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")
+public class WxMpProperties {
+ private List configs;
+
+ @Data
+ public static class MpConfig {
+ /**
+ * 设置微信公众号的appid
+ */
+ private String appId;
+
+ /**
+ * 设置微信公众号的app secret
+ */
+ private String secret;
+
+ /**
+ * 设置微信公众号的token
+ */
+ private String token;
+
+ /**
+ * 设置微信公众号的EncodingAESKey
+ */
+ private String aesKey;
+ }
+
+ @Override
+ public String toString() {
+ return JsonUtils.toJson(this);
+ }
+}
diff --git a/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/handler/AbstractHandler.java b/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/handler/AbstractHandler.java
new file mode 100644
index 0000000000..3831d6427a
--- /dev/null
+++ b/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/handler/AbstractHandler.java
@@ -0,0 +1,12 @@
+package com.epmet.wx.mp.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());
+}
diff --git a/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/handler/KfSessionHandler.java b/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/handler/KfSessionHandler.java
new file mode 100644
index 0000000000..cfdcb95eec
--- /dev/null
+++ b/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/handler/KfSessionHandler.java
@@ -0,0 +1,25 @@
+package com.epmet.wx.mp.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 context, WxMpService wxMpService,
+ WxSessionManager sessionManager) {
+ //TODO 对会话做处理
+ return null;
+ }
+
+}
diff --git a/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/handler/LocationHandler.java b/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/handler/LocationHandler.java
new file mode 100644
index 0000000000..78f8296350
--- /dev/null
+++ b/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/handler/LocationHandler.java
@@ -0,0 +1,44 @@
+package com.epmet.wx.mp.handler;
+
+import com.epmet.wx.mp.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 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;
+ }
+
+}
diff --git a/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/handler/LogHandler.java b/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/handler/LogHandler.java
new file mode 100644
index 0000000000..7efe62c03e
--- /dev/null
+++ b/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/handler/LogHandler.java
@@ -0,0 +1,25 @@
+package com.epmet.wx.mp.handler;
+
+import com.epmet.wx.mp.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 context, WxMpService wxMpService,
+ WxSessionManager sessionManager) {
+ this.logger.info("\n接收到请求消息,内容:{}", JsonUtils.toJson(wxMessage));
+ return null;
+ }
+
+}
diff --git a/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/handler/MenuHandler.java b/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/handler/MenuHandler.java
new file mode 100644
index 0000000000..edb0fa8af8
--- /dev/null
+++ b/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/handler/MenuHandler.java
@@ -0,0 +1,36 @@
+package com.epmet.wx.mp.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.MenuButtonType;
+
+/**
+ * @author Binary Wang(https://github.com/binarywang)
+ */
+@Component
+public class MenuHandler extends AbstractHandler {
+
+ @Override
+ public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
+ Map context, WxMpService weixinService,
+ WxSessionManager sessionManager) {
+
+ String msg = String.format("type:%s, event:%s, key:%s",
+ wxMessage.getMsgType(), wxMessage.getEvent(),
+ wxMessage.getEventKey());
+ if (MenuButtonType.VIEW.equals(wxMessage.getEvent())) {
+ return null;
+ }
+
+ return WxMpXmlOutMessage.TEXT().content(msg)
+ .fromUser(wxMessage.getToUser()).toUser(wxMessage.getFromUser())
+ .build();
+ }
+
+}
diff --git a/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/handler/MsgHandler.java b/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/handler/MsgHandler.java
new file mode 100644
index 0000000000..492ba61613
--- /dev/null
+++ b/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/handler/MsgHandler.java
@@ -0,0 +1,52 @@
+package com.epmet.wx.mp.handler;
+
+import com.epmet.wx.mp.builder.TextBuilder;
+import com.epmet.wx.mp.utils.JsonUtils;
+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 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 = "收到信息内容:" + JsonUtils.toJson(wxMessage);
+
+ return new TextBuilder().build(content, wxMessage, weixinService);
+
+ }
+
+}
diff --git a/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/handler/NullHandler.java b/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/handler/NullHandler.java
new file mode 100644
index 0000000000..39716acf93
--- /dev/null
+++ b/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/handler/NullHandler.java
@@ -0,0 +1,24 @@
+package com.epmet.wx.mp.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 context, WxMpService wxMpService,
+ WxSessionManager sessionManager) {
+ return null;
+ }
+
+}
diff --git a/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/handler/ScanHandler.java b/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/handler/ScanHandler.java
new file mode 100644
index 0000000000..0f22dd27ff
--- /dev/null
+++ b/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/handler/ScanHandler.java
@@ -0,0 +1,25 @@
+package com.epmet.wx.mp.handler;
+
+import java.util.Map;
+
+import org.springframework.stereotype.Component;
+
+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;
+
+/**
+ * @author Binary Wang(https://github.com/binarywang)
+ */
+@Component
+public class ScanHandler extends AbstractHandler {
+
+ @Override
+ public WxMpXmlOutMessage handle(WxMpXmlMessage wxMpXmlMessage, Map map,
+ WxMpService wxMpService, WxSessionManager wxSessionManager) throws WxErrorException {
+ // 扫码事件处理
+ return null;
+ }
+}
diff --git a/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/handler/StoreCheckNotifyHandler.java b/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/handler/StoreCheckNotifyHandler.java
new file mode 100644
index 0000000000..79ed57f75c
--- /dev/null
+++ b/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/handler/StoreCheckNotifyHandler.java
@@ -0,0 +1,27 @@
+package com.epmet.wx.mp.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 context, WxMpService wxMpService,
+ WxSessionManager sessionManager) {
+ // TODO 处理门店审核事件
+ return null;
+ }
+
+}
diff --git a/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/handler/SubscribeHandler.java b/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/handler/SubscribeHandler.java
new file mode 100644
index 0000000000..4acfb20c81
--- /dev/null
+++ b/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/handler/SubscribeHandler.java
@@ -0,0 +1,71 @@
+package com.epmet.wx.mp.handler;
+
+import java.util.Map;
+
+import com.epmet.wx.mp.builder.TextBuilder;
+import org.springframework.stereotype.Component;
+
+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;
+
+/**
+ * @author Binary Wang(https://github.com/binarywang)
+ */
+@Component
+public class SubscribeHandler extends AbstractHandler {
+
+ @Override
+ public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
+ Map 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 可以添加关注用户到本地数据库
+ }
+ } 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;
+ }
+
+}
diff --git a/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/handler/UnsubscribeHandler.java b/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/handler/UnsubscribeHandler.java
new file mode 100644
index 0000000000..3f86977706
--- /dev/null
+++ b/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/handler/UnsubscribeHandler.java
@@ -0,0 +1,27 @@
+package com.epmet.wx.mp.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 context, WxMpService wxMpService,
+ WxSessionManager sessionManager) {
+ String openId = wxMessage.getFromUser();
+ this.logger.info("取消关注用户 OPENID: " + openId);
+ // TODO 可以更新本地数据库为取消关注状态
+ return null;
+ }
+
+}
diff --git a/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/utils/JsonUtils.java b/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/utils/JsonUtils.java
new file mode 100644
index 0000000000..8534fce802
--- /dev/null
+++ b/epmet-commons/epmet-commons-tools-wx-mp/src/main/java/com/epmet/wx/mp/utils/JsonUtils.java
@@ -0,0 +1,16 @@
+package com.epmet.wx.mp.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()
+ .create();
+ return gson.toJson(obj);
+ }
+}
diff --git a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/redis/RedisKeys.java b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/redis/RedisKeys.java
index 419ab5a51e..0281c824b0 100644
--- a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/redis/RedisKeys.java
+++ b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/redis/RedisKeys.java
@@ -13,59 +13,96 @@ package com.epmet.commons.tools.redis;
* @since 1.0.0
*/
public class RedisKeys {
+
+ /**
+ * 党群e事通redis前缀
+ */
+ private static String rootPrefix = "epdc:";
+
/**
* 系统参数Key
*/
- public static String getSysParamsKey(){
- return "sys:params";
+ public static String getSysParamsKey() {
+ return rootPrefix.concat("sys:params");
}
/**
* 登录验证码Key
*/
- public static String getLoginCaptchaKey(String uuid){
- return "sys:captcha:" + uuid;
+ public static String getLoginCaptchaKey(String uuid) {
+ return rootPrefix.concat("sys:captcha:").concat(uuid);
}
/**
* 登录用户Key
*/
- public static String getSecurityUserKey(Long id){
- return "sys:security:user:" + id;
+ public static String getSecurityUserKey(Long id) {
+ return rootPrefix.concat("sys:security:user:").concat(String.valueOf(id));
}
/**
* 系统日志Key
*/
- public static String getSysLogKey(){
- return "sys:log";
+ public static String getSysLogKey() {
+ return rootPrefix.concat("sys:log");
}
/**
* 系统资源Key
*/
- public static String getSysResourceKey(){
- return "sys:resource";
+ public static String getSysResourceKey() {
+ return rootPrefix.concat("sys:resource");
}
/**
* 用户菜单导航Key
*/
- public static String getUserMenuNavKey(Long userId, String language){
- return "sys:user:nav:" + userId + "_" + language;
+ public static String getUserMenuNavKey(Long userId, String language) {
+ return rootPrefix.concat("sys:user:nav:").concat(String.valueOf(userId)).concat("_").concat(language);
}
/**
* 用户菜单导航Key
*/
- public static String getUserMenuNavKey(Long userId){
- return "sys:user:nav:" + userId + "_*";
+ public static String getUserMenuNavKey(Long userId) {
+ return rootPrefix.concat("sys:user:nav:").concat(String.valueOf(userId)).concat("_*");
}
/**
* 用户权限标识Key
*/
- public static String getUserPermissionsKey(Long userId){
- return "sys:user:permissions:" + userId;
+ public static String getUserPermissionsKey(Long userId) {
+ return rootPrefix.concat("sys:user:permissions:").concat(String.valueOf(userId));
}
+
+ public static String getCpUserKey(String id) {
+ return rootPrefix.concat("sys:security:cpuser:").concat(id);
+ }
+
+ /**
+ * 拼接手机验证码key---后面需要改!!!
+ *
+ * @param phone
+ * @return java.lang.String
+ * @author yujintao
+ * @date 2019/9/6 17:03
+ */
+ public static String getPhoneSmsCodeKey(String phone) {
+ return rootPrefix.concat("phone:sms:code:").concat(phone);
+ }
+
+ /**
+ * 用户请求发送短信接口,记录本次请求时间,保存一分钟
+ * ---后面需要改!!!
+ * @param phone
+ * @return java.lang.String
+ * @author work@yujt.net.cn
+ * @date 2019/12/6 19:05
+ */
+ public static String getPhoneSmsHistoryKey(String phone) {
+ return rootPrefix.concat("phone:sms:history:").concat(phone);
+ }
+
+
+
}
diff --git a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/redis/RedisUtils.java b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/redis/RedisUtils.java
index 9211a3a319..fd02d32f73 100644
--- a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/redis/RedisUtils.java
+++ b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/redis/RedisUtils.java
@@ -29,29 +29,53 @@ public class RedisUtils {
@Autowired
private RedisTemplate redisTemplate;
- /** 默认过期时长为24小时,单位:秒 */
+ /**
+ * 默认过期时长为24小时,单位:秒
+ */
public final static long DEFAULT_EXPIRE = 60 * 60 * 24L;
- /** 过期时长为1小时,单位:秒 */
+ /**
+ * 过期时长为1小时,单位:秒
+ */
public final static long HOUR_ONE_EXPIRE = 60 * 60 * 1L;
- /** 过期时长为6小时,单位:秒 */
+ /**
+ * 过期时长为6小时,单位:秒
+ */
public final static long HOUR_SIX_EXPIRE = 60 * 60 * 6L;
- /** 不设置过期时长 */
+ /**
+ * 过期时长为5分钟,单位:秒
+ */
+ public final static long MINUTE_FIVE_EXPIRE = 60 * 5 * 1L;
+ /**
+ * 过期时长为1分钟,单位:秒
+ */
+ public final static long MINUTE_ONE_EXPIRE = 60 * 1 * 1L;
+ /**
+ * 过期时长为10分钟,单位:秒
+ */
+ public final static long MINUTE_TEN_EXPIRE = 60 * 10 * 1L;
+ /**
+ * 过期时长为30分钟,单位:秒
+ */
+ public final static long MINUTE_THIRTY_EXPIRE = 60 * 30 * 1L;
+ /**
+ * 不设置过期时长
+ */
public final static long NOT_EXPIRE = -1L;
- public void set(String key, Object value, long expire){
+ public void set(String key, Object value, long expire) {
redisTemplate.opsForValue().set(key, value);
- if(expire != NOT_EXPIRE){
+ if (expire != NOT_EXPIRE) {
expire(key, expire);
}
}
- public void set(String key, Object value){
+ public void set(String key, Object value) {
set(key, value, DEFAULT_EXPIRE);
}
public Object get(String key, long expire) {
Object value = redisTemplate.opsForValue().get(key);
- if(expire != NOT_EXPIRE){
+ if (expire != NOT_EXPIRE) {
expire(key, expire);
}
return value;
@@ -61,7 +85,7 @@ public class RedisUtils {
return get(key, NOT_EXPIRE);
}
- public Set keys(String pattern){
+ public Set keys(String pattern) {
return redisTemplate.keys(pattern);
}
@@ -81,19 +105,19 @@ public class RedisUtils {
return redisTemplate.opsForHash().get(key, field);
}
- public Map hGetAll(String key){
+ public Map hGetAll(String key) {
HashOperations hashOperations = redisTemplate.opsForHash();
return hashOperations.entries(key);
}
- public void hMSet(String key, Map map){
+ public void hMSet(String key, Map map) {
hMSet(key, map, DEFAULT_EXPIRE);
}
- public void hMSet(String key, Map map, long expire){
+ public void hMSet(String key, Map map, long expire) {
redisTemplate.opsForHash().putAll(key, map);
- if(expire != NOT_EXPIRE){
+ if (expire != NOT_EXPIRE) {
expire(key, expire);
}
}
@@ -105,32 +129,37 @@ public class RedisUtils {
public void hSet(String key, String field, Object value, long expire) {
redisTemplate.opsForHash().put(key, field, value);
- if(expire != NOT_EXPIRE){
+ if (expire != NOT_EXPIRE) {
expire(key, expire);
}
}
- public void expire(String key, long expire){
- redisTemplate.expire(key, expire, TimeUnit.SECONDS);
+ public boolean expire(String key, long expire) {
+ return redisTemplate.expire(key, expire, TimeUnit.SECONDS);
}
- public void hDel(String key, Object... fields){
+ public long getExpire(String key) {
+ return redisTemplate.getExpire(key, TimeUnit.SECONDS);
+ }
+
+ public void hDel(String key, Object... fields) {
redisTemplate.opsForHash().delete(key, fields);
}
- public void leftPush(String key, Object value){
+ public void leftPush(String key, Object value) {
leftPush(key, value, DEFAULT_EXPIRE);
}
- public void leftPush(String key, Object value, long expire){
+ public void leftPush(String key, Object value, long expire) {
redisTemplate.opsForList().leftPush(key, value);
- if(expire != NOT_EXPIRE){
+ if (expire != NOT_EXPIRE) {
expire(key, expire);
}
}
- public Object rightPop(String key){
+ public Object rightPop(String key) {
return redisTemplate.opsForList().rightPop(key);
}
+
}
diff --git a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/utils/DateUtils.java b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/utils/DateUtils.java
index 022d28b9c8..097da00d3e 100644
--- a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/utils/DateUtils.java
+++ b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/utils/DateUtils.java
@@ -29,6 +29,8 @@ public class DateUtils {
public final static String DATE_PATTERN = "yyyy-MM-dd";
/** 时间格式(yyyy-MM-dd HH:mm:ss) */
public final static String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
+ /** 时间格式(yyyyMMddHHmmss) */
+ public final static String DATE_TIME_NO_SPLIT = "yyyyMMddHHmmss";
/**
* 日期格式化 日期格式为:yyyy-MM-dd
diff --git a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/utils/WebUtil.java b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/utils/WebUtil.java
new file mode 100644
index 0000000000..f1e2c53382
--- /dev/null
+++ b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/utils/WebUtil.java
@@ -0,0 +1,66 @@
+package com.epmet.commons.tools.utils;
+
+import org.springframework.web.context.request.RequestAttributes;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * Web工具类
+ *
+ * @author rongchao
+ * @Date 18-11-20
+ */
+public class WebUtil {
+
+ public static HttpServletRequest getHttpServletRequest() {
+ ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+ HttpServletRequest request = requestAttributes.getRequest();
+ return request;
+ }
+
+ public static Object getAttributesFromRequest(String paramName) {
+ ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+ return requestAttributes.getAttribute(paramName, RequestAttributes.SCOPE_REQUEST);
+ }
+
+ public static void setAttributesFromRequest(String paramName, Object obj) {
+ ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+ requestAttributes.setAttribute(paramName, obj, RequestAttributes.SCOPE_REQUEST);
+ }
+
+ /**
+ * 获取用户真实IP地址,不使用request.getRemoteAddr();的原因是有可能用户使用了代理软件方式避免真实IP地址,
+ *
+ * 可是,如果通过了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP值,究竟哪个才是真正的用户端的真实IP呢?
+ * 答案是取X-Forwarded-For中第一个非unknown的有效IP字符串。
+ *
+ * 如:X-Forwarded-For:192.168.1.110, 192.168.1.120, 192.168.1.130,
+ * 192.168.1.100
+ *
+ * 用户真实IP为: 192.168.1.110
+ *
+ * @return
+ */
+ public static String getIpAddress() {
+ HttpServletRequest request = getHttpServletRequest();
+ String ip = request.getHeader("x-forwarded-for");
+ if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+ ip = request.getHeader("Proxy-Client-IP");
+ }
+ if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+ ip = request.getHeader("WL-Proxy-Client-IP");
+ }
+ if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+ ip = request.getHeader("HTTP_CLIENT_IP");
+ }
+ if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+ ip = request.getHeader("HTTP_X_FORWARDED_FOR");
+ }
+ if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+ ip = request.getRemoteAddr();
+ }
+ return ip;
+ }
+}
diff --git a/epmet-commons/pom.xml b/epmet-commons/pom.xml
index c4f8cd0f99..350503fdae 100644
--- a/epmet-commons/pom.xml
+++ b/epmet-commons/pom.xml
@@ -17,6 +17,10 @@
epmet-commons-tools
epmet-commons-mybatis
epmet-commons-dynamic-datasource
+ epmet-commons-tools-phone
+ epmet-common-clienttoken
+ epmet-commons-tools-wx-ma
+ epmet-commons-tools-wx-mp