소스 검색

新增微信端功能

M墨鱼—_mo 5 년 전
부모
커밋
9f41796574
34개의 변경된 파일2650개의 추가작업 그리고 5개의 파일을 삭제
  1. 20 0
      pom.xml
  2. 2 1
      src/main/java/com/jpsoft/smart/config/WebMvcConfig.java
  3. 2 0
      src/main/java/com/jpsoft/smart/modules/base/dao/InformationInfoDAO.java
  4. 2 0
      src/main/java/com/jpsoft/smart/modules/base/service/InformationInfoService.java
  5. 5 0
      src/main/java/com/jpsoft/smart/modules/base/service/impl/InformationInfoServiceImpl.java
  6. 10 0
      src/main/java/com/jpsoft/smart/modules/common/dto/MessageResult.java
  7. 105 0
      src/main/java/com/jpsoft/smart/modules/common/service/IRedisService.java
  8. 33 0
      src/main/java/com/jpsoft/smart/modules/common/service/impl/RedisServiceImpl.java
  9. 100 0
      src/main/java/com/jpsoft/smart/modules/common/utils/ApiUtil.java
  10. 135 0
      src/main/java/com/jpsoft/smart/modules/common/utils/Generator/AbstractCaptchaA.java
  11. 29 0
      src/main/java/com/jpsoft/smart/modules/common/utils/Generator/AbstractGeneratorA.java
  12. 39 0
      src/main/java/com/jpsoft/smart/modules/common/utils/Generator/CaptchaUtilA.java
  13. 55 0
      src/main/java/com/jpsoft/smart/modules/common/utils/Generator/CircleCaptchaA.java
  14. 31 0
      src/main/java/com/jpsoft/smart/modules/common/utils/Generator/RandomGeneratorA.java
  15. 376 0
      src/main/java/com/jpsoft/smart/modules/common/utils/HttpConnectionUtil.java
  16. 24 0
      src/main/java/com/jpsoft/smart/modules/common/utils/MyX509TrustManager.java
  17. 155 0
      src/main/java/com/jpsoft/smart/modules/common/utils/SMSUtil.java
  18. 70 0
      src/main/java/com/jpsoft/smart/modules/common/utils/Sign.java
  19. 316 0
      src/main/java/com/jpsoft/smart/modules/common/utils/WechatMessageUtil.java
  20. 139 0
      src/main/java/com/jpsoft/smart/modules/common/utils/WeixinUtil.java
  21. 631 0
      src/main/java/com/jpsoft/smart/modules/wechat/controller/WxController.java
  22. 20 0
      src/main/java/com/jpsoft/smart/modules/wechat/dao/AccessContorlDAO.java
  23. 62 0
      src/main/java/com/jpsoft/smart/modules/wechat/entity/AccessControl.java
  24. 29 0
      src/main/java/com/jpsoft/smart/modules/wechat/entity/AccessToken.java
  25. 36 0
      src/main/java/com/jpsoft/smart/modules/wechat/service/IAccessControlService.java
  26. 44 0
      src/main/java/com/jpsoft/smart/modules/wechat/service/impl/AccessControlServiceImpl.java
  27. 15 0
      src/main/java/com/jpsoft/smart/modules/wechat/vo/BindFaceVo.java
  28. 39 0
      src/main/java/com/jpsoft/smart/modules/wechat/vo/BindPhoneVo.java
  29. 17 0
      src/main/java/com/jpsoft/smart/modules/wechat/vo/RepairsVo.java
  30. 20 0
      src/main/java/com/jpsoft/smart/modules/wechat/vo/UserInfo.java
  31. 3 3
      src/main/resources/application-dev.yml
  32. 4 1
      src/main/resources/application.yml
  33. 6 0
      src/main/resources/mapper/base/InformationInfo.xml
  34. 76 0
      src/main/resources/mapper/wechat/accessControl.xml

+ 20 - 0
pom.xml

@@ -84,6 +84,11 @@
             <version>${swagger2.version}</version>
         </dependency>
 
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+        </dependency>
+
         <!--jwt start-->
         <dependency>
             <groupId>io.jsonwebtoken</groupId>
@@ -194,6 +199,21 @@
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-data-redis</artifactId>
         </dependency>
+
+        <!--短信相关-->
+        <dependency>
+            <groupId>com.taobao</groupId>
+            <artifactId>taobao-sdk-java</artifactId>
+            <version>1.0.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>net.sf.json-lib</groupId>
+            <artifactId>json-lib</artifactId>
+            <version>2.4</version>
+            <type>jar</type>
+            <classifier>jdk15</classifier>
+        </dependency>
     </dependencies>
     <build>
         <plugins>

+ 2 - 1
src/main/java/com/jpsoft/smart/config/WebMvcConfig.java

@@ -55,6 +55,7 @@ public class WebMvcConfig implements WebMvcConfigurer {
 				.excludePathPatterns("/aliPay/payNotify")
 				.excludePathPatterns("/wxPay/payNotify")
 				.excludePathPatterns("/base/alarmInfo/alarmNotify")
-				.excludePathPatterns("/base/informationInfo/addMobile");
+				.excludePathPatterns("/base/informationInfo/addMobile")
+				.excludePathPatterns("/wechat/**");
 	}
 }

+ 2 - 0
src/main/java/com/jpsoft/smart/modules/base/dao/InformationInfoDAO.java

@@ -16,4 +16,6 @@ public interface InformationInfoDAO {
 	int delete(String id);
 	List<InformationInfo> list();
 	List<InformationInfo> search(Map<String, Object> searchParams, List<Sort> sortList);
+
+    List<InformationInfo> findByOwnerIdAndType(String ownerId, String type);
 }

+ 2 - 0
src/main/java/com/jpsoft/smart/modules/base/service/InformationInfoService.java

@@ -15,4 +15,6 @@ public interface InformationInfoService {
 	int delete(String id);
 	List<InformationInfo> list();
 	Page<InformationInfo> pageSearch(Map<String, Object> searchParams, int pageNum, int pageSize, List<Sort> sortList);
+
+	List<InformationInfo> findByOwnerIdAndType(String ownerId, String type);
 }

+ 5 - 0
src/main/java/com/jpsoft/smart/modules/base/service/impl/InformationInfoServiceImpl.java

@@ -67,4 +67,9 @@ public class InformationInfoServiceImpl implements InformationInfoService {
         
         return page;
 	}
+
+	@Override
+	public List<InformationInfo> findByOwnerIdAndType(String ownerId, String type) {
+		return informationInfoDAO.findByOwnerIdAndType(ownerId,type);
+	}
 }

+ 10 - 0
src/main/java/com/jpsoft/smart/modules/common/dto/MessageResult.java

@@ -6,6 +6,16 @@ public class MessageResult<T> {
 	private T data;
 	private int code = 200;
 
+	public MessageResult() {
+	}
+
+	public MessageResult(boolean result, String message, T data, int code) {
+		this.result = result;
+		this.message = message;
+		this.data = data;
+		this.code = code;
+	}
+
 	public boolean isResult() {
 		return result;
 	}

+ 105 - 0
src/main/java/com/jpsoft/smart/modules/common/service/IRedisService.java

@@ -0,0 +1,105 @@
+package com.jpsoft.smart.modules.common.service;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.HashOperations;
+import org.springframework.data.redis.core.RedisTemplate;
+
+import javax.annotation.Resource;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+public abstract class IRedisService<T> {
+    @Autowired
+    protected RedisTemplate<String, Object> redisTemplate;
+    @Resource
+    protected HashOperations<String, String, T> hashOperations;
+
+    /**
+     * 存入redis中的key
+     *
+     * @return
+     */
+    protected abstract String getRedisKey(String jpKey);
+
+    /**
+     * 添加
+     *
+     * @param key    key
+     * @param doamin 对象
+     * @param expire 过期时间(单位:秒),传入 -1 时表示不设置过期时间
+     */
+    public void put(String jpKey, String key, T doamin, long expire) {
+        hashOperations.put(getRedisKey(jpKey), key, doamin);
+        if (expire != -1) {
+            redisTemplate.expire(getRedisKey(jpKey), expire, TimeUnit.SECONDS);
+        }
+    }
+
+    /**
+     * 删除
+     *
+     * @param key 传入key的名称
+     */
+    public void remove(String key) {
+        hashOperations.delete(getRedisKey(""), key);
+    }
+
+    /**
+     * 查询
+     *
+     * @param key 查询的key
+     * @return
+     */
+    public T get(String jpKey ,String key) {
+        return hashOperations.get(getRedisKey(jpKey), key);
+    }
+
+    /**
+     * 获取当前redis库下所有对象
+     *
+     * @return
+     */
+    public List<T> getAll() {
+        return hashOperations.values(getRedisKey(""));
+    }
+
+    /**
+     * 查询查询当前redis库下所有key
+     *
+     * @return
+     */
+    public Set<String> getKeys() {
+        return hashOperations.keys(getRedisKey(""));
+    }
+
+    /**
+     * 判断key是否存在redis中
+     *
+     * @param key 传入key的名称
+     * @return
+     */
+    public boolean isKeyExists(String key) {
+        return hashOperations.hasKey(getRedisKey(""), key);
+    }
+
+    /**
+     * 查询当前key下缓存数量
+     *
+     * @return
+     */
+    public long count() {
+        return hashOperations.size(getRedisKey(""));
+    }
+
+    /**
+     * 清空redis
+     */
+    public void empty() {
+        Set<String> set = hashOperations.keys(getRedisKey(""));
+        
+        for (String key : set) {  
+        	hashOperations.delete(getRedisKey(""), key);
+        }  
+    }
+}

+ 33 - 0
src/main/java/com/jpsoft/smart/modules/common/service/impl/RedisServiceImpl.java

@@ -0,0 +1,33 @@
+package com.jpsoft.smart.modules.common.service.impl;
+
+import com.jpsoft.smart.modules.common.service.IRedisService;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Service;
+
+@Service(value="redisService")
+public class RedisServiceImpl extends IRedisService<Object> {
+    private static final String REDIS_KEY = "JP_HOUSEPROPERTY_REDIS_KEY";
+    private static final String REDIS_KEY1 = "VERIFYCODE_REDIS_KEY";
+    private static final String REDIS_KEY2 = "APITOKEN_REDIS_KEY";
+    private static final String REDIS_KEY3 = "ACCESSTOKEN_REDIS_KEY";
+
+
+    @SuppressWarnings("static-access")
+	@Override
+    protected String getRedisKey(String jpKey) {
+        if (jpKey.equals("code")){
+            return REDIS_KEY1;
+        }
+        if (jpKey.equals("apiToken")){
+            return REDIS_KEY2;
+        }
+        if (jpKey.equals("accessToken")){
+            return REDIS_KEY3;
+        }
+        if (StringUtils.isBlank(jpKey)){
+            return REDIS_KEY;
+        }
+        return REDIS_KEY;
+
+    }
+}

+ 100 - 0
src/main/java/com/jpsoft/smart/modules/common/utils/ApiUtil.java

@@ -0,0 +1,100 @@
+package com.jpsoft.smart.modules.common.utils;
+
+import cn.hutool.http.HttpRequest;
+import com.alibaba.fastjson.JSONObject;
+import com.jpsoft.smart.modules.common.service.impl.RedisServiceImpl;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author 墨鱼_mo
+ * @date 2019-8-6 9:43
+ */
+@Component
+public class ApiUtil {
+
+    @Value("${doorApi.apiId}")
+    private String apiId;
+
+    @Value("${doorApi.apiKey}")
+    private String apiKey;
+
+    @Value("${doorApi.referer}")
+    private String referer;
+
+    @Autowired
+    private RedisServiceImpl redisService;
+
+
+    public String getApiToken(){
+        HashMap map = new HashMap();
+
+        map.put("apiid",apiId);
+        map.put("apikey", apiKey);
+
+        Map<String,String> heardMap = new HashMap<>();
+        heardMap.put("referer",referer);
+
+
+        String body = HttpRequest.post("https://api.parkline.cc/api/token").addHeaders(heardMap).form(map).execute().body();
+        JSONObject jsonbody = JSONObject.parseObject(body);
+        String apiToken = jsonbody.getString("access_token");
+
+        if (StringUtils.isNotBlank(apiToken)){
+
+            redisService.put("apiToken","apiToken",apiToken,7200L);
+
+            return apiToken;
+
+
+        }
+        else {
+            return "";
+        }
+
+
+
+
+
+    }
+
+
+    public JSONObject httpRequest(String url, String token,String typeid,String devid,String lockid,String tel,String filedata){
+        HashMap map = new HashMap();
+
+        map.put("token",token);
+        map.put("typeid", typeid);
+        map.put("devid",devid);
+        map.put("lockid",lockid);
+        map.put("tel",tel);
+        map.put("filedata",filedata);
+
+
+
+        String body = HttpRequest.post(url).header("referer",referer).form(map).execute().body();
+        JSONObject jsonbody = JSONObject.parseObject(body);
+        return jsonbody;
+
+
+    }
+
+    public Boolean testApiToken(String apiToken,String devid){
+        if (StringUtils.isBlank(apiToken)){
+            return false;
+        }
+
+        JSONObject resultJSON = httpRequest("https://api.parkline.cc/api/statuscgi",apiToken,"",devid,"","","");
+        if (resultJSON.getString("code").equals("402")){
+            return false;
+        }
+        else {
+            return true;
+        }
+    }
+
+}

+ 135 - 0
src/main/java/com/jpsoft/smart/modules/common/utils/Generator/AbstractCaptchaA.java

@@ -0,0 +1,135 @@
+package com.jpsoft.smart.modules.common.utils.Generator;
+
+import cn.hutool.captcha.ICaptcha;
+import cn.hutool.captcha.generator.CodeGenerator;
+import cn.hutool.core.codec.Base64;
+import cn.hutool.core.img.ImgUtil;
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.io.IORuntimeException;
+import cn.hutool.core.io.IoUtil;
+
+import java.awt.*;
+import java.awt.image.BufferedImage;
+import java.io.*;
+
+/**
+ * @author 墨鱼_mo
+ * @date 2019-8-8 15:27
+ */
+
+public abstract class AbstractCaptchaA implements ICaptcha {
+    private static final long serialVersionUID = 3180820918087507254L;
+    protected int width;
+    protected int height;
+    protected int interfereCount;
+    protected Font font;
+    protected String code;
+    protected byte[] imageBytes;
+    protected CodeGenerator generator;
+    protected Color background;
+
+    public AbstractCaptchaA(int width, int height, int codeCount, int interfereCount) {
+        this(width, height, new RandomGeneratorA(codeCount), interfereCount);
+    }
+
+    public AbstractCaptchaA(int width, int height, CodeGenerator generator, int interfereCount) {
+        this.width = 100;
+        this.height = 37;
+        this.interfereCount = 15;
+        this.width = width;
+        this.height = height;
+        this.generator = generator;
+        this.interfereCount = interfereCount;
+        this.font = new Font("Courier", 0, (int) ((double) this.height * 0.75D));
+        this.createCode();
+    }
+
+    public void createCode() {
+        this.generateCode();
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        ImgUtil.writePng(this.createImage(this.code), out);
+        this.imageBytes = out.toByteArray();
+    }
+
+    protected void generateCode() {
+        this.code = this.generator.generate();
+    }
+
+    protected abstract Image createImage(String var1);
+
+    public String getCode() {
+        return this.code;
+    }
+
+    public boolean verify(String userInputCode) {
+        return this.generator.verify(this.code, userInputCode);
+    }
+
+    public void write(String path) throws IORuntimeException {
+        this.write(FileUtil.touch(path));
+    }
+
+    public void write(File file) throws IORuntimeException {
+        try {
+            OutputStream out = FileUtil.getOutputStream(file);
+            Throwable var3 = null;
+
+            try {
+                this.write((OutputStream) out);
+            } catch (Throwable var13) {
+                var3 = var13;
+                throw var13;
+            } finally {
+                if (out != null) {
+                    if (var3 != null) {
+                        try {
+                            out.close();
+                        } catch (Throwable var12) {
+                            var3.addSuppressed(var12);
+                        }
+                    } else {
+                        out.close();
+                    }
+                }
+
+            }
+
+        } catch (IOException var15) {
+            throw new IORuntimeException(var15);
+        }
+    }
+
+    public void write(OutputStream out) {
+        IoUtil.write(out, false, this.imageBytes);
+    }
+
+    public BufferedImage getImage() {
+        if (null == this.imageBytes) {
+            this.createCode();
+        }
+
+        return ImgUtil.read(new ByteArrayInputStream(this.imageBytes));
+    }
+
+    public String getImageBase64() {
+        return Base64.encode(this.imageBytes);
+    }
+
+    public void setFont(Font font) {
+        this.font = font;
+    }
+
+    public CodeGenerator getGenerator() {
+        return this.generator;
+    }
+
+    public void setGenerator(CodeGenerator generator) {
+        this.generator = generator;
+        this.createCode();
+    }
+
+    public void setBackground(Color background) {
+        this.background = background;
+    }
+}
+

+ 29 - 0
src/main/java/com/jpsoft/smart/modules/common/utils/Generator/AbstractGeneratorA.java

@@ -0,0 +1,29 @@
+package com.jpsoft.smart.modules.common.utils.Generator;
+
+import cn.hutool.captcha.generator.CodeGenerator;
+
+/**
+ * @author 墨鱼_mo
+ * @date 2019-8-8 15:21
+ */
+
+
+public abstract class AbstractGeneratorA implements CodeGenerator {
+    private static final long serialVersionUID = 8685744597154953479L;
+    protected String baseStr;
+    protected int length;
+
+    public AbstractGeneratorA(int count) {
+        this("0123456789", count);
+    }
+
+    public AbstractGeneratorA(String baseStr, int length) {
+        this.baseStr = baseStr;
+        this.length = length;
+    }
+
+    public int getLength() {
+        return this.length;
+    }
+}
+

+ 39 - 0
src/main/java/com/jpsoft/smart/modules/common/utils/Generator/CaptchaUtilA.java

@@ -0,0 +1,39 @@
+package com.jpsoft.smart.modules.common.utils.Generator;
+
+import cn.hutool.captcha.CircleCaptcha;
+import cn.hutool.captcha.LineCaptcha;
+import cn.hutool.captcha.ShearCaptcha;
+
+/**
+ * @author 墨鱼_mo
+ * @date 2019-8-8 15:30
+ */
+public class CaptchaUtilA {
+
+    public CaptchaUtilA() {
+    }
+
+    public static LineCaptcha createLineCaptcha(int width, int height) {
+        return new LineCaptcha(width, height);
+    }
+
+    public static LineCaptcha createLineCaptcha(int width, int height, int codeCount, int lineCount) {
+        return new LineCaptcha(width, height, codeCount, lineCount);
+    }
+
+    public static CircleCaptcha createCircleCaptcha(int width, int height) {
+        return new CircleCaptcha(width, height);
+    }
+
+    public static CircleCaptchaA createCircleCaptcha(int width, int height, int codeCount, int circleCount) {
+        return new CircleCaptchaA(width, height, codeCount, circleCount);
+    }
+
+    public static ShearCaptcha createShearCaptcha(int width, int height) {
+        return new ShearCaptcha(width, height);
+    }
+
+    public static ShearCaptcha createShearCaptcha(int width, int height, int codeCount, int thickness) {
+        return new ShearCaptcha(width, height, codeCount, thickness);
+    }
+}

+ 55 - 0
src/main/java/com/jpsoft/smart/modules/common/utils/Generator/CircleCaptchaA.java

@@ -0,0 +1,55 @@
+package com.jpsoft.smart.modules.common.utils.Generator;
+
+import cn.hutool.core.img.GraphicsUtil;
+import cn.hutool.core.img.ImgUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.RandomUtil;
+
+import java.awt.*;
+import java.awt.image.BufferedImage;
+import java.util.concurrent.ThreadLocalRandom;
+
+/**
+ * @author 墨鱼_mo
+ * @date 2019-8-8 15:29
+ */
+
+    public class CircleCaptchaA extends AbstractCaptchaA {
+        private static final long serialVersionUID = -7096627300356535494L;
+
+        public CircleCaptchaA(int width, int height) {
+            this(width, height, 5);
+        }
+
+        public CircleCaptchaA(int width, int height, int codeCount) {
+            this(width, height, codeCount, 15);
+        }
+
+        public CircleCaptchaA(int width, int height, int codeCount, int interfereCount) {
+            super(width, height, codeCount, interfereCount);
+        }
+
+        public Image createImage(String code) {
+            BufferedImage image = new BufferedImage(this.width, this.height, 1);
+            Graphics2D g = ImgUtil.createGraphics(image, (Color) ObjectUtil.defaultIfNull(this.background, Color.WHITE));
+            this.drawInterfere(g);
+            this.drawString(g, code);
+            return image;
+        }
+
+        private void drawString(Graphics2D g, String code) {
+            g.setComposite(AlphaComposite.getInstance(3, 0.9F));
+            GraphicsUtil.drawStringColourful(g, code, this.font, this.width, this.height);
+        }
+
+        private void drawInterfere(Graphics2D g) {
+            ThreadLocalRandom random = RandomUtil.getRandom();
+
+            for(int i = 0; i < this.interfereCount; ++i) {
+                g.setColor(ImgUtil.randomColor(random));
+                g.drawOval(random.nextInt(this.width), random.nextInt(this.height), random.nextInt(this.height >> 1), random.nextInt(this.height >> 1));
+            }
+
+        }
+    }
+

+ 31 - 0
src/main/java/com/jpsoft/smart/modules/common/utils/Generator/RandomGeneratorA.java

@@ -0,0 +1,31 @@
+package com.jpsoft.smart.modules.common.utils.Generator;
+
+import cn.hutool.core.util.RandomUtil;
+import cn.hutool.core.util.StrUtil;
+
+/**
+ * @author 墨鱼_mo
+ * @date 2019-8-8 15:25
+ */
+
+
+    public class RandomGeneratorA extends AbstractGeneratorA {
+        private static final long serialVersionUID = -7802758587765561876L;
+
+        public RandomGeneratorA(int count) {
+            super(count);
+        }
+
+        public RandomGeneratorA(String baseStr, int length) {
+            super(baseStr, length);
+        }
+
+        public String generate() {
+            return RandomUtil.randomString(this.baseStr, this.length);
+        }
+
+        public boolean verify(String code, String userInputCode) {
+            return StrUtil.isNotBlank(userInputCode) ? StrUtil.equalsIgnoreCase(code, userInputCode) : false;
+        }
+    }
+

+ 376 - 0
src/main/java/com/jpsoft/smart/modules/common/utils/HttpConnectionUtil.java

@@ -0,0 +1,376 @@
+package com.jpsoft.smart.modules.common.utils;
+
+import net.sf.json.JSONObject;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.config.RegistryBuilder;
+import org.apache.http.conn.socket.ConnectionSocketFactory;
+import org.apache.http.conn.socket.PlainConnectionSocketFactory;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.impl.conn.BasicHttpClientConnectionManager;
+import org.apache.http.util.EntityUtils;
+
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+import java.io.*;
+import java.net.ConnectException;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Iterator;
+import java.util.Map;
+
+
+public class HttpConnectionUtil {
+    public static String getHttpContent(String url) {
+        return getHttpContent(url, "UTF-8");
+    }
+
+    public static String getHttpContent(String url, String charSet) {
+        HttpURLConnection connection = null;
+        String content = "";
+        try {
+            URL address_url = new URL(url);
+            connection = (HttpURLConnection) address_url.openConnection();
+            connection.setRequestMethod("GET");
+            //设置访问超时时间及读取网页流的超市时间,毫秒值
+            System.setProperty("sun.net.client.defaultConnectTimeout","30000");
+            System.setProperty("sun.net.client.defaultReadTimeout", "30000");
+
+            //after JDK 1.5
+//            connection.setConnectTimeout(10000);
+//            connection.setReadTimeout(10000);
+            //得到访问页面的返回值
+            int response_code = connection.getResponseCode();
+            if (response_code == HttpURLConnection.HTTP_OK) {
+                InputStream in = connection.getInputStream();
+//                InputStreamReader reader = new InputStreamReader(in,charSet);
+                BufferedReader reader = new BufferedReader(new InputStreamReader(in, charSet));
+                String line = null;
+                while ((line = reader.readLine()) != null) {
+                    content+=line;
+                }
+                return content;
+            }
+        } catch (MalformedURLException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        } finally {
+            if(connection !=null){
+                connection.disconnect();
+            }
+        }
+        return "";
+    }
+    
+    @SuppressWarnings("rawtypes")
+    public static String getHttpContentByPost(String url, String charSet,Map<String, Object> requestParamsMap) {
+        HttpURLConnection connection = null;
+        DataOutputStream out = null;
+        String content = "";
+        StringBuffer params = new StringBuffer();  
+        try {
+        	
+        	// 组织请求参数  
+            Iterator it = requestParamsMap.entrySet().iterator();  
+            while (it.hasNext()) {  
+				Map.Entry element = (Map.Entry) it.next();  
+                params.append(element.getKey());  
+                params.append("=");  
+                params.append(element.getValue());  
+                params.append("&");  
+            }  
+            if (params.length() > 0) {  
+                params.deleteCharAt(params.length() - 1);  
+            }  
+        	
+            System.out.println("url>>>>>>>>>>" + url);
+            System.out.println("params>>>>>>>>>>" + params);
+            
+            URL address_url = new URL(url);
+            connection = (HttpURLConnection) address_url.openConnection();
+            connection.setRequestMethod("POST");
+            //设置访问超时时间及读取网页流的超市时间,毫秒值
+            System.setProperty("sun.net.client.defaultConnectTimeout","30000");
+            System.setProperty("sun.net.client.defaultReadTimeout", "30000");
+
+         // 设置通用的请求属性  
+            connection.setRequestProperty("accept", "*/*");  
+            connection.setRequestProperty("connection", "Keep-Alive");  
+            connection.setRequestProperty("Content-Length", String.valueOf(params.length()));  
+            // 发送POST请求必须设置如下两行  
+            connection.setDoOutput(true);  
+            connection.setDoInput(true);  
+            // 获取URLConnection对象对应的输出流  
+            out = new DataOutputStream(connection.getOutputStream());
+            // 发送请求参数 
+            out.write(params.toString().getBytes("utf-8"));
+            out.flush();
+            out.close();
+            //得到访问页面的返回值
+            int response_code = connection.getResponseCode();
+            
+            System.out.println("response_code>>>>>" + response_code);
+            
+            if (response_code == HttpURLConnection.HTTP_OK) {
+                InputStream in = connection.getInputStream();
+//                InputStreamReader reader = new InputStreamReader(in,charSet);
+                BufferedReader reader = new BufferedReader(new InputStreamReader(in, charSet));
+                String line = null;
+                while ((line = reader.readLine()) != null) {
+                    content+=line;
+                }
+                
+                System.out.println("content>>>>>" + content);
+                return content;
+            }
+            
+            
+        } catch (MalformedURLException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        } finally {
+            if(connection !=null){
+                connection.disconnect();
+            }
+        }
+        return "";
+    }
+    
+    public static String getHttpContentByPost(String url, String charSet,String params) {
+        HttpURLConnection connection = null;
+        String content = "";
+        PrintWriter printWriter = null;
+        try {
+
+            URL address_url = new URL(url);
+            connection = (HttpURLConnection) address_url.openConnection();
+            connection.setRequestMethod("POST");
+            //设置访问超时时间及读取网页流的超市时间,毫秒值
+            System.setProperty("sun.net.client.defaultConnectTimeout","30000");
+            System.setProperty("sun.net.client.defaultReadTimeout", "30000");
+
+         // 设置通用的请求属性  
+            connection.setRequestProperty("accept", "*/*");  
+            connection.setRequestProperty("connection", "Keep-Alive");  
+            connection.setRequestProperty("Content-Length", String.valueOf(params.length()));  
+            // 发送POST请求必须设置如下两行  
+            connection.setDoOutput(true);  
+            connection.setDoInput(true);  
+            // 获取URLConnection对象对应的输出流  
+            printWriter = new PrintWriter(connection.getOutputStream());  
+            // 发送请求参数  
+            printWriter.write(params);  
+            // flush输出流的缓冲  
+            printWriter.flush();  
+            //得到访问页面的返回值
+            int response_code = connection.getResponseCode();
+            if (response_code == HttpURLConnection.HTTP_OK) {
+                InputStream in = connection.getInputStream();
+//                InputStreamReader reader = new InputStreamReader(in,charSet);
+                BufferedReader reader = new BufferedReader(new InputStreamReader(in, charSet));
+                String line = null;
+                while ((line = reader.readLine()) != null) {
+                    content+=line;
+                }
+                return content;
+            }
+        } catch (MalformedURLException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        } finally {
+            if(connection !=null){
+                connection.disconnect();
+            }
+        }
+        return "";
+    }
+    
+    private static int connectTimeoutMs = 3000;
+	private static int readTimeoutMs = 3000;
+	private static String charSet = "UTF-8";
+	
+	/**
+	 * 以http post方式请求
+	 * @param url 请求地址
+	 * @param data 请求参数
+	 * @return
+	 */
+	public static String requestByPost(String url,String data){
+		return requestByPost(url,charSet,data,connectTimeoutMs,readTimeoutMs);
+	}
+	
+	/**
+	 * 以http get方式请求
+	 * @param url 请求地址
+	 * @return
+	 */
+	public static String requestByGet(String url){
+		return requestByGet(url,charSet,connectTimeoutMs,readTimeoutMs);
+	}
+	
+	/**
+	 * 以http post方式请求
+	 * @param url 请求地址
+	 * @param charSet 字符编码
+	 * @param data 请求参数
+	 * @param connectTimeoutMs 连接超时(毫秒)
+	 * @param readTimeoutMs 数据读取超时(毫秒)
+	 * @return
+	 */
+    public static String requestByPost(String url,String charSet,String data, int connectTimeoutMs, int readTimeoutMs){
+    	try{
+	        BasicHttpClientConnectionManager connManager;
+	        
+	        connManager = new BasicHttpClientConnectionManager(
+	                RegistryBuilder.<ConnectionSocketFactory>create()
+	                        .register("http", PlainConnectionSocketFactory.getSocketFactory())
+	                        .register("https", SSLConnectionSocketFactory.getSocketFactory())
+	                        .build(),
+	                null,
+	                null,
+	                null
+	        );
+	
+	        HttpClient httpClient = HttpClientBuilder.create()
+	                .setConnectionManager(connManager)
+	                .build();
+	        
+	        HttpPost httpPost = new HttpPost(url);
+	        
+	        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(readTimeoutMs).setConnectTimeout(connectTimeoutMs).build();
+	        httpPost.setConfig(requestConfig);
+	
+	        StringEntity postEntity = new StringEntity(data, charSet);
+	        httpPost.addHeader("Content-Type", "text/xml");
+	        httpPost.setEntity(postEntity);
+	
+	        HttpResponse httpResponse = httpClient.execute(httpPost);
+	        HttpEntity httpEntity = httpResponse.getEntity();
+	        return EntityUtils.toString(httpEntity, "UTF-8");
+    	}catch(Exception e){
+    		e.printStackTrace();
+    	}
+    	
+    	return "";
+
+    }
+    
+    /**
+	 * 以http get方式请求
+	 * @param url 请求地址
+	 * @param charSet 字符编码
+	 * @param connectTimeoutMs 连接超时(毫秒)
+	 * @param readTimeoutMs 数据读取超时(毫秒)
+	 * @return
+	 */
+    public static String requestByGet(String url,String charSet,int connectTimeoutMs, int readTimeoutMs){
+    	try{
+	        BasicHttpClientConnectionManager connManager;
+	        
+	        connManager = new BasicHttpClientConnectionManager(
+	                RegistryBuilder.<ConnectionSocketFactory>create()
+	                        .register("http", PlainConnectionSocketFactory.getSocketFactory())
+	                        .register("https", SSLConnectionSocketFactory.getSocketFactory())
+	                        .build(),
+	                null,
+	                null,
+	                null
+	        );
+	
+	        HttpClient httpClient = HttpClientBuilder.create()
+	                .setConnectionManager(connManager)
+	                .build();
+	        
+	        HttpGet httpGet = new HttpGet(url);
+	        
+	        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(readTimeoutMs).setConnectTimeout(connectTimeoutMs).build();
+	        httpGet.setConfig(requestConfig);	
+	        httpGet.addHeader("Content-Type", "text/xml");
+	
+	        HttpResponse httpResponse = httpClient.execute(httpGet);
+	        HttpEntity httpEntity = httpResponse.getEntity();
+	        return EntityUtils.toString(httpEntity, "UTF-8");
+    	}catch(Exception e){
+    		e.printStackTrace();
+    	}
+    	
+    	return "";
+
+    }
+    
+    /**
+	 * 发起https请求并获取结果
+	 * 
+	 * @param requestUrl 请求地址
+	 * @param requestMethod 请求方式(GET、POST)
+	 * @param outputStr 提交的数据
+	 * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
+	 */
+	public static JSONObject httpRequest(String requestUrl, String requestMethod, String outputStr) {
+		JSONObject jsonObject = null;
+		StringBuffer buffer = new StringBuffer();
+		try {
+			// 创建SSLContext对象,并使用我们指定的信任管理器初始化
+			TrustManager[] tm = { new MyX509TrustManager() };
+			SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
+			sslContext.init(null, tm, new java.security.SecureRandom());
+			// 从上述SSLContext对象中得到SSLSocketFactory对象
+			SSLSocketFactory ssf = sslContext.getSocketFactory();
+
+			URL url = new URL(requestUrl);
+			HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();
+			httpUrlConn.setSSLSocketFactory(ssf);
+
+			httpUrlConn.setDoOutput(true);
+			httpUrlConn.setDoInput(true);
+			httpUrlConn.setUseCaches(false);
+			// 设置请求方式(GET/POST)
+			httpUrlConn.setRequestMethod(requestMethod);
+
+			if ("GET".equalsIgnoreCase(requestMethod))
+				httpUrlConn.connect();
+
+			// 当有数据需要提交时
+			if (null != outputStr) {
+				OutputStream outputStream = httpUrlConn.getOutputStream();
+				// 注意编码格式,防止中文乱码
+				outputStream.write(outputStr.getBytes("UTF-8"));
+				outputStream.close();
+			}
+
+			// 将返回的输入流转换成字符串
+			InputStream inputStream = httpUrlConn.getInputStream();
+			InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
+			BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
+
+			String str = null;
+			while ((str = bufferedReader.readLine()) != null) {
+				buffer.append(str);
+			}
+			bufferedReader.close();
+			inputStreamReader.close();
+			// 释放资源
+			inputStream.close();
+			inputStream = null;
+			httpUrlConn.disconnect();
+			jsonObject = JSONObject.fromObject(buffer.toString());
+		} catch (ConnectException ce) {
+			System.out.println("Weixin server connection timed out.");
+		} catch (Exception e) {
+			System.out.println("https request error:" +  e.getMessage());
+		}
+		return jsonObject;
+	}
+}

+ 24 - 0
src/main/java/com/jpsoft/smart/modules/common/utils/MyX509TrustManager.java

@@ -0,0 +1,24 @@
+package com.jpsoft.smart.modules.common.utils;
+
+import javax.net.ssl.X509TrustManager;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+
+/**
+ * 证书信任管理器(用于https请求)
+ * 
+ * @author lt
+ * @date 2013-08-08
+ */
+public class MyX509TrustManager implements X509TrustManager {
+
+	public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+	}
+
+	public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+	}
+
+	public X509Certificate[] getAcceptedIssuers() {
+		return null;
+	}
+}

+ 155 - 0
src/main/java/com/jpsoft/smart/modules/common/utils/SMSUtil.java

@@ -0,0 +1,155 @@
+package com.jpsoft.smart.modules.common.utils;
+
+import com.jpsoft.smart.modules.common.dto.MessageResult;
+import com.taobao.api.ApiException;
+import com.taobao.api.DefaultTaobaoClient;
+import com.taobao.api.TaobaoClient;
+import com.taobao.api.request.AlibabaAliqinFcSmsNumSendRequest;
+import com.taobao.api.response.AlibabaAliqinFcSmsNumSendResponse;
+import net.sf.json.JSONException;
+import net.sf.json.JSONObject;
+
+import java.util.Random;
+
+
+public class SMSUtil {
+	
+	public final static String REG_TEMPLATE_CODE = "SMS_49390047";
+	public static final String NUMBERCHAR = "0123456789";
+	
+	private final static String APP_KEY = "24698874";
+	private final static String APP_SECRET = "5f5b21d1dc93e124aa803f95d71c00b8";
+	private final static String APP_URL = "https://eco.taobao.com/router/rest";
+	private final static String SIGN_NAME = "荆鹏云平台";
+	private final static String SMS_TYPE = "normal";
+	
+	/**
+	 * 
+	 * @param phones 手机号,多个以英文逗号","隔开
+	 * @param smsTemplateCode 短信模版ID
+	 * @param jsonStr 短信模板变量,传参规则{"key":"value"},key的名字须和申请模板中的变量名一致,多个变量之间以逗号隔开。示例:针对模板“验证码${code},您正在进行${product}身份验证,打死不要告诉别人哦!”,传参时需传入{"code":"1234","product":"alidayu"}
+	 * @return
+	 */
+	public static MessageResult send(String phones, String smsTemplateCode, String jsonStr){
+		
+		boolean success = true;
+		String msg = "发送成功";
+		
+		TaobaoClient client = new DefaultTaobaoClient(APP_URL, APP_KEY, APP_SECRET);
+		AlibabaAliqinFcSmsNumSendRequest req = new AlibabaAliqinFcSmsNumSendRequest();
+		req.setSmsType(SMS_TYPE);
+		req.setSmsFreeSignName(SIGN_NAME);
+		if(jsonStr != null){
+			req.setSmsParamString(jsonStr);
+		}
+		req.setRecNum(phones);
+		req.setSmsTemplateCode(smsTemplateCode);
+		AlibabaAliqinFcSmsNumSendResponse rsp;
+		try {
+			rsp = client.execute(req);
+			
+			JSONObject ret = JSONObject.fromObject(rsp.getBody());
+			
+			System.out.println("ret>>>>" + ret);
+			
+			if(ret.containsKey("error_response")){
+				success = false;
+				msg = ret.getJSONObject("error_response").getString("sub_msg");
+			}else if(ret.containsKey("alibaba_aliqin_fc_sms_num_send_response")){
+				
+				JSONObject result = ret.getJSONObject("alibaba_aliqin_fc_sms_num_send_response").getJSONObject("result");
+				
+				if(!result.getBoolean("success")){
+					msg = result.getString("msg");
+				}
+			}else{
+				success = false;
+				msg = ret.toString();
+			}
+		} catch (ApiException e) {
+			success = false;
+			msg = e.getErrMsg();
+		} catch (JSONException ex) {
+			success = false;
+			msg = ex.getMessage();
+		}
+
+		MessageResult retMessage = new MessageResult();
+		
+		retMessage.setMessage(msg);
+		retMessage.setResult(success);
+		
+		return retMessage;
+	}
+	
+	/**
+	 * 
+	 * @param phones 手机号,多个以英文逗号","隔开
+	 * @param signName 签名:目前仅支持"荆鹏云平台","速乐购"两种签名
+	 * @param smsTemplateCode 短信模版ID
+	 * @param json 短信模板变量,传参规则{"key":"value"},key的名字须和申请模板中的变量名一致,多个变量之间以逗号隔开。示例:针对模板“验证码${code},您正在进行${product}身份验证,打死不要告诉别人哦!”,传参时需传入{"code":"1234","product":"alidayu"}
+	 * @return
+	 */
+	public static MessageResult send(String phones, String signName, String smsTemplateCode, JSONObject json){
+		
+		boolean success = true;
+		String msg = "发送成功";
+		
+		TaobaoClient client = new DefaultTaobaoClient(APP_URL, APP_KEY, APP_SECRET);
+		AlibabaAliqinFcSmsNumSendRequest req = new AlibabaAliqinFcSmsNumSendRequest();
+		req.setSmsType(SMS_TYPE);
+		req.setSmsFreeSignName(signName);
+		if(json != null){
+			req.setSmsParamString(json.toString());
+		}
+		req.setRecNum(phones);
+		req.setSmsTemplateCode(smsTemplateCode);
+		AlibabaAliqinFcSmsNumSendResponse rsp;
+		try {
+			rsp = client.execute(req);
+			
+			JSONObject ret = JSONObject.fromObject(rsp.getBody());
+			
+			System.out.println("ret>>>>" + ret);
+			
+			if(ret.containsKey("error_response")){
+				success = false;
+				msg = ret.getJSONObject("error_response").getString("sub_msg");
+			}else if(ret.containsKey("alibaba_aliqin_fc_sms_num_send_response")){
+				
+				JSONObject result = ret.getJSONObject("alibaba_aliqin_fc_sms_num_send_response").getJSONObject("result");
+				
+				if(!result.getBoolean("success")){
+					msg = result.getString("msg");
+				}
+			}else{
+				success = false;
+				msg = ret.toString();
+			}
+		} catch (ApiException e) {
+			success = false;
+			msg = e.getErrMsg();
+		} catch (JSONException ex) {
+			success = false;
+			msg = ex.getMessage();
+		}
+
+		MessageResult retMessage = new MessageResult();
+		
+		retMessage.setMessage(msg);
+		retMessage.setResult(success);
+		
+		return retMessage;
+	}
+
+
+
+	public static String generateNumberString(int length) {
+		StringBuffer sb = new StringBuffer();
+		Random random = new Random();
+		for (int i = 0; i < length; i++) {
+			sb.append(NUMBERCHAR.charAt(random.nextInt(NUMBERCHAR.length())));
+		}
+		return sb.toString();
+	}
+}

+ 70 - 0
src/main/java/com/jpsoft/smart/modules/common/utils/Sign.java

@@ -0,0 +1,70 @@
+package com.jpsoft.smart.modules.common.utils;
+
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Formatter;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+public class Sign {
+
+    public static Map<String, String> sign(String jsapi_ticket, String url) {
+        Map<String, String> ret = new HashMap<String, String>();
+        String nonce_str = create_nonce_str();
+        String timestamp = create_timestamp();
+        String string1;
+        String signature = "";
+
+        //注意这里参数名必须全部小写,且必须有序
+        string1 = "jsapi_ticket=" + jsapi_ticket +
+                  "&noncestr=" + nonce_str +
+                  "&timestamp=" + timestamp +
+                  "&url=" + url;
+        System.out.println(string1);
+
+        try
+        {
+            MessageDigest crypt = MessageDigest.getInstance("SHA-1");
+            crypt.reset();
+            crypt.update(string1.getBytes("UTF-8"));
+            signature = byteToHex(crypt.digest());
+        }
+        catch (NoSuchAlgorithmException e)
+        {
+            e.printStackTrace();
+        }
+        catch (UnsupportedEncodingException e)
+        {
+            e.printStackTrace();
+        }
+
+        ret.put("url", url);
+        ret.put("jsapi_ticket", jsapi_ticket);
+        ret.put("nonceStr", nonce_str);
+        ret.put("timestamp", timestamp);
+        ret.put("signature", signature);
+
+        return ret;
+    }
+
+    private static String byteToHex(final byte[] hash) {
+        Formatter formatter = new Formatter();
+        for (byte b : hash)
+        {
+            formatter.format("%02x", b);
+        }
+        String result = formatter.toString();
+        formatter.close();
+        return result;
+    }
+
+    private static String create_nonce_str() {
+        return UUID.randomUUID().toString();
+    }
+
+    private static String create_timestamp() {
+        return Long.toString(System.currentTimeMillis() / 1000);
+    }
+}

+ 316 - 0
src/main/java/com/jpsoft/smart/modules/common/utils/WechatMessageUtil.java

@@ -0,0 +1,316 @@
+package com.jpsoft.smart.modules.common.utils;
+
+import com.jpsoft.smart.modules.wechat.entity.AccessToken;
+import net.sf.json.JSONObject;
+import org.apache.commons.lang3.StringUtils;
+
+import java.math.BigDecimal;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+
+public class WechatMessageUtil {
+
+
+	
+	public static final String send_template = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN";
+	
+
+
+
+
+	private static final String TEMPLATE_REDIRECT_PRE_URL = "http://wuyeopenlocktest-wecat.sudaonline.net";
+
+
+	
+	
+
+	public static boolean sendBillInfo(String fullName, BigDecimal amount, String openId,
+									   String detailAmount, String propertyName, String billRemark, String billDetailId,String billTemplateId,String appId,String appSecret) {
+
+
+		JSONObject sendData = new JSONObject();
+		
+		JSONObject first = new JSONObject();
+		first.put("value", "您有一个新的账单,点击查看详情!");
+		first.put("color", "#FF0000");
+		
+		JSONObject keyword1 = new JSONObject();
+		keyword1.put("value", fullName);
+		keyword1.put("color", "#173177");
+
+		JSONObject keyword2 = new JSONObject();
+		keyword2.put("value", "¥" + amount.setScale(2) + "元");
+		keyword2.put("color", "#173177");
+
+		JSONObject keyword3 = new JSONObject();
+		keyword3.put("value", detailAmount);
+		keyword3.put("color", "#173177");
+
+
+
+		String remarkStr = "账单来源:" + propertyName;
+		
+		if(StringUtils.isNotBlank(billRemark)){
+			remarkStr = remarkStr + "\n备注:"+ billRemark +"";
+		}
+		
+		JSONObject remark = new JSONObject();
+		remark.put("value", remarkStr);
+		remark.put("color", "#173177");
+		
+		sendData.put("first", first);
+		sendData.put("keyword1", keyword1);
+		sendData.put("keyword2", keyword2);
+		sendData.put("keyword3", keyword3);
+		sendData.put("remark", remark);
+		
+		//w8Zk_VQMFIEVSIBPZid7zSrvHmBdrgnqF76u8PLCZEs cs
+		boolean ret = sendTemplate(sendData, appId,appSecret,billTemplateId,openId, TEMPLATE_REDIRECT_PRE_URL + "/billDetail/" + billDetailId +"payTime=0&payType=bill");
+				
+		return ret;
+	}
+	
+	//
+	public static boolean sendBillPayedMessage(String fullName,String feeName,Date createTime,BigDecimal amount,String openId,String billDetailId,String payedTemplateId,String appId,String appSecret) {
+
+		JSONObject sendData = new JSONObject();
+		
+		JSONObject first = new JSONObject();
+		first.put("value", "账单支付成功!");
+		first.put("color", "#FF0000");
+		
+		JSONObject keyword1 = new JSONObject();
+		keyword1.put("value", fullName);
+		keyword1.put("color", "#173177");
+		
+		JSONObject keyword2 = new JSONObject();
+		keyword2.put("value", feeName);
+		keyword2.put("color", "#173177");
+
+
+		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+
+		JSONObject keyword3 = new JSONObject();
+		keyword3.put("value", sdf.format(createTime));
+		keyword3.put("color", "#173177");
+		
+		JSONObject keyword4 = new JSONObject();
+		
+		keyword4.put("value", "¥" + amount.setScale(2) + "元");
+		keyword4.put("color", "#173177");
+		
+
+		
+
+		
+		String remarkStr = "感谢您的支持,点击查看缴费详情";
+		
+		JSONObject remark = new JSONObject();
+		remark.put("value", remarkStr);
+		remark.put("color", "#173177");
+		
+		sendData.put("first", first);
+		sendData.put("keyword1", keyword1);
+		sendData.put("keyword2", keyword2);
+		sendData.put("keyword3", keyword3);
+		sendData.put("keyword4", keyword4);
+		sendData.put("remark", remark);
+		
+		//w8Zk_VQMFIEVSIBPZid7zSrvHmBdrgnqF76u8PLCZEs cs
+		boolean ret = sendTemplate(sendData,appId,appSecret,payedTemplateId ,openId,TEMPLATE_REDIRECT_PRE_URL + "/billDetail/" + billDetailId +"payTime=1&payType=bill");
+				
+		return ret;
+	}
+	
+	//
+	public static boolean sendScanPayedMessage(String fullName,String feeName,Date createTime,BigDecimal amount,String openId,String independentPayId,String payedTemplateId,String appId,String appSecret) {
+
+		JSONObject sendData = new JSONObject();
+
+		JSONObject first = new JSONObject();
+		first.put("value", "账单支付成功!");
+		first.put("color", "#FF0000");
+
+		JSONObject keyword1 = new JSONObject();
+		keyword1.put("value", fullName);
+		keyword1.put("color", "#173177");
+
+		JSONObject keyword2 = new JSONObject();
+		keyword2.put("value", feeName);
+		keyword2.put("color", "#173177");
+
+
+		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+
+		JSONObject keyword3 = new JSONObject();
+		keyword3.put("value", sdf.format(createTime));
+		keyword3.put("color", "#173177");
+
+		JSONObject keyword4 = new JSONObject();
+
+		keyword4.put("value", "¥" + amount.setScale(2) + "元");
+		keyword4.put("color", "#173177");
+
+
+
+
+
+		String remarkStr = "感谢您的支持,点击查看缴费详情";
+
+		JSONObject remark = new JSONObject();
+		remark.put("value", remarkStr);
+		remark.put("color", "#173177");
+
+		sendData.put("first", first);
+		sendData.put("keyword1", keyword1);
+		sendData.put("keyword2", keyword2);
+		sendData.put("keyword3", keyword3);
+		sendData.put("keyword4", keyword4);
+		sendData.put("remark", remark);
+
+		boolean ret = sendTemplate(sendData,appId,appSecret,payedTemplateId ,openId,TEMPLATE_REDIRECT_PRE_URL + "/billDetail/" + independentPayId +"payTime=1&payType=wechat");
+
+		return ret;
+	}
+	
+	/**
+	 * 发送通知信息
+	 * @param noticeName 通知名称名称
+	 * @param noticeDetailId 通知详情ID
+	 * @param openId 发送人
+	 * @return
+	 */
+	public static boolean sendNoticeMessage(String noticeName,String content,String openId,String noticeDetailId,String noticeTemplateId,String appId,String appSecret) {
+
+
+		JSONObject sendData = new JSONObject();
+		String finallyContent = getContent(content);
+		JSONObject first = new JSONObject();
+		first.put("value", "您好,园区通知如下:");
+		first.put("color", "#173177");
+		
+		JSONObject keyword1 = new JSONObject();
+		keyword1.put("value", noticeName);
+		keyword1.put("color", "#173177");
+		
+
+		
+		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+		
+		JSONObject keyword2 = new JSONObject();
+		keyword2.put("value", sdf.format(new Date()));
+		keyword2.put("color", "#173177");
+		
+		JSONObject keyword3 = new JSONObject();
+		keyword3.put("value", finallyContent);
+		keyword3.put("color", "#173177");
+		
+		JSONObject remark = new JSONObject();
+		remark.put("value", "点击查看详情");
+		remark.put("color", "#173177");
+		
+		sendData.put("first", first);
+		sendData.put("keyword1", keyword1);
+		sendData.put("keyword2", keyword2);
+		sendData.put("keyword3", keyword3);
+		sendData.put("remark", remark);
+		
+		//noticeDetailId
+		boolean ret = sendTemplate(sendData,appId,appSecret,noticeTemplateId ,openId, TEMPLATE_REDIRECT_PRE_URL + "/#/noticeInfo/" + noticeDetailId);
+				
+		return ret;
+	}
+	
+	/**
+	 * 微信发送模版
+	 * @param sendData 发送数据
+	 * @param templateId 模版Id
+	 * @param openId 发送人
+	 * @param url 详情跳转地址
+	 * @return
+	 */
+	private static boolean sendTemplate(JSONObject sendData,String appId,String appSecret,String templateId,String openId,String url){
+		
+		boolean result = false;
+
+
+		AccessToken accessToken = WeixinUtil.getAccessToken(appId, appSecret);
+		
+		if(accessToken != null){
+			//发送模版内容
+			String sendTemplateUrl = send_template.replace("ACCESS_TOKEN", accessToken.getToken());
+			
+			JSONObject sendTemplateData = new JSONObject();
+			
+			sendTemplateData.put("touser", openId);
+			sendTemplateData.put("template_id", templateId);
+			sendTemplateData.put("url", url);
+			sendTemplateData.put("data", sendData);
+			
+			System.out.println("模版发送Id>>>>" + templateId + ">>>模版发送数据>>>>>" + sendTemplateData.toString());
+			
+			String sendTemplateRet =  HttpConnectionUtil.requestByPost(sendTemplateUrl, sendTemplateData.toString());
+			
+			System.out.println("模版发送返回数据>>>>>" + sendTemplateRet);
+			
+			if(StringUtils.isNotBlank(sendTemplateRet)){
+				JSONObject sendTemplateJson = JSONObject.fromObject(sendTemplateRet);
+				
+				if("0".equals(sendTemplateJson.getString("errcode"))){
+					//发送成功
+					result = true;
+				}
+			}
+		}
+		
+		return result;
+	}
+
+	public static String getContent(String content){
+		String finallyContent = content;
+		String regex="<p.*?>(.*?)</p>";
+		Pattern p =Pattern.compile(regex);
+		Matcher m=p.matcher(content);
+		while(m.find()){
+			finallyContent =  m.group(1);
+		}
+
+
+
+		return finallyContent;
+	}
+	
+
+		
+	public static void main(String[] args) {
+		/*AccessToken at = WeixinUtil.getAccessToken(APP_ID, APP_SECRET,"061iw9gy1sZ1dg09dqhy1ae3gy1iw9gq");
+		
+		System.out.println(at.getOpenid());*/
+		
+		/*for (int i = 0; i < 1; i++) {
+			doorMessage("1111", 2,"2018-09-22 09:00-12:00", 1, "2222222", "3333333", "oiFbN0p9jKphExeGIa3HtyL9HjqM");
+		}*/
+		
+		//orderConfirmMessage("12312321312", 1111, DEFAULT_OPEN_ID);
+		//sendBillInfo("测试", "测试", "荆鹏创业", "张三", new BigDecimal(1), "o64fbt6TTUcqLC_tyVJ60I5kzWVc", "1111", new Date());
+		//sendBillPayedMessage("测试", "荆鹏创业", "张三", new BigDecimal(1), "o64fbt6TTUcqLC_tyVJ60I5kzWVc", "11111", new Date());
+		//sendScanPayedMessage("测试", "荆鹏创业", "张三11111", new BigDecimal(1), "o64fbt6TTUcqLC_tyVJ60I5kzWVc", "11111", new Date());
+	/*	sendNoticeMessage("测试", "sdfsdfasfasdfafasdfasdf", "oOlFd1BUR6Fi2ayBWUeou81G8ZD4", "2222","9JKu9t9uTPHL1siIm7WatOJ1KXGolzEPlnmqIbckTUM","wx41ac6791b9dbcf52","3e3d47c5f132d4b47636a536d503fbd4");
+*/
+	/*	sendBillInfo("1栋-1单元-101",new BigDecimal("0.01"),"oOlFd1BUR6Fi2ayBWUeou81G8ZD4",
+				"物业费","小鹏物业","测试","9e52c923-2179-4526-a108-32becc9aa1d0","vVraOPl4OyNVWDGz6XYlJqRb7qGjjcyJdnVi5HWmFRI","wx41ac6791b9dbcf52","3e3d47c5f132d4b47636a536d503fbd4");*/
+
+		/*sendBillPayedMessage("1栋-1单元-101","物业费",new Date(),new BigDecimal("0.01"),"oOlFd1BUR6Fi2ayBWUeou81G8ZD4","33e7e5e6-5b38-45f5-9ccf-c7ef21978a5b","kbx5u70nzo7PklTVl4B1xvRffksrUtXxnDll8ggEKlo","wx41ac6791b9dbcf52","3e3d47c5f132d4b47636a536d503fbd4");*/
+
+
+		getContent("<p>内容</p>");
+
+	}
+
+
+	
+	
+}

+ 139 - 0
src/main/java/com/jpsoft/smart/modules/common/utils/WeixinUtil.java

@@ -0,0 +1,139 @@
+package com.jpsoft.smart.modules.common.utils;
+
+import com.jpsoft.smart.modules.wechat.entity.AccessToken;
+import com.jpsoft.smart.modules.wechat.vo.UserInfo;
+import net.sf.json.JSONException;
+import net.sf.json.JSONObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.UnsupportedEncodingException;
+
+/**
+ * 公众平台通用接口工具类
+ * 
+ * @author lt
+ * @date 2013-08-09
+ */
+public class WeixinUtil {
+	private static Logger log = LoggerFactory.getLogger(WeixinUtil.class);
+	
+	// 获取access_token的接口地址(GET) 限200(次/天)
+	public final static String access_token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
+
+	//获取微信的code
+	public static String code = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect";
+	public static String getCodeRequest(String appid, String url,String scope){
+        String result = null;
+        String url_encode = "";
+        try {
+			url_encode = java.net.URLEncoder.encode(url, "utf-8");
+		} catch (UnsupportedEncodingException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+        result  = code.replace("APPID", appid).replace("REDIRECT_URI",url_encode).replace("SCOPE", scope);
+        return result;
+    }
+	
+	//通过code换取网页授权access_token
+	public static String accessTokenurl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
+	public static AccessToken getAccessToken(String appid, String appsecret,String code) throws Exception {
+        AccessToken accessToken = null;
+        String formatUrl = accessTokenurl.replace("APPID", appid).replace("SECRET",appsecret).replace("CODE", code);
+        JSONObject json  = HttpConnectionUtil.httpRequest(formatUrl, "GET", null);
+        if (!json.isNullObject() && !json.isEmpty()) {
+			try {
+				accessToken = new AccessToken();
+				accessToken.setToken(json.getString("access_token"));
+				accessToken.setExpiresIn(json.getInt("expires_in"));
+				accessToken.setOpenid(json.getString("openid"));
+				accessToken.setScope(json.getString("scope"));
+			} catch (Exception e) {
+				
+				// 获取token失败
+				log.error("获取token失败,返回结果result={}", json);
+				if (json.getString("errcode").equals("40163")){
+					throw new Exception("请重新扫码");
+
+				}
+
+			}
+		}
+        return accessToken;
+    }
+	
+	public static String jsAccessTokenUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";
+	public static String getJsAPI(String accessToken){
+		String formatUrl = jsAccessTokenUrl.replace("ACCESS_TOKEN", accessToken);
+        JSONObject json  = HttpConnectionUtil.httpRequest(formatUrl, "GET", null);
+        
+        if (!json.isNullObject() && !json.isEmpty()) {
+			try {
+				return json.getString("ticket");
+			} catch (Exception e) {
+				// 获取token失败
+				log.error("获取jsAPI失败,返回结果result={}", json);
+			}
+		}
+        
+        return null;
+	}
+	
+	/**
+	 * 获取access_token
+	 * 
+	 * @param appid 凭证
+	 * @param appsecret 密钥
+	 * @return
+	 */
+	public static AccessToken getAccessToken(String appid, String appsecret) {
+		AccessToken accessToken = null;
+
+		String requestUrl = access_token_url.replace("APPID", appid).replace("APPSECRET", appsecret);
+		JSONObject jsonObject =HttpConnectionUtil.httpRequest(requestUrl, "GET", null);
+		// 如果请求成功
+		if (null != jsonObject) {
+			try {
+				accessToken = new AccessToken();
+				accessToken.setToken(jsonObject.getString("access_token"));
+				accessToken.setExpiresIn(jsonObject.getInt("expires_in"));
+				//accessToken.setOpenid(jsonObject.getString("openid"));
+			} catch (JSONException e) {
+				accessToken = null;
+				// 获取token失败
+				log.error("获取token失败 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));
+			}
+		}
+		return accessToken;
+	}
+	
+	// 获取用户信息
+	public static String user_info_url = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";
+	public static String subscribe_user_info_url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN ";
+	
+	public static UserInfo getUserInfo(String openid, String accessToken) {
+		// 拼装url
+		String url = user_info_url.replace("ACCESS_TOKEN", accessToken).replace("OPENID", openid);;
+		
+		JSONObject jsonObject = HttpConnectionUtil.httpRequest(url, "GET", null);
+		
+		UserInfo userInfo = null;
+		 if (null != jsonObject) {
+				try {
+					userInfo = new UserInfo();
+					userInfo.setOpenid(jsonObject.getString("openid").replaceAll("\"", ""));
+					
+					userInfo.setNickname(jsonObject.getString("nickname").replaceAll("\"", ""));
+					userInfo.setCity(jsonObject.getString("city").replaceAll("\"", ""));
+					userInfo.setProvince(jsonObject.getString("province").replaceAll("\"", ""));
+					userInfo.setCountry(jsonObject.getString("country").replaceAll("\"", ""));
+					userInfo.setHeadimgurl(jsonObject.getString("headimgurl").replaceAll("\"", ""));
+				} catch (JSONException e) {
+					// 获取token失败
+					log.error("获取token失败 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));
+				}
+			}
+		return userInfo;
+	}
+}

+ 631 - 0
src/main/java/com/jpsoft/smart/modules/wechat/controller/WxController.java

@@ -0,0 +1,631 @@
+package com.jpsoft.smart.modules.wechat.controller;
+
+import com.alibaba.fastjson.JSONObject;
+import com.jpsoft.smart.modules.base.entity.InformationInfo;
+import com.jpsoft.smart.modules.base.service.InformationInfoService;
+import com.jpsoft.smart.modules.base.service.OwnerInfoService;
+import com.jpsoft.smart.modules.common.dto.MessageResult;
+import com.jpsoft.smart.modules.common.service.impl.RedisServiceImpl;
+import com.jpsoft.smart.modules.common.utils.ApiUtil;
+import com.jpsoft.smart.modules.common.utils.Generator.CaptchaUtilA;
+import com.jpsoft.smart.modules.common.utils.Generator.CircleCaptchaA;
+import com.jpsoft.smart.modules.common.utils.SMSUtil;
+import com.jpsoft.smart.modules.common.utils.Sign;
+import com.jpsoft.smart.modules.common.utils.WeixinUtil;
+import com.jpsoft.smart.modules.pay.properties.WxPayProperties;
+import com.jpsoft.smart.modules.wechat.entity.AccessControl;
+import com.jpsoft.smart.modules.wechat.entity.AccessToken;
+import com.jpsoft.smart.modules.wechat.service.IAccessControlService;
+import com.jpsoft.smart.modules.wechat.vo.BindFaceVo;
+import com.jpsoft.smart.modules.wechat.vo.BindPhoneVo;
+import com.jpsoft.smart.modules.wechat.vo.RepairsVo;
+import com.jpsoft.smart.modules.wechat.vo.UserInfo;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.*;
+
+/**
+ * @author 墨鱼_mo
+ * @date 2019-12-3 15:08
+ */
+
+@Slf4j
+@RequestMapping("/wechat")
+@RestController
+public class WxController {
+
+
+    @Autowired
+    private ApiUtil apiUtil;
+
+    @Autowired
+    private RedisServiceImpl redisService;
+
+    @Autowired
+    private OwnerInfoService ownerInfoService;
+
+    @Autowired
+    private WxPayProperties wxPayProperties;
+
+    @Autowired
+    private IAccessControlService accessControlService;
+
+    @Autowired
+    private InformationInfoService informationInfoService;
+
+
+    @ApiOperation(value = "获取微信配置")
+    @GetMapping(value = "/getConfig")
+    public MessageResult getConfig(String url) {
+
+        int code = 200;
+        String message = "获取成功";
+        Object data = "";
+        boolean result = true;
+
+        try {
+            AccessToken token = WeixinUtil.getAccessToken(wxPayProperties.getAppId(), wxPayProperties.getAppSecret());
+
+            Map<String, String> wxMap = Sign.sign(WeixinUtil.getJsAPI(token.getToken()), url);
+
+            wxMap.put("appId", wxPayProperties.getAppId());
+
+            HashMap<String, Object> dataMap = new HashMap<String, Object>();
+
+            dataMap.put("wxConfig", wxMap);
+
+            data = dataMap;
+        } catch (Exception ex) {
+            code = 500;
+            result = false;
+            message = "系统错误";
+        }
+
+        return new MessageResult(result, message, data, code);
+    }
+
+    @ApiOperation(value = "获取微信code")
+    @PostMapping(value = "findWechatUrl")
+    public MessageResult findWechatUrl(@RequestBody String url) {
+
+        String newpath = WeixinUtil.getCodeRequest(wxPayProperties.getAppId(), url, "snsapi_userinfo");
+
+        HashMap<String, Object> dataMap = new HashMap<String, Object>();
+
+        dataMap.put("wechatUrl", newpath);
+
+        return new MessageResult(true, "获取成功", dataMap, 200);
+    }
+
+    @ApiOperation(value = "获取公众号用户信息")
+    @GetMapping(value = "findUserInfo/{code}")
+    public MessageResult findUserInfo(@PathVariable String code) {
+        try {
+            System.out.println(code);
+
+
+            AccessToken at = WeixinUtil.getAccessToken(wxPayProperties.getAppId(), wxPayProperties.getAppSecret(), code);
+
+            if (at != null && StringUtils.isNotBlank(at.getOpenid())) {
+                String openId = at.getOpenid();
+                System.out.println("openId:" + openId);
+
+                UserInfo userInfo = WeixinUtil.getUserInfo(openId, at.getToken());
+
+                HashMap<String, Object> dataMap = new HashMap<String, Object>();
+
+                dataMap.put("userInfo", userInfo);
+
+                return new MessageResult(true, "获取微信信息成功", userInfo, 200);
+
+            } else {
+                return new MessageResult(false, "获取微信信息失败", "", 400);
+            }
+
+        } catch (Exception ex) {
+            ex.printStackTrace();
+            return new MessageResult(false, "系统错误", "", 500);
+        }
+    }
+
+    @GetMapping(value = "getAppId/{id}")
+    @ResponseBody
+    public MessageResult getAppId(@PathVariable("id") String id) {
+
+        int code = 200;
+        String message = "获取成功";
+        Object data = "";
+        boolean result = true;
+
+        try {
+
+                HashMap<String, Object> wxMap = new HashMap<>();
+
+                wxMap.put("appId", wxPayProperties.getAppId());
+
+                HashMap<String, Object> dataMap = new HashMap<String, Object>();
+
+                dataMap.put("wxConfig", wxMap);
+
+                data = dataMap;
+
+        } catch (Exception ex) {
+            code = 500;
+            message = "系统错误";
+            result = false;
+        }
+
+        return new MessageResult(result, message, data, code);
+    }
+
+    @GetMapping(value = "/findAccessControlByOpenId/{openId}")
+    @ResponseBody
+    public MessageResult findAccessControlByOpenId(@PathVariable(name = "openId", value = "") String openId) {
+
+        int code = 200;
+        String message = "查询成功";
+        Object data = "";
+        boolean result = true;
+
+        if (StringUtils.isNotBlank(openId)) {
+
+            AccessControl accessControl = accessControlService.findByOpenId(openId);
+
+            if (accessControl == null) {
+                code = 400;
+                message = "用户信息不存在";
+                result = false;
+            } else {
+
+
+                HashMap<String, Object> dataMap = new HashMap<String, Object>();
+
+                dataMap.put("accessControl", accessControl);
+
+                data = dataMap;
+            }
+
+
+        } else {
+            code = 400;
+            message = "用户信息不存在";
+            result = false;
+
+        }
+
+        return new MessageResult(result, message, data,code);
+    }
+
+
+    @ApiOperation(value = "获取门禁token")
+    @PostMapping("/getApiToken")
+    public MessageResult getApiToken() {
+        boolean result = true;
+        String message = "";
+        Object data = "";
+
+        try {
+
+            String token = apiUtil.getApiToken();
+            if (StringUtils.isNotBlank(token)) {
+                result = true;
+                message = "获取token成功";
+                redisService.put("apiToken", "apiToken", token, 7200L);
+            }
+
+
+        } catch (Exception e) {
+            e.printStackTrace();
+            result = false;
+            message = "获取token失败";
+        }
+
+        return new MessageResult(result, message, data, 200);
+    }
+
+    @ApiOperation(value = "公众号开门")
+    @GetMapping(value = "/openDoor/{openId}")
+    public MessageResult openDoor(@PathVariable(name = "openId", value = "") String openId) {
+
+        int code = 200;
+        String message = "开锁成功";
+        Object data = "";
+
+        if (StringUtils.isNotBlank(openId)) {
+            AccessControl accessControl = accessControlService.findByOpenId(openId);
+            if (accessControl == null) {
+                code = 401;
+                message = "请先绑定用户";
+            } else {
+
+
+                String apiToken = (String) redisService.get("apiToken", "apiToken");
+
+                if (!apiUtil.testApiToken(apiToken, "215301")) {
+                    apiToken = apiUtil.getApiToken();
+                }
+                JSONObject resultJSON = apiUtil.httpRequest("https://api.parkline.cc/api/devicecgi", apiToken, "01", "215301", "01", "", "");
+                String resultCode = resultJSON.getString("code");
+
+
+                if (!resultCode.equals("0")) {
+                    code = Integer.parseInt(resultCode);
+                    message = resultJSON.getString("msg");
+                }
+            }
+
+
+        } else {
+            code = 400;
+            message = "开锁失败";
+        }
+
+        return new MessageResult(true, message, "", code);
+    }
+
+
+    @ApiOperation(value = "获取图片验证码信息")
+    @GetMapping("/getVerifyPic")
+    public MessageResult getVerifyPic(String openId, HttpServletResponse response) {
+        int code = 200;
+        String message = "获取验证码成功";
+        Object data = "";
+        boolean result = true;
+
+        try {
+
+            if (StringUtils.isBlank(openId)) {
+                throw new Exception("openId为空");
+            }
+
+            CircleCaptchaA captcha = CaptchaUtilA.createCircleCaptcha(200, 100, 4, 0);
+            captcha.write(response.getOutputStream());
+            String verifyPic = captcha.getCode();
+            redisService.put("code", openId, verifyPic, 120);
+
+
+            response.getOutputStream().close();
+
+        } catch (Exception e) {
+            e.printStackTrace();
+            code = 500;
+            message = e.getMessage();
+            result = false;
+        }
+
+        return new MessageResult(result, message, data, code);
+    }
+
+    @ApiOperation(value = "获取短信验证码")
+    @PostMapping("/getVerifyCode")
+    public MessageResult getVerifyCode(@RequestBody BindPhoneVo bindPhoneVo) {
+        int code = 200;
+        String message = "获取验证码成功";
+        Object data = "";
+        boolean result = true;
+
+        try {
+
+            if (StringUtils.isBlank(bindPhoneVo.getOpenId())) {
+                throw new Exception("openId为空");
+            }
+
+
+            if (StringUtils.isBlank(bindPhoneVo.getName()) || StringUtils.isBlank(bindPhoneVo.getPhoneNum())) {
+                throw new Exception("业主姓名和手机号必填");
+            }
+            if (StringUtils.isBlank(bindPhoneVo.getVerifyPicCode())) {
+                throw new Exception("图片验证码为空");
+            }
+
+            String verifyPicCode = (String) redisService.get("code", bindPhoneVo.getOpenId());
+            if (StringUtils.isBlank(verifyPicCode)) {
+                throw new Exception("图片验证码过期");
+            }
+            if (!verifyPicCode.equals(bindPhoneVo.getVerifyPicCode())) {
+                throw new Exception("图片验证码错误");
+            }
+
+
+            List<Map> ownerInfoList = ownerInfoService.findByTel(bindPhoneVo.getPhoneNum());
+            if (ownerInfoList.size()<=0){
+                throw new Exception("人员信息未录入,请联系物业公司");
+            }
+            AccessControl accessControl = accessControlService.findByOwnerId(ownerInfoList.get(0).get("id").toString());
+
+
+            if (accessControl != null) {
+                throw new Exception("此手机号已被绑定");
+            }
+
+
+            String apiToken = (String) redisService.get("apiToken", "apiToken");
+
+            if (!apiUtil.testApiToken(apiToken, "215301")) {
+                apiToken = apiUtil.getApiToken();
+            }
+            JSONObject resultJSON = apiUtil.httpRequest("https://api.parkline.cc/api/facecgi", apiToken, "101", "", "", bindPhoneVo.getPhoneNum(), "");
+            if (!resultJSON.getString("code").equals("100101")) {
+                code = resultJSON.getIntValue("code");
+                if (code == 100100) {
+                    message = "未找到业主信息,请联系物业";
+                } else {
+                    message = resultJSON.getString("msg");
+                }
+
+                return new MessageResult(result, message, data, code);
+            } else {
+                JSONObject dataJSON = resultJSON.getJSONObject("data");
+                String name = dataJSON.getString("name");
+                if (!bindPhoneVo.getName().equals(name)) {
+                    throw new Exception("业主姓名有误");
+                }
+            }
+
+            String verifyCode = SMSUtil.generateNumberString(6);
+            JSONObject verifyCodeJSON = new JSONObject();
+            verifyCodeJSON.put("code", verifyCode);
+            MessageResult rmg = SMSUtil.send(bindPhoneVo.getPhoneNum(), "SMS_49390047", verifyCodeJSON.toString());
+
+            if (rmg.isResult()) {
+
+                redisService.put("code", bindPhoneVo.getPhoneNum(), verifyCode, 120);
+
+            }
+
+
+        } catch (Exception e) {
+            e.printStackTrace();
+            code = 400;
+            message = e.getMessage();
+            result = false;
+        }
+
+        return new MessageResult(result, message, data, code);
+    }
+
+    @ApiOperation(value = "公众号绑定住户手机")
+    @PostMapping(value = "/bindPhoneNumAndOpenId")
+    public MessageResult bindPhoneNumAndOpenId(@RequestBody BindPhoneVo bindPhoneVo) {
+
+        int code = 200;
+        String message = "绑定成功";
+        Object data = "";
+        boolean result = true;
+
+        try {
+
+
+            if (StringUtils.isBlank(bindPhoneVo.getPhoneNum()) || StringUtils.isBlank(bindPhoneVo.getOpenId()) || StringUtils.isBlank(bindPhoneVo.getVerifyCode())) {
+                throw new Exception("参数错误");
+            }
+
+            //   else {
+
+
+            String verifyCode = (String) redisService.get("code", bindPhoneVo.getPhoneNum());
+            if (StringUtils.isBlank(verifyCode)) {
+                throw new Exception("验证码过期");
+            }
+            if (!verifyCode.equals(bindPhoneVo.getVerifyCode())) {
+                throw new Exception("验证码错误");
+            }
+
+
+            AccessControl accessControl1 = accessControlService.findByOpenId(bindPhoneVo.getOpenId());
+            if (accessControl1 != null) {
+                throw new Exception("此微信号已绑定手机号");
+            }
+
+
+            String apiToken = (String) redisService.get("apiToken", "apiToken");
+
+            if (!apiUtil.testApiToken(apiToken, "215301")) {
+                apiToken = apiUtil.getApiToken();
+            }
+
+            JSONObject resultJSON = apiUtil.httpRequest("https://api.parkline.cc/api/facecgi", apiToken, "101", "", "", bindPhoneVo.getPhoneNum(), "");
+            if (!resultJSON.getString("code").equals("100101")) {
+                code = resultJSON.getIntValue("code");
+                System.out.println(code);
+                if (code == 100100) {
+                    message = "未找到业主信息,请联系物业";
+                } else {
+                    message = resultJSON.getString("msg");
+                }
+
+
+            } else {
+                net.sf.json.JSONObject dataJSON = net.sf.json.JSONObject.fromObject(resultJSON.getString("data"));
+                List<Map> ownerInfoList = ownerInfoService.findByTel(bindPhoneVo.getPhoneNum());
+                AccessControl accessControl2 = new AccessControl();
+                accessControl2.setId(UUID.randomUUID().toString());
+                accessControl2.setOwnerId(ownerInfoList.get(0).get("id").toString());
+                accessControl2.setOpenId(bindPhoneVo.getOpenId());
+                accessControl2.setBindTime(new Date());
+                accessControl2.setBindFace(false);
+                accessControl2.setCreateTime(new Date());
+                accessControlService.save(accessControl2);
+            }
+
+
+            //    }
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+            code = 400;
+            message = e.getMessage();
+            result = false;
+
+        }
+
+
+        return new MessageResult(result, message, data, code);
+    }
+
+    @ApiOperation(value = "微信端上传住户人脸")
+    @PostMapping(value = "/bindFace")
+    public MessageResult bindFace(@RequestBody BindFaceVo bindFaceVo) {
+
+        int code = 200;
+        String message = "提交成功";
+        Object data = "";
+        boolean result = true;
+
+
+        List<Map> ownerList = ownerInfoService.findByTel(bindFaceVo.getPhoneNum());
+        if (ownerList.size() <= 0) {
+            return new MessageResult(false, "未找到用户信息,请联系物业", data, 400);
+        }
+
+        AccessControl accessControl = accessControlService.findByOwnerId(ownerList.get(0).get("id").toString());
+        if (accessControl == null) {
+            return new MessageResult(false, "请先进行微信绑定", data, 400);
+        }
+
+        if (StringUtils.isBlank(bindFaceVo.getPhoneNum()) || StringUtils.isBlank(bindFaceVo.getFiledata())) {
+            code = 400;
+            message = "参数错误";
+            return new MessageResult(false, message, data, code);
+        }
+
+        String apiToken = (String) redisService.get("apiToken", "apiToken");
+
+        if (!apiUtil.testApiToken(apiToken, "215301")) {
+            apiToken = apiUtil.getApiToken();
+        }
+
+        JSONObject resultJSON = apiUtil.httpRequest("https://api.parkline.cc/api/facecgi", apiToken, "300", "215301", "01", bindFaceVo.getPhoneNum(), bindFaceVo.getFiledata());
+        if (!resultJSON.getString("code").equals("100101")) {
+            code = resultJSON.getInteger("code");
+            if (code == 100100) {
+                message = "未找到业主信息,请联系物业";
+            } else {
+                message = resultJSON.getString("msg");
+            }
+
+
+        } else if (resultJSON.getString("code").equals("1")) {
+            accessControl.setBindFace(true);
+            accessControlService.update(accessControl);
+        }
+        return new MessageResult(result, message, "", code);
+    }
+
+    @ApiOperation(value = "微信端报修或投诉列表")
+    @PostMapping(value = "/reportAndRepairsList")
+    @ResponseBody
+    public MessageResult reportAndRepairsList(@RequestBody RepairsVo repairsVo) {
+
+        int code = 200;
+        String message = "查询成功";
+        Object data = "";
+        boolean result = true;
+
+        if (StringUtils.isBlank(repairsVo.getOpenId())) {
+            code = 400;
+            message = "openId为空";
+            return new MessageResult(false, message, "", code);
+        }
+        if (repairsVo.getType() == null) {
+            return new MessageResult(false, "类型不能为空", "", 400);
+        }
+
+        AccessControl accessControl = accessControlService.findByOpenId(repairsVo.getOpenId());
+        if (accessControl == null) {
+            return new MessageResult(false, "此微信还未绑定住户", "", 400);
+        }
+        List<InformationInfo> informationInfoList = informationInfoService.findByOwnerIdAndType(accessControl.getOwnerId(),repairsVo.getType());
+
+        data = informationInfoList;
+
+
+        return new MessageResult(result, message, data, code);
+    }
+
+    @ApiOperation(value = "微信端提交报修或投诉")
+    @PostMapping(value = "/reportAndRepairs")
+    @ResponseBody
+    public MessageResult reportAndRepairs(@RequestBody RepairsVo repairsVo) {
+
+        int code = 200;
+        String message = "提交成功";
+        Object data = "";
+        boolean result = true;
+
+        try{
+
+
+        if (StringUtils.isBlank(repairsVo.getOpenId()) || StringUtils.isBlank(repairsVo.getContent())) {
+            throw new Exception("参数错误");
+        }
+        if (repairsVo.getType() == null) {
+            throw new Exception("类型不能为空");
+        }
+
+        AccessControl accessControl = accessControlService.findByOpenId(repairsVo.getOpenId());
+        if (accessControl == null) {
+            throw new Exception("此微信还未绑定住户");
+        }
+        InformationInfo informationInfo = new InformationInfo();
+        informationInfo.setId(UUID.randomUUID().toString());
+        informationInfo.setDelFlag(false);
+        informationInfo.setCreateBy(repairsVo.getOpenId());
+        informationInfo.setCreateTime(new Date());
+        informationInfo.setStatus("0");
+        informationInfo.setContent(repairsVo.getContent());
+        informationInfo.setOwnerId(accessControl.getOwnerId());
+        informationInfo.setType(repairsVo.getType());
+
+        informationInfoService.insert(informationInfo);
+
+        }catch (Exception e){
+            e.printStackTrace();
+            log.error(e.getMessage(),e);
+            message = e.getMessage();
+            result = false;
+            code = 400;
+
+        }
+        return new MessageResult(result, message, data, code);
+    }
+
+
+    @ApiOperation(value = "根据报修或投诉id获取内容")
+    @GetMapping(value = "/reportAndRepairsDetail")
+    @ResponseBody
+    public MessageResult reportAndRepairsDetail(String id) {
+
+        int code = 200;
+        String message = "查询成功";
+        Object data = "";
+        boolean result = true;
+
+        try{
+
+
+
+        if (id == null) {
+            throw new Exception("id为空");
+        }
+
+
+        InformationInfo informationInfo = informationInfoService.get(id);
+        data = informationInfo;
+
+
+        }catch (Exception e){
+            e.printStackTrace();
+            log.error(e.getMessage(),e);
+            message = e.getMessage();
+            code = 400;
+            result = false;
+        }
+        return new MessageResult(result, message, data, code);
+    }
+
+}

+ 20 - 0
src/main/java/com/jpsoft/smart/modules/wechat/dao/AccessContorlDAO.java

@@ -0,0 +1,20 @@
+package com.jpsoft.smart.modules.wechat.dao;
+
+import com.jpsoft.smart.modules.wechat.entity.AccessControl;
+import org.springframework.stereotype.Repository;
+
+/**
+ * @author 墨鱼_mo
+ * @date 2019-12-11 10:27
+ */
+@Repository
+public interface AccessContorlDAO {
+
+    AccessControl findByOpenId(String openId);
+
+    void save(AccessControl accessControl);
+
+    void update(AccessControl accessControl);
+
+    AccessControl findByOwner(String id);
+}

+ 62 - 0
src/main/java/com/jpsoft/smart/modules/wechat/entity/AccessControl.java

@@ -0,0 +1,62 @@
+package com.jpsoft.smart.modules.wechat.entity;
+
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * @author 墨鱼_mo
+ * @date 2019-12-11 9:55
+ */
+@Data
+public class AccessControl {
+
+    /**
+     * id
+     */
+    private String id;
+
+    /**
+     * 业主id
+     */
+    private String ownerId;
+
+    /**
+     * openId
+     */
+    private String openId;
+
+    /**
+     * 绑定时间
+     */
+    private Date bindTime;
+
+    /**
+     * 是否绑定人脸
+     */
+    private Boolean bindFace;
+
+
+    /**
+     * 创建时间
+     */
+    private Date createTime;
+
+
+    /**
+     * 创建人
+     */
+    private String createBy;
+
+    /**
+     * 更新时间
+     */
+    private Date updateTime;
+
+    /**
+     * 更新人
+     */
+    private String updateBy;
+
+
+}

+ 29 - 0
src/main/java/com/jpsoft/smart/modules/wechat/entity/AccessToken.java

@@ -0,0 +1,29 @@
+package com.jpsoft.smart.modules.wechat.entity;
+
+import lombok.Data;
+
+/**
+ * @author 墨鱼_mo
+ * @date 2019-12-11 15:29
+ */
+@Data
+public class AccessToken {
+
+    /**
+     * 获取到的凭证
+     */
+    private String token;
+    /**
+     * 凭证有效时间,单位:秒
+     */
+    private int expiresIn;
+    /**
+     * 用户唯一标识
+     */
+    private String openid;
+
+    /**
+     * 类型
+     */
+    private String scope;
+}

+ 36 - 0
src/main/java/com/jpsoft/smart/modules/wechat/service/IAccessControlService.java

@@ -0,0 +1,36 @@
+package com.jpsoft.smart.modules.wechat.service;
+
+import com.jpsoft.smart.modules.wechat.entity.AccessControl;
+
+/**
+ * @author 墨鱼_mo
+ * @date 2019-12-11 10:24
+ */
+public interface IAccessControlService {
+
+    /**
+     * 根据openid查询绑定记录
+     * @param openId
+     * @return
+     */
+    AccessControl findByOpenId(String openId);
+
+    /**
+     * 根据ownerid查询绑定记录
+     * @param id
+     * @return
+     */
+    AccessControl findByOwnerId(String id);
+
+    /**
+     * 保存绑定记录
+     * @param accessControl
+     */
+    void save(AccessControl accessControl);
+
+    /**
+     * 更新绑定信息
+     * @param accessControl
+     */
+    void update(AccessControl accessControl);
+}

+ 44 - 0
src/main/java/com/jpsoft/smart/modules/wechat/service/impl/AccessControlServiceImpl.java

@@ -0,0 +1,44 @@
+package com.jpsoft.smart.modules.wechat.service.impl;
+
+import com.jpsoft.smart.modules.wechat.dao.AccessContorlDAO;
+import com.jpsoft.smart.modules.wechat.entity.AccessControl;
+import com.jpsoft.smart.modules.wechat.service.IAccessControlService;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+
+/**
+ * @author 墨鱼_mo
+ * @date 2019-12-3 15:55
+ */
+@Service
+public class AccessControlServiceImpl implements IAccessControlService {
+
+    @Resource(name="accessContorlDAO")
+    private AccessContorlDAO accessContorlDAO;
+
+
+
+
+    @Override
+    public AccessControl findByOpenId(String openId) {
+        return accessContorlDAO.findByOpenId(openId);
+    }
+
+    @Override
+    public AccessControl findByOwnerId(String id) {
+        return accessContorlDAO.findByOwner(id);
+    }
+
+    @Override
+    public void save(AccessControl accessControl) {
+        accessContorlDAO.save(accessControl);
+    }
+
+    @Override
+    public void update(AccessControl accessControl) {
+        accessContorlDAO.update(accessControl);
+    }
+
+
+}

+ 15 - 0
src/main/java/com/jpsoft/smart/modules/wechat/vo/BindFaceVo.java

@@ -0,0 +1,15 @@
+package com.jpsoft.smart.modules.wechat.vo;
+
+import lombok.Data;
+
+/**
+ * @author 墨鱼_mo
+ * @date 2019-9-4 12:39
+ */
+@Data
+public class BindFaceVo {
+
+    private String phoneNum;
+
+    private String filedata;
+}

+ 39 - 0
src/main/java/com/jpsoft/smart/modules/wechat/vo/BindPhoneVo.java

@@ -0,0 +1,39 @@
+package com.jpsoft.smart.modules.wechat.vo;
+
+import lombok.Data;
+
+/**
+ * @author 墨鱼_mo
+ * @date 2019-8-5 13:32
+ */
+@Data
+public class BindPhoneVo {
+
+
+    /**
+     * 业主姓名
+     */
+    private String name;
+
+    /**
+     * 业主手机号
+     */
+    private String phoneNum;
+
+    /**
+     * openId
+     */
+    private String openId;
+
+    /**
+     * 图片验证码
+     */
+    private String verifyPicCode;
+
+    /**
+     * 短信验证码
+     */
+    private String verifyCode;
+
+
+}

+ 17 - 0
src/main/java/com/jpsoft/smart/modules/wechat/vo/RepairsVo.java

@@ -0,0 +1,17 @@
+package com.jpsoft.smart.modules.wechat.vo;
+
+import lombok.Data;
+
+/**
+ * @author 墨鱼_mo
+ * @date 2019-9-3 17:21
+ */
+@Data
+public class RepairsVo {
+
+    private String openId;
+
+    private String content;
+
+    private String type;
+}

+ 20 - 0
src/main/java/com/jpsoft/smart/modules/wechat/vo/UserInfo.java

@@ -0,0 +1,20 @@
+package com.jpsoft.smart.modules.wechat.vo;
+
+import lombok.Data;
+
+/**
+ * 微信通用接口凭证
+ * 
+ * @author lt
+ * @date 2013-08-08
+ */
+@Data
+public class UserInfo {
+	private String openid;
+	private String nickname;
+	private String city;
+	private String country;
+	private String province;
+	private String headimgurl;
+
+}

+ 3 - 3
src/main/resources/application-dev.yml

@@ -15,15 +15,15 @@ spring:
 
 logger:
   level: WARN
-  dir: D:\\idea-project\\smart-community-server
+  dir: E:\mye\WORK\wisdowHouse
 
 netty:
   port: 9966    #监听端口
 
 wx:
   pay:
-    appId: wxc0ddd6a415c535d9
-    appSecret: 042fe6c9c970c1d9fe585dccfca89221
+    appId: wx7e70eb62a8459869
+    appSecret: 909d17e353268da57c4f18cc09798049
 
 alipay:
   serviceUrl: https://openapi.alipaydev.com/gateway.do

+ 4 - 1
src/main/resources/application.yml

@@ -117,5 +117,8 @@ wx:
     notifyUrl: http://18891j25i6.iok.la:40309/epay-server/wxPay/payNotify
     ip: 101.37.31.116
 
-
+doorApi:
+  referer: http://58.54.251.155
+  apiId: bl63d49fae22bf5cca
+  apiKey: e52e545cb4d6c98a8a7e68b0718d3f63
 

+ 6 - 0
src/main/resources/mapper/base/InformationInfo.xml

@@ -118,4 +118,10 @@ id_,create_by,create_time,update_by,update_time,del_flag,owner_id,community_,con
 	        ${sort.name} ${sort.order}
 	 	</foreach>
 	</select>
+
+	<select id="findByOwnerIdAndType"  resultMap="InformationInfoMap">
+		select
+		id_,create_by,create_time,update_by,update_time,del_flag,owner_id,community_,content_,status_,return_content,return_time,type_		from base_information_info where owner_id=#{ownerId} and type_=#{type}
+	</select>
+
 </mapper>

+ 76 - 0
src/main/resources/mapper/wechat/accessControl.xml

@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<!-- namespace必须指向DAO接口 -->
+<mapper namespace="com.jpsoft.smart.modules.wechat.dao.AccessContorlDAO">
+    <resultMap id="AccessControlMap" type="AccessControl">
+        <id property="id" column="id"/>
+        <result property="ownerId" column="owner_id"/>
+        <result property="openId" column="open_id"/>
+        <result property="bindTime" column="bind_time"/>
+        <result property="bindFace" column="bind_face"/>
+        <result property="createTime" column="create_time"/>
+        <result property="createBy" column="create_by"/>
+        <result property="updateTime" column="update_time"/>
+        <result property="updateBy" column="update_by"/>
+    </resultMap>
+
+    <select id="findByOpenId" parameterType="string" resultMap="AccessControlMap">
+        select
+        * from access_control where
+        open_id=#{0}
+    </select>
+
+
+    <insert id="save" parameterType="AccessControl">
+        insert into access_control
+        (id,owner_id,open_id,bind_time,bind_face,create_time)
+        values
+        (#{id,jdbcType=VARCHAR}
+        ,#{ownerId,jdbcType=VARCHAR}
+        ,#{openId,jdbcType=VARCHAR}
+        ,#{bindTime,jdbcType= TIMESTAMP}
+        ,#{bindFace,jdbcType= NUMERIC }
+        ,#{createTime,jdbcType= TIMESTAMP }
+        )
+
+    </insert>
+
+
+    <update id="update" parameterType="AccessControl">
+        update access_control
+        <set>
+            <if test="createBy!=null">
+                create_by=#{createBy,jdbcType=VARCHAR},
+            </if>
+            <if test="createTime!=null">
+                create_time=#{createTime,jdbcType= TIMESTAMP },
+            </if>
+            <if test="updateBy!=null">
+                update_by=#{updateBy,jdbcType=VARCHAR},
+            </if>
+            <if test="updateTime!=null">
+                update_time=#{updateTime,jdbcType= TIMESTAMP },
+            </if>
+            <if test="ownerId!=null">
+                owner_id=#{ownerId,jdbcType=VARCHAR},
+            </if>
+            <if test="openId!=null">
+                open_id=#{openId,jdbcType=VARCHAR},
+            </if>
+            <if test="bindFace!=null">
+                bind_face=#{bindFace,jdbcType=NUMERIC},
+            </if>
+        </set>
+        where id=#{id}
+    </update>
+
+    <select id="findByOwner" parameterType="string" resultMap="AccessControlMap">
+        select
+        * from access_control where
+        owner_id=#{0}
+    </select>
+
+
+
+</mapper>