瀏覽代碼

公众号-关注/取消关注实现

Aron 6 年之前
父節點
當前提交
37617a7af6

+ 33 - 0
src/main/java/com/ifast/common/base/CoreService.java

@@ -1,7 +1,11 @@
 package com.ifast.common.base;
 
+import com.baomidou.mybatisplus.mapper.EntityWrapper;
 import com.baomidou.mybatisplus.service.IService;
 
+import java.util.List;
+import java.util.Map;
+
 /**
  * <pre>
  * 通用业务层实现
@@ -13,4 +17,33 @@ import com.baomidou.mybatisplus.service.IService;
  */
 public interface CoreService<T> extends IService<T> {
 
+    List<T> findByKv(Object... param);
+
+    T findOneByKv(Object... param);
+
+    /**
+     * <pre>
+     *
+     * </pre>
+     *
+     * <small> 2018/6/14 17:32 | Aron</small>
+     * @param [clazz, param]
+     * @return java.util.Map<java.lang.String,java.lang.Object>
+     *
+     */
+
+    Map<String, Object> convertToMap(Object... param);
+    
+    /**
+     * <pre>
+     *
+     * </pre>
+     * 
+     * <small> 2018/6/14 17:14 | Aron</small>
+     * @param [clazz, params]
+     * @return java.util.Map<java.lang.String,java.lang.Object>
+     *
+     */
+    EntityWrapper<T> convertToEntityWrapper(Object... params);
+
 }

+ 53 - 6
src/main/java/com/ifast/common/base/CoreServiceImpl.java

@@ -1,21 +1,68 @@
 package com.ifast.common.base;
 
+import com.baomidou.mybatisplus.mapper.BaseMapper;
+import com.baomidou.mybatisplus.mapper.EntityWrapper;
+import com.baomidou.mybatisplus.service.impl.ServiceImpl;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.baomidou.mybatisplus.mapper.BaseMapper;
-import com.baomidou.mybatisplus.service.impl.ServiceImpl;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 /**
  * <pre>
  * 通用业务层实现
  * </pre>
- * 
+ *
  * <small> 2018年1月9日 | Aron</small>
- * 
- * @param <M> mapper
- * @param <T> entity
+ *
+ * @param <M>
+ *            mapper
+ * @param <T>
+ *            entity
  */
 public abstract class CoreServiceImpl<M extends BaseMapper<T>, T> extends ServiceImpl<M, T> implements CoreService<T> {
     public Logger log = LoggerFactory.getLogger(this.getClass());
+
+    @Override
+    public List<T> findByKv(Object... params) {
+        if (params == null) {
+            return new ArrayList<>();
+        }
+        return baseMapper.selectByMap(convertToMap(params));
+    }
+
+    @Override
+    public T findOneByKv(Object... params) {
+        return selectOne(this.convertToEntityWrapper(params));
+    }
+
+    @Override
+    public Map<String, Object> convertToMap(Object... params) {
+        Map<String, Object> map = new HashMap<>();
+        if (params == null) {
+            return map;
+        }
+        for (int i = 0; i < params.length; i++) {
+            if (i % 2 == 1) {
+                map.put((String) params[i - 1], params[i]);
+            }
+        }
+        return map;
+    }
+    @Override
+    public EntityWrapper<T> convertToEntityWrapper(Object... params) {
+        EntityWrapper<T> ew = new EntityWrapper<>();
+        if (params == null) {
+            return ew;
+        }
+        for (int i = 0; i < params.length; i++) {
+            if (i % 2 == 1) {
+                ew.eq((String) params[i - 1], params[i]);
+            }
+        }
+        return ew;
+    }
 }

+ 1 - 0
src/main/java/com/ifast/shiro/config/ShiroConfig.java

@@ -129,6 +129,7 @@ public class ShiroConfig {
         shiroFilterFactoryBean.setUnauthorizedUrl("/shiro/415");
         LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
         filterChainDefinitionMap.put("/api/**", "jwt"); // api
+        filterChainDefinitionMap.put("/wx/**", "anon"); // 微信接入
         filterChainDefinitionMap.put("/shiro/**", "anon");
         filterChainDefinitionMap.put("/login", "anon");
         filterChainDefinitionMap.put("/css/**", "anon");

+ 29 - 0
src/main/java/com/ifast/wxmp/controller/mp/WxMenuController.java

@@ -0,0 +1,29 @@
+package com.ifast.wxmp.controller.mp;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.ifast.common.base.AdminBaseController;
+import com.ifast.wxmp.service.WeixinService;
+
+/**
+ * <pre>
+ * </pre>
+ *
+ * @Author Aron
+ * @Date 2018/5/3
+ */
+@RestController
+@RequestMapping("/wx/mp/menu")
+public class WxMenuController extends AdminBaseController {
+    
+    @Autowired
+    private WeixinService wxService;
+    
+    private final Logger logger = LoggerFactory.getLogger(this.getClass());
+    
+    
+}

+ 5 - 11
src/main/java/com/ifast/wxmp/controller/mp/WxMsgController.java

@@ -13,7 +13,7 @@ import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.ResponseBody;
 import org.springframework.web.bind.annotation.RestController;
 
-import com.ifast.common.utils.Result;
+import com.ifast.common.base.AdminBaseController;
 import com.ifast.wxmp.service.WeixinService;
 import com.ifast.wxmp.util.WxMpConfigHolder;
 
@@ -29,7 +29,7 @@ import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
  */
 @RestController
 @RequestMapping("/wx/mp/msg")
-public class WxMsgController {
+public class WxMsgController extends AdminBaseController {
     
     @Autowired
     private WeixinService wxService;
@@ -100,16 +100,10 @@ public class WxMsgController {
     }
     
     protected WeixinService getWxService() {
+        if(wxService.getRequestHttpClient() == null) {
+            wxService.initHttp();
+        }
         return this.wxService;
     }
     
-    @GetMapping("/")
-    private Result<String> msgGet() {
-        return Result.ok();
-    }
-    
-    @PostMapping("/")
-    public Result<String> msgPost() {
-        return Result.ok();
-    }
 }

+ 27 - 3
src/main/java/com/ifast/wxmp/domain/MpFansDO.java

@@ -1,12 +1,12 @@
 package com.ifast.wxmp.domain;
 
-import java.io.Serializable;
-import java.util.Date;
-
 import com.baomidou.mybatisplus.annotations.TableField;
 import com.baomidou.mybatisplus.annotations.TableId;
 import com.baomidou.mybatisplus.annotations.TableName;
 
+import java.io.Serializable;
+import java.util.Date;
+
 
 
 /**
@@ -275,4 +275,28 @@ public class MpFansDO implements Serializable {
     public String getTagidList() {
         return tagidList;
     }
+
+    @Override
+    public String toString() {
+        return "MpFansDO{" +
+                "id=" + id +
+                ", mpId=" + mpId +
+                ", openid='" + openid + '\'' +
+                ", nickname='" + nickname + '\'' +
+                ", subscribe=" + subscribe +
+                ", subscribeTime=" + subscribeTime +
+                ", subscribeKey='" + subscribeKey + '\'' +
+                ", sex=" + sex +
+                ", city='" + city + '\'' +
+                ", country='" + country + '\'' +
+                ", province='" + province + '\'' +
+                ", language='" + language + '\'' +
+                ", headimgurl='" + headimgurl + '\'' +
+                ", unionid='" + unionid + '\'' +
+                ", remark='" + remark + '\'' +
+                ", groupid=" + groupid +
+                ", status=" + status +
+                ", tagidList='" + tagidList + '\'' +
+                '}';
+    }
 }

+ 6 - 7
src/main/java/com/ifast/wxmp/handler/MsgHandler.java

@@ -1,18 +1,16 @@
 package com.ifast.wxmp.handler;
 
-import java.util.Map;
-
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.stereotype.Component;
-
 import com.ifast.wxmp.builder.TextBuilder;
 import com.ifast.wxmp.service.WeixinService;
-
 import me.chanjar.weixin.common.api.WxConsts;
 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;
 
 /**
  * 
@@ -27,11 +25,12 @@ public class MsgHandler extends AbstractHandler {
     @Override
     public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService,
             WxSessionManager sessionManager) {
-
+        logger.debug("接受消息:{}", wxMessage);
         WeixinService weixinService = (WeixinService) wxMpService;
 
         if (!wxMessage.getMsgType().equals(WxConsts.XmlMsgType.TEXT)) {
             // TODO 可以选择将消息保存到本地
+            logger.debug("文本消息持久化到本地");
         }
 
         // 当用户输入关键词如“你好”,“客服”等,并且有客服在线时,把消息转发给在线客服

+ 54 - 10
src/main/java/com/ifast/wxmp/handler/SubscribeHandler.java

@@ -1,34 +1,45 @@
 package com.ifast.wxmp.handler;
 
-import java.util.Map;
-
-import org.springframework.stereotype.Component;
-
 import com.ifast.wxmp.builder.TextBuilder;
+import com.ifast.wxmp.domain.MpFansDO;
+import com.ifast.wxmp.service.MpConfigService;
+import com.ifast.wxmp.service.MpFansService;
 import com.ifast.wxmp.service.WeixinService;
-
+import com.ifast.wxmp.util.WxMpConfigHolder;
 import me.chanjar.weixin.common.exception.WxErrorException;
 import me.chanjar.weixin.common.session.WxSessionManager;
 import me.chanjar.weixin.mp.api.WxMpService;
 import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
 import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
 import me.chanjar.weixin.mp.bean.result.WxMpUser;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.Arrays;
+import java.util.Date;
+import java.util.Map;
 
 /**
- * 
  * <pre>
+ *     关注
  * </pre>
- * 
+ * <p>
  * <small> 2018年6月13日 | Aron</small>
  */
 @Component
 public class SubscribeHandler extends AbstractHandler {
 
+    @Autowired
+    private MpFansService mpFansService;
+    @Autowired
+    private MpConfigService mpConfigService;
+
     @Override
     public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService,
-            WxSessionManager sessionManager) throws WxErrorException {
+                                    WxSessionManager sessionManager) throws WxErrorException {
 
-        this.logger.info("新关注用户 OPENID: " + wxMessage.getFromUser());
+        this.logger.info("新关注用户 openid: " + wxMessage.getFromUser());
 
         WeixinService weixinService = (WeixinService) wxMpService;
 
@@ -36,7 +47,11 @@ public class SubscribeHandler extends AbstractHandler {
         WxMpUser userWxInfo = weixinService.getUserService().userInfo(wxMessage.getFromUser(), null);
 
         if (userWxInfo != null) {
-            // TODO 可以添加关注用户到本地
+            this.logger.debug("同步微信用户信息数据");
+            MpFansDO fans = new MpFansDO();
+            convert(userWxInfo, fans);
+            mpFansService.sync(fans);
+
         }
 
         WxMpXmlOutMessage responseResult = null;
@@ -59,11 +74,40 @@ public class SubscribeHandler extends AbstractHandler {
         return null;
     }
 
+    private void convert(WxMpUser wxUser, MpFansDO fans) {
+        BeanUtils.copyProperties(wxUser, fans);
+//        fans.setCity(wxUser.getCity());
+//        fans.setCountry(wxUser.getCountry());
+        fans.setGroupid(wxUser.getGroupId());
+        fans.setHeadimgurl(wxUser.getHeadImgUrl());
+//        fans.setLanguage(wxUser.getLanguage());
+//        fans.setNickname(wxUser.getNickname());
+        fans.setOpenid(wxUser.getOpenId());
+//        fans.setProvince(wxUser.getProvince());
+//        fans.setRemark(wxUser.getRemark());
+//        fans.setSex(wxUser.getSex());
+        fans.setMpId(this.getMpIdByAppId(WxMpConfigHolder.getCurrentAppId()));
+        // fans.setStatus(status);
+        // fans.setSubscribeKey();
+        fans.setSubscribe(wxUser.getSubscribe() ? 1 : 0);
+        fans.setSubscribeTime(new Date());
+        fans.setTagidList(Arrays.toString(wxUser.getTagIds()));
+        fans.setUnionid(wxUser.getUnionId());
+
+        this.logger.debug("convert return :{}", fans);
+
+    }
+
+    public long getMpIdByAppId(String appId) {
+        return mpConfigService.findOneByKv("app_id", appId).getId();
+    }
+
     /**
      * 处理特殊请求,比如如果是扫码进来的,可以做相应处理
      */
     protected WxMpXmlOutMessage handleSpecial(WxMpXmlMessage wxMessage) throws Exception {
         // TODO
+        logger.debug("扫码事件触发... :", wxMessage);
         return null;
     }
 

+ 15 - 6
src/main/java/com/ifast/wxmp/handler/UnsubscribeHandler.java

@@ -1,17 +1,20 @@
 package com.ifast.wxmp.handler;
 
-import java.util.Map;
-
-import org.springframework.stereotype.Component;
-
+import com.ifast.wxmp.domain.MpFansDO;
+import com.ifast.wxmp.service.MpFansService;
 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.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.Map;
 
 /**
  * 
  * <pre>
+ *     取消关注
  * </pre>
  * 
  * <small> 2018年6月13日 | Aron</small>
@@ -19,12 +22,18 @@ import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
 @Component
 public class UnsubscribeHandler extends AbstractHandler {
 
+    
+    @Autowired
+    private MpFansService mpFansService;
+    
     @Override
     public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService,
             WxSessionManager sessionManager) {
         String openId = wxMessage.getFromUser();
-        this.logger.info("取消关注用户 OPENID: " + openId);
-        // TODO 可以更新本地数据库为取消关注状态
+        this.logger.info("用户取消关注 openid: " + openId);
+        MpFansDO fans = mpFansService.findOneByKv("openid", openId);
+        fans.setSubscribe(0);
+        mpFansService.updateById(fans);
         return null;
     }
 

+ 11 - 0
src/main/java/com/ifast/wxmp/service/MpFansService.java

@@ -11,5 +11,16 @@ import com.ifast.common.base.CoreService;
  * <small> 2018-04-11 23:27:06 | Aron</small>
  */
 public interface MpFansService extends CoreService<MpFansDO> {
+
+    /**
+     * <pre>
+     * 根据openid查表是否存在,如果存在则更新fans数据
+     * </pre>
+     * 
+     * <small> 2018年6月13日 | Aron</small>
+     * 
+     * @param fans
+     */
+    void sync(MpFansDO fans);
     
 }

+ 7 - 8
src/main/java/com/ifast/wxmp/service/WeixinService.java

@@ -1,9 +1,8 @@
 package com.ifast.wxmp.service;
 
-import javax.annotation.PostConstruct;
-
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.InitializingBean;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -36,7 +35,7 @@ import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
  * <small> 2018年6月13日 | Aron</small>
  */
 @Service
-public class WeixinService extends WxMpServiceImpl {
+public class WeixinService extends WxMpServiceImpl implements InitializingBean {
     private final Logger logger = LoggerFactory.getLogger(this.getClass());
 
     @Autowired
@@ -68,11 +67,6 @@ public class WeixinService extends WxMpServiceImpl {
 
     private WxMpMessageRouter router;
 
-    @PostConstruct
-    public void init() {
-        this.refreshRouter();
-    }
-
     @Override
     public WxMpConfigStorage getWxMpConfigStorage() {
         WxMpInMemoryConfigStorage wxMpInMemoryConfigStorage = WxMpConfigHolder.getWxMpInMemoryConfigStorage();
@@ -165,4 +159,9 @@ public class WeixinService extends WxMpServiceImpl {
         return null;
     }
 
+    @Override
+    public void afterPropertiesSet() throws Exception {
+        this.refreshRouter();
+    }
+
 }

+ 14 - 0
src/main/java/com/ifast/wxmp/service/impl/MpFansServiceImpl.java

@@ -1,5 +1,6 @@
 package com.ifast.wxmp.service.impl;
 
+import org.springframework.beans.BeanUtils;
 import org.springframework.stereotype.Service;
 
 import com.ifast.wxmp.dao.MpFansDao;
@@ -17,4 +18,17 @@ import com.ifast.common.base.CoreServiceImpl;
 @Service
 public class MpFansServiceImpl extends CoreServiceImpl<MpFansDao, MpFansDO> implements MpFansService {
 
+    @Override
+    public void sync(MpFansDO fans) {
+        MpFansDO one = findOneByKv("openid", fans.getOpenid());
+        if(one == null) {
+            log.debug("新用户保存信息到db");
+            insert(fans);
+            return;
+        }
+        log.debug("老用户更新信息");
+        BeanUtils.copyProperties(fans, one);
+        updateById(one);
+    }
+
 }