浏览代码

Merge remote-tracking branch 'origin/master'

小么熊🐻 3 年之前
父节点
当前提交
bfb9f28b19

+ 27 - 14
twzd-admin/src/main/java/com/miaxis/app/controller/wx/WxgzhController.java

@@ -8,12 +8,12 @@ import io.swagger.annotations.ApiOperation;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.RestController;
 
 import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
 
 /**
  * 微信公众号相关
@@ -42,14 +42,13 @@ public class WxgzhController {
 
 
     /**
-     * 处理服务器推送消息
+     * 获取微信验签
      * @param request
-     * @param response
      * @return
      */
-    @RequestMapping(value = "/notifyMsg",method = { RequestMethod.GET, RequestMethod.POST })
-    @ApiOperation("处理服务器推送消息")
-    public String checkSign(HttpServletRequest request, HttpServletResponse response) {
+    @GetMapping(value = "/notifyMsg")
+    @ApiOperation("获取微信验签")
+    public String checkSign(HttpServletRequest request) {
         log.info("-----------进入---------");
         try {
             String signature = request.getParameter("signature");
@@ -57,13 +56,8 @@ public class WxgzhController {
             String nonce = request.getParameter("nonce");
             String echostr = request.getParameter("echostr");
             log.info("本身" + signature);
-            if(request.getMethod().equals("GET")){
-                log.info("-----------微信验签---------");
-                return SignUtil.checkSignature(signature, timestamp, nonce) == true ? echostr : null;
-            }else{
-                log.info("-----------推送消息处理---------");
-                return wxGzhService.handlePublicMsg(request);
-            }
+            log.info("-----------微信验签---------");
+            return SignUtil.checkSignature(signature, timestamp, nonce) == true ? echostr : null;
         } catch (Exception e) {
             log.error("验证公众号token失败", e);
         }
@@ -71,4 +65,23 @@ public class WxgzhController {
     }
 
 
+    /**
+     * 处理服务器推送消息
+     * @param request
+     * @return
+     */
+    @PostMapping(value = "/notifyMsg")
+    @ApiOperation("处理服务器推送消息")
+    public String dealNotify(HttpServletRequest request) {
+        log.info("-----------进入---------");
+        try {
+            log.info("-----------推送消息处理---------");
+            return wxGzhService.handlePublicMsg(request);
+        } catch (Exception e) {
+            log.error("处理推送消息失败", e);
+        }
+        return null;
+    }
+
+
 }

+ 110 - 0
twzd-admin/src/main/java/com/miaxis/pc/controller/wx/WxForeverCodeController.java

@@ -0,0 +1,110 @@
+package com.miaxis.pc.controller.wx;
+
+import com.miaxis.common.core.controller.BaseController;
+import com.miaxis.common.core.page.ResponsePageInfo;
+import com.miaxis.wx.domain.WxForeverCode;
+import com.miaxis.wx.service.IWxForeverCodeService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+/**
+ * 【微信永久二维码口令】Controller
+ *
+ * @author miaxis
+ * @date 2022-01-17
+ */
+@RestController
+@RequestMapping("/wx/code")
+@Api(tags={"【pc-微信永久二维码口令】"})
+public class WxForeverCodeController extends BaseController{
+    @Autowired
+    private IWxForeverCodeService wxForeverCodeService;
+
+    /**
+     * 查询微信永久二维码口令列表
+     */
+    @PreAuthorize("@ss.hasPermi('wx:code:list')")
+    @GetMapping("/list")
+    @ApiOperation("查询微信永久二维码口令列表")
+        @ApiImplicitParams({
+            @ApiImplicitParam(name = "pageNum",value = "当前页码" ,dataType = "int", paramType = "query", required = false),
+            @ApiImplicitParam(name = "pageSize",value = "每页数据量" , dataType = "int", paramType = "query", required = false),
+    })
+    public ResponsePageInfo<WxForeverCode> list(@ModelAttribute WxForeverCode wxForeverCode){
+        startPage();
+        List<WxForeverCode> list = wxForeverCodeService.selectWxForeverCodeList(wxForeverCode);
+        return toResponsePageInfo(list);
+    }
+
+//    /**
+//     * 导出微信永久二维码口令列表
+//     */
+//    @PreAuthorize("@ss.hasPermi('wx:code:export')")
+//    @Log(title = "微信永久二维码口令", businessType = BusinessTypeEnum.EXPORT)
+//    @GetMapping("/export")
+//    @ApiOperation("导出微信永久二维码口令列表Excel")
+//    public Response<String> export(@ModelAttribute WxForeverCode wxForeverCode){
+//        List<WxForeverCode> list = wxForeverCodeService.selectWxForeverCodeList(wxForeverCode);
+//        ExcelUtil<WxForeverCode> util = new ExcelUtil<WxForeverCode>(WxForeverCode.class);
+//        return util.exportExcel(list, "code");
+//    }
+
+//    /**
+//     * 获取微信永久二维码口令详细信息
+//     */
+//    @PreAuthorize("@ss.hasPermi('wx:code:query')")
+//    @GetMapping(value = "/{id}")
+//    @ApiOperation("获取微信永久二维码口令详细信息")
+//    public Response<WxForeverCode> getInfo(
+//            @ApiParam(name = "id", value = "微信永久二维码口令参数", required = true)
+//            @PathVariable("id") Long id
+//    ){
+//        return Response.success(wxForeverCodeService.getById(id));
+//    }
+
+//    /**
+//     * 新增微信永久二维码口令
+//     */
+//    @PreAuthorize("@ss.hasPermi('wx:code:add')")
+//    @Log(title = "微信永久二维码口令", businessType = BusinessTypeEnum.INSERT)
+//    @PostMapping
+//    @ApiOperation("新增微信永久二维码口令")
+//    public Response<Integer> add(@RequestBody WxForeverCode wxForeverCode){
+//        return toResponse(wxForeverCodeService.save(wxForeverCode) ? 1 : 0);
+//    }
+//
+//    /**
+//     * 修改微信永久二维码口令
+//     */
+//    @PreAuthorize("@ss.hasPermi('wx:code:edit')")
+//    @Log(title = "微信永久二维码口令", businessType = BusinessTypeEnum.UPDATE)
+//    @PutMapping
+//    @ApiOperation("修改微信永久二维码口令")
+//    public Response<Integer> edit(@RequestBody WxForeverCode wxForeverCode){
+//        return toResponse(wxForeverCodeService.updateById(wxForeverCode) ? 1 : 0);
+//    }
+//
+//    /**
+//     * 删除微信永久二维码口令
+//     */
+//    @PreAuthorize("@ss.hasPermi('wx:code:remove')")
+//    @Log(title = "微信永久二维码口令", businessType = BusinessTypeEnum.DELETE)
+//	@DeleteMapping("/{ids}")
+//    @ApiOperation("删除微信永久二维码口令")
+//    public  Response<Integer> remove(
+//            @ApiParam(name = "ids", value = "微信永久二维码口令ids参数", required = true)
+//            @PathVariable Long[] ids
+//    ){
+//        return toResponse(wxForeverCodeService.removeByIds(Arrays.asList(ids)) ? 1 : 0);
+//    }
+}

+ 55 - 0
twzd-admin/src/test/java/com/miaxis/test/NormalTest.java

@@ -1,14 +1,21 @@
 package com.miaxis.test;
 
+import com.alibaba.fastjson.JSONObject;
 import com.miaxis.TwzdApplication;
+import com.miaxis.common.constant.Constants;
+import com.miaxis.common.utils.StringUtils;
+import com.miaxis.feign.service.IWxSendService;
 import com.miaxis.question.mapper.QuestionInfoMapper;
 import com.miaxis.question.vo.QuestionInfoExcelTypeVo;
 import com.miaxis.question.vo.QuestionInfoExcelVo;
+import com.miaxis.wx.service.IWxForeverCodeService;
 import com.miaxis.wx.service.impl.WxGzhServiceImpl;
 import org.apache.poi.hssf.usermodel.*;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.test.context.ActiveProfiles;
 import org.springframework.test.context.junit4.SpringRunner;
 
@@ -16,6 +23,7 @@ import javax.annotation.Resource;
 import java.io.FileOutputStream;
 import java.io.OutputStream;
 import java.util.List;
+import java.util.concurrent.TimeUnit;
 
 @ActiveProfiles("prod")
 @SpringBootTest(classes = TwzdApplication.class)
@@ -29,7 +37,54 @@ public class NormalTest {
     @Resource
     QuestionInfoMapper questionInfoMapper;
 
+    @Resource
+    IWxForeverCodeService wxForeverCodeService;
+
+
+    @Resource
+    IWxSendService wxSendService;
+
+    @Resource
+    RedisTemplate redisTemplate;
+
+
+    @Value("${app.appid}")
+    private String appid;
+
+    @Value("${app.appSecret}")
+    private String secret;
 
+    public String getGzhToken() {
+        String token = "";
+        Integer expiresIn;
+        if (redisTemplate.hasKey(Constants.GZH_MESSAGE_TOKEN)){
+            token = (String)redisTemplate.opsForValue().get(Constants.GZH_MESSAGE_TOKEN);
+        }
+        if (StringUtils.isEmpty(token)){
+            String result = wxSendService.getAccessToken("client_credential",appid,secret);
+            JSONObject json = JSONObject.parseObject(result);
+            token = json.getString("access_token");
+            expiresIn = json.getIntValue("expires_in");
+            if (expiresIn <= 0){
+                expiresIn = 7000;
+            }
+
+            redisTemplate.opsForValue().set(Constants.GZH_MESSAGE_TOKEN,token,expiresIn, TimeUnit.SECONDS);
+        }
+
+        return token;
+    }
+
+    @Test
+    public void test11() throws Exception {
+        //获取用户信息
+        String userInfoResult = wxSendService.userInfo(this.getGzhToken(), "ovKTX5-FKLF6_sgTtCIXpG_lz3PY", "zh_CN");
+        JSONObject jsonObj = JSONObject.parseObject(userInfoResult);
+        System.out.println(jsonObj);
+//        String  content = "k3vvps";
+//        WxForeverCode wxForeverCode = wxForeverCodeService.getOne(new QueryWrapper<WxForeverCode>().eq("code", content).isNull("openid"));
+//        System.out.println(11);
+    }
 
 
     @Test

+ 1 - 4
twzd-framework/src/main/java/com/miaxis/framework/aspectj/LogFileAspect.java

@@ -1,8 +1,6 @@
 package com.miaxis.framework.aspectj;
 
 import cn.hutool.json.JSONUtil;
-import com.alibaba.fastjson.JSON;
-import com.miaxis.common.utils.ServletUtils;
 import lombok.extern.slf4j.Slf4j;
 import org.aspectj.lang.JoinPoint;
 import org.aspectj.lang.ProceedingJoinPoint;
@@ -12,7 +10,6 @@ import org.springframework.web.context.request.RequestContextHolder;
 import org.springframework.web.context.request.ServletRequestAttributes;
 
 import javax.servlet.http.HttpServletRequest;
-import java.util.Arrays;
 
 @Aspect
 @Component
@@ -45,7 +42,7 @@ public class LogFileAspect {
     @AfterReturning(returning = "ret", pointcut = "logPoint()")// returning的值和doAfterReturning的参数名一致
     public void doAfterReturning(Object ret) throws Throwable {
         // 处理完请求,返回内容
-        log.info("返回值 : " + JSON.toJSONString(ret));
+        //log.info("返回值 : " + JSON.toJSONString(ret));
     }
 
     @Around("logPoint()")

+ 2 - 2
twzd-framework/src/main/java/com/miaxis/framework/interceptor/impl/SameUrlDataInterceptor.java

@@ -19,7 +19,7 @@ import java.util.concurrent.TimeUnit;
 /**
  * 判断请求url和数据是否和上一次相同,
  * 如果和上次相同,则是重复提交表单。 有效时间为10秒内。
- * 
+ *
  * @author miaxis
  */
 @Component
@@ -38,7 +38,7 @@ public class SameUrlDataInterceptor extends RepeatSubmitInterceptor
 
     /**
      * 间隔时间,单位:秒 默认10秒
-     * 
+     *
      * 两次相同参数的请求,如果间隔时间大于该参数,系统不会认定为重复提交的数据
      */
     private int intervalTime = 10;

+ 6 - 1
twzd-framework/src/main/java/com/miaxis/framework/web/service/TokenService.java

@@ -12,6 +12,7 @@ import eu.bitwalker.useragentutils.UserAgent;
 import io.jsonwebtoken.Claims;
 import io.jsonwebtoken.Jwts;
 import io.jsonwebtoken.SignatureAlgorithm;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
@@ -27,6 +28,7 @@ import java.util.concurrent.TimeUnit;
  * @author miaxis
  */
 @Component
+@Slf4j
 public class TokenService
 {
     // 令牌自定义标识
@@ -122,7 +124,10 @@ public class TokenService
     {
         long expireTime = loginUser.getExpireTime();
         long currentTime = System.currentTimeMillis();
-        if (expireTime - currentTime <= MILLIS_MINUTE_TEN)
+        long differTime = expireTime - currentTime;
+        Long differMinuts= differTime/(1000l*60);
+        log.info(differMinuts.toString());
+        if (differTime <= MILLIS_MINUTE_TEN)
         {
             refreshToken(loginUser);
         }

+ 108 - 0
twzd-service/src/main/java/com/miaxis/wx/domain/WxForeverCode.java

@@ -0,0 +1,108 @@
+package com.miaxis.wx.domain;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.miaxis.common.annotation.Excel;
+import com.miaxis.common.core.domain.BaseBusinessEntity;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+/**
+ * 微信永久二维码口令对象 wx_forever_code
+ *
+ * @author miaxis
+ * @date 2022-01-17
+ */
+@Data
+@TableName("wx_forever_code")
+@ApiModel(value = "WxForeverCode", description = "微信永久二维码口令对象 wx_forever_code")
+public class WxForeverCode extends BaseBusinessEntity{
+    private static final long serialVersionUID = 1L;
+
+    /** 主键 */
+    @TableId(value = "id")
+    @ApiModelProperty(value = "主键")
+    private Long id;
+
+    /** 用户唯一标识(微信) */
+    @Excel(name = "用户唯一标识(微信)")
+    @TableField("openid")
+    @ApiModelProperty(value = "用户唯一标识(微信)")
+    private String openid;
+
+    /** 6位口令 */
+    @Excel(name = "6位口令")
+    @TableField("code")
+    @ApiModelProperty(value = "6位口令")
+    private String code;
+
+    /** 微信昵称 */
+    @Excel(name = "微信昵称")
+    @TableField("nick_name")
+    @ApiModelProperty(value = "微信昵称")
+    private String nickName;
+
+
+    @TableField("url")
+    @ApiModelProperty(value = "url")
+    private String url;
+
+    /** 状态  1:有效(默认) 0:失效  */
+    @Excel(name = "状态  1:有效(默认) 0:失效 ")
+    @TableField("status")
+    @ApiModelProperty(value = "状态  1:有效(默认) 0:失效 ")
+    private Integer status;
+
+    public void setId(Long id){
+        this.id = id;
+    }
+
+    public Long getId(){
+        return id;
+    }
+    public void setOpenid(String openid){
+        this.openid = openid;
+    }
+
+    public String getOpenid(){
+        return openid;
+    }
+    public void setCode(String code){
+        this.code = code;
+    }
+
+    public String getCode(){
+        return code;
+    }
+    public void setNickName(String nickName){
+        this.nickName = nickName;
+    }
+
+    public String getNickName(){
+        return nickName;
+    }
+    public void setStatus(Integer status){
+        this.status = status;
+    }
+
+    public Integer getStatus(){
+        return status;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("id", getId())
+            .append("openid", getOpenid())
+            .append("code", getCode())
+            .append("nickName", getNickName())
+            .append("createTime", getCreateTime())
+            .append("updateTime", getUpdateTime())
+            .append("status", getStatus())
+            .toString();
+    }
+}

+ 23 - 0
twzd-service/src/main/java/com/miaxis/wx/mapper/WxForeverCodeMapper.java

@@ -0,0 +1,23 @@
+package com.miaxis.wx.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.miaxis.wx.domain.WxForeverCode;
+
+import java.util.List;
+
+/**
+ * 微信永久二维码口令Mapper接口
+ *
+ * @author miaxis
+ * @date 2022-01-17
+ */
+public interface WxForeverCodeMapper extends BaseMapper<WxForeverCode> {
+    /**
+     * 查询微信永久二维码口令列表
+     *
+     * @param wxForeverCode 微信永久二维码口令
+     * @return 微信永久二维码口令集合
+     */
+    public List<WxForeverCode> selectWxForeverCodeList(WxForeverCode wxForeverCode);
+
+}

+ 22 - 0
twzd-service/src/main/java/com/miaxis/wx/service/IWxForeverCodeService.java

@@ -0,0 +1,22 @@
+package com.miaxis.wx.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.miaxis.wx.domain.WxForeverCode;
+
+import java.util.List;
+
+/**
+ * 微信永久二维码口令Service接口
+ *
+ * @author miaxis
+ * @date 2022-01-17
+ */
+public interface IWxForeverCodeService extends IService<WxForeverCode>{
+    /**
+     * 查询微信永久二维码口令列表
+     *
+     * @param wxForeverCode 微信永久二维码口令
+     * @return 微信永久二维码口令集合
+     */
+    public List<WxForeverCode> selectWxForeverCodeList(WxForeverCode wxForeverCode);
+}

+ 6 - 3
twzd-service/src/main/java/com/miaxis/wx/service/IWxMessageEvenService.java

@@ -1,5 +1,7 @@
 package com.miaxis.wx.service;
 
+import com.miaxis.wx.domain.WxForeverCode;
+
 /**
  * 微信消息事件处理
  * @author wwl
@@ -14,20 +16,21 @@ public interface IWxMessageEvenService {
     /**
      * 扫码关注事件
      * @param fromUserName 发送方帐号(一个OpenID)
-     * @param ticket 二维码的ticket
      * @param token 凭证
      * @param userName 微信名称
      * @return
      */
-    String scanSubscribeEvent(String fromUserName,String ticket,String token,String userName);
+    String scanSubscribeEvent(String fromUserName,String eventKey,String token,String userName);
 
     /**
      * click获取分销二维码事件
      * @param fromUserName 发送方帐号(一个OpenID)
      * @param token 凭证
+     * @param isForever 是否是永久二维码
+     * @param wxForeverCode
      * @return
      */
-    String gainTicketEvent(String fromUserName,String token);
+    String gainTicketEvent(String fromUserName, String token, boolean isForever, WxForeverCode wxForeverCode);
 
 
 }

+ 85 - 0
twzd-service/src/main/java/com/miaxis/wx/service/impl/WxForeverCodeServiceImpl.java

@@ -0,0 +1,85 @@
+package com.miaxis.wx.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.miaxis.wx.domain.WxForeverCode;
+import com.miaxis.wx.mapper.WxForeverCodeMapper;
+import com.miaxis.wx.service.IWxForeverCodeService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import java.util.List;
+import java.util.Random;
+
+/**
+ * 微信永久二维码口令Service业务层处理
+ *
+ * @author miaxis
+ * @date 2022-01-17
+ */
+@Service
+public class WxForeverCodeServiceImpl extends ServiceImpl<WxForeverCodeMapper, WxForeverCode> implements IWxForeverCodeService {
+    @Autowired
+    private WxForeverCodeMapper wxForeverCodeMapper;
+
+    /**
+     * 查询微信永久二维码口令列表
+     *
+     * @param wxForeverCode 微信永久二维码口令
+     * @return 微信永久二维码口令
+     */
+    @Override
+    public List<WxForeverCode> selectWxForeverCodeList(WxForeverCode wxForeverCode){
+        List<WxForeverCode> wxForeverCodes = wxForeverCodeMapper.selectWxForeverCodeList(wxForeverCode);
+        // 若目前无数据,则创建一个
+        if (CollectionUtils.isEmpty(wxForeverCodes)){
+            creatNewCode();
+        }else{
+            //查询未被使用的口令个数,如果等于0 ,创建一个
+            long count = wxForeverCodes.stream().filter(o -> o.getOpenid() == null).count();
+            if (count == 0l){
+                creatNewCode();
+            }
+        }
+        return wxForeverCodeMapper.selectWxForeverCodeList(wxForeverCode);
+    }
+
+    private void creatNewCode() {
+        WxForeverCode newWxForeverCode = new WxForeverCode();
+        String code = null ;
+        do {
+            code  = getRandomString(6);
+        }while (isRepeat(code));
+        newWxForeverCode.setCode(code);
+        this.save(newWxForeverCode);
+    }
+
+    private boolean isRepeat(String code) {
+        QueryWrapper<WxForeverCode> wrapper = new QueryWrapper<WxForeverCode>();
+        wrapper.eq("code",code);
+        WxForeverCode one = this.getOne(wrapper);
+        return one!= null;
+    }
+
+
+    //length用户要求产生字符串的长度
+    public static String getRandomString(int length){
+        String str="abcdefghjkmnpqrstuvwxyz123456789";
+        Random random=new Random();
+        StringBuffer sb=new StringBuffer();
+        int bound = str.length();
+        for(int i=0;i<length;i++){
+            int number=random.nextInt(bound);
+            sb.append(str.charAt(number));
+        }
+        return sb.toString();
+    }
+
+    public static void main(String[] args) {
+        Random random=new Random();
+        for(int i =0 ;i <100;i++){
+            System.out.println(random.nextInt(1));
+        }
+    }
+}

+ 38 - 14
twzd-service/src/main/java/com/miaxis/wx/service/impl/WxGzhServiceImpl.java

@@ -1,18 +1,23 @@
 package com.miaxis.wx.service.impl;
 
+import cn.hutool.json.XML;
 import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.miaxis.common.constant.Constants;
 import com.miaxis.common.core.domain.entity.UserInfo;
 import com.miaxis.common.utils.StringUtils;
 import com.miaxis.common.utils.wx.MessageUtil;
 import com.miaxis.feign.service.IWxSendService;
 import com.miaxis.system.service.ISysUserService;
+import com.miaxis.wx.domain.WxForeverCode;
 import com.miaxis.wx.mapper.WxMenuMapper;
+import com.miaxis.wx.service.IWxForeverCodeService;
 import com.miaxis.wx.service.IWxGzhService;
 import com.miaxis.wx.service.IWxMessageEvenService;
 import com.qcloud.cos.COSClient;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.io.IOUtils;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Service;
@@ -43,6 +48,8 @@ public class WxGzhServiceImpl implements IWxGzhService {
 
     private final IWxMessageEvenService wxMessageEvenService;
 
+    private final IWxForeverCodeService wxForeverCodeService;
+
     @Value("${app.appid}")
     private String appid;
 
@@ -87,11 +94,11 @@ public class WxGzhServiceImpl implements IWxGzhService {
     public String handlePublicMsg(HttpServletRequest request) {
         try {
             log.info("1....");
-//            cn.hutool.json.JSONObject decryptMap = XML.toJSONObject(IOUtils.toString(request.getInputStream()));
-//            cn.hutool.json.JSONObject jsonObjectData = decryptMap.getJSONObject("xml");
+            cn.hutool.json.JSONObject decryptMap = XML.toJSONObject(IOUtils.toString(request.getInputStream()));
+            cn.hutool.json.JSONObject jsonObjectData = decryptMap.getJSONObject("xml");
 
 
-            cn.hutool.json.JSONObject jsonObjectData = new cn.hutool.json.JSONObject("{\"CreateTime\":1639474955,\"EventKey\":\"https://jpcj-h5.zzxcx.net\",\"ToUserName\":\"gh_628da25a95e5\",\"MsgType\":\"event\",\"MenuId\":442656773,\"Event\":\"VIEW\",\"FromUserName\":\"ovKTX50v7OAEPI_ERofpUvrNQCJU\"}");
+            //cn.hutool.json.JSONObject jsonObjectData = new cn.hutool.json.JSONObject("{\"CreateTime\":1639474955,\"EventKey\":\"https://jpcj-h5.zzxcx.net\",\"ToUserName\":\"gh_628da25a95e5\",\"MsgType\":\"event\",\"MenuId\":442656773,\"Event\":\"VIEW\",\"FromUserName\":\"ovKTX50v7OAEPI_ERofpUvrNQCJU\"}");
             log.info("2-----jsonObjectData------"+jsonObjectData);
 
 
@@ -102,12 +109,22 @@ public class WxGzhServiceImpl implements IWxGzhService {
             String fromUserName = jsonObjectData.getStr("FromUserName");
             // 区分消息类型
             String msgType = jsonObjectData.getStr("MsgType");
+            //获取用户信息
+//            String userInfoResult = wxSendService.userInfo(this.getGzhToken(), fromUserName, "zh_CN");
+//            JSONObject jsonObj = JSONObject.parseObject(userInfoResult);
 
             // 普通消息
             if (MessageUtil.MESSAGE_TEXT.equals(msgType)) { // 文本消息
                 log.info("2.1...");
                 String content = jsonObjectData.getStr("Content");
-                if (content.startsWith("你好")){
+                WxForeverCode wxForeverCode = wxForeverCodeService.getOne(new QueryWrapper<WxForeverCode>().eq("code", content).isNull("openid"));
+                //若该口令为未使用的口令
+                if (wxForeverCode != null){
+                    log.info("2.1.1:口令有效,生成永久二维码");
+                    String mediaId = wxMessageEvenService.gainTicketEvent(fromUserName, this.getGzhToken(),true,wxForeverCode);
+                    return MessageUtil.initImage(fromUserName,toUserName,mediaId);
+                }
+                else if (content.startsWith("你好")){
                     return MessageUtil.initText(fromUserName, toUserName, "你好啊");
                 }else if (content.startsWith("傻逼")){
                     return MessageUtil.initText(fromUserName, toUserName, "你才是煞笔");
@@ -124,17 +141,13 @@ public class WxGzhServiceImpl implements IWxGzhService {
                 String event = jsonObjectData.getStr("Event");
                 if (MessageUtil.MESSAGE_SUBSCRIBE.equals(event)) { // 关注事件 或 扫描二维码关注事件
                     log.info("3.1...");
-
-                    //获取用户信息
-                    String userInfoResult = wxSendService.userInfo(this.getGzhToken(), fromUserName, "zh_CN");
-                    JSONObject jsonObj = JSONObject.parseObject(userInfoResult);
                     UserInfo user = userService.getStudentByOpenId(fromUserName);
                     UserInfo userInfo = new UserInfo();
                     if (user == null){
                         //保存用户信息
-                        userInfo.setHeadImage(jsonObj.getString("headimgurl"));
-                        userInfo.setNickName(jsonObj.getString("nickname"));
-                        userInfo.setOpenid(jsonObj.getString("openid"));
+//                        userInfo.setHeadImage(jsonObj.getString("headimgurl"));
+//                        userInfo.setNickName(jsonObj.getString("nickname"));
+                        userInfo.setOpenid(fromUserName);
                         userService.saveUserInfo(userInfo);
                     }
 
@@ -142,11 +155,11 @@ public class WxGzhServiceImpl implements IWxGzhService {
                     if (org.apache.commons.lang3.StringUtils.isNotEmpty(jsonObjectData.getStr("Ticket"))){
                         log.info("3.1.2..");
                         //根据Ticket  绑定信息到上级用户
-                        String subscribeEvent = wxMessageEvenService.scanSubscribeEvent(fromUserName, jsonObjectData.getStr("Ticket"),this.getGzhToken(),userInfo.getNickName());
+                        String subscribeEvent = wxMessageEvenService.scanSubscribeEvent(fromUserName, jsonObjectData.getStr("EventKey"),this.getGzhToken(),userInfo.getNickName());
                         return MessageUtil.initText(fromUserName,toUserName,subscribeEvent);
 
                     }else {
-                        return MessageUtil.initText(fromUserName, toUserName, jsonObj.getString("nickname")+":关注事件");
+                        return MessageUtil.initText(fromUserName, toUserName, "关注事件");
                     }
 
                 }  else if (MessageUtil.MESSAGE_UNSUBSCRIBE.equals(event)) { // 取消订阅事件
@@ -163,7 +176,14 @@ public class WxGzhServiceImpl implements IWxGzhService {
                     log.info("3.3.....click:" + jsonObjectData.get("EventKey"));
                     //判断事件KEY值,与自定义菜单接口中KEY值对应
                     if ("generateTicket".equals(jsonObjectData.get("EventKey"))){ //获取分销二维码
-                        String mediaId = wxMessageEvenService.gainTicketEvent(fromUserName, this.getGzhToken());
+                        //先判定之前是否存在永久码,若存在,则返回相应的素材id
+                        WxForeverCode wxForeverCode = wxForeverCodeService.getOne(new QueryWrapper<WxForeverCode>().eq("openid",fromUserName));
+                        if (wxForeverCode!=null){
+                            log.info("3.4:返回永久码图片");
+                            String mediaId = wxMessageEvenService.gainTicketEvent(fromUserName, this.getGzhToken(),true,wxForeverCode);
+                            return MessageUtil.initImage(fromUserName,toUserName,mediaId);
+                        }
+                        String mediaId = wxMessageEvenService.gainTicketEvent(fromUserName, this.getGzhToken(), false, wxForeverCode);
                         return MessageUtil.initImage(fromUserName,toUserName,mediaId);
                     }
 
@@ -177,5 +197,9 @@ public class WxGzhServiceImpl implements IWxGzhService {
         return null;
     }
 
+    public static void main(String[] args) {
+        System.out.println("qrscene_ovKTX5-FKLF6_sgTtCIXpG_lz3PY".substring(8));
+    }
+
 
 }

+ 71 - 27
twzd-service/src/main/java/com/miaxis/wx/service/impl/WxMessageEvenServiceImpl.java

@@ -8,7 +8,6 @@ import cn.hutool.extra.qrcode.QrCodeUtil;
 import cn.hutool.extra.qrcode.QrConfig;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.miaxis.common.constant.Constants;
 import com.miaxis.common.utils.http.HttpUtils;
 import com.miaxis.feign.dto.WxGzhMini;
 import com.miaxis.feign.dto.WxMessageCusom;
@@ -17,6 +16,8 @@ import com.miaxis.feign.dto.WxQrTicket;
 import com.miaxis.feign.service.IWxSendService;
 import com.miaxis.spread.domain.WxSpreadRelation;
 import com.miaxis.spread.service.IWxSpreadRelationService;
+import com.miaxis.wx.domain.WxForeverCode;
+import com.miaxis.wx.service.IWxForeverCodeService;
 import com.miaxis.wx.service.IWxMessageEvenService;
 import com.miaxis.wx.service.IWxTicketService;
 import lombok.RequiredArgsConstructor;
@@ -30,7 +31,6 @@ import java.io.File;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
-import java.util.concurrent.TimeUnit;
 
 /**
  * @author wwl
@@ -42,6 +42,8 @@ import java.util.concurrent.TimeUnit;
 @RequiredArgsConstructor
 public class WxMessageEvenServiceImpl implements IWxMessageEvenService {
 
+    private final static Integer expireTime = 2592000;//30天
+
     private final RedisTemplate redisTemplate;
 
     private final IWxSendService wxSendService;
@@ -50,6 +52,8 @@ public class WxMessageEvenServiceImpl implements IWxMessageEvenService {
 
     private final IWxSpreadRelationService wxSpreadRelationService;
 
+    private final IWxForeverCodeService wxForeverCodeService;
+
     @Value("${file.ticketPath}")
     private String ticketPath;
 
@@ -69,20 +73,19 @@ public class WxMessageEvenServiceImpl implements IWxMessageEvenService {
     /**
      * 扫码关注事件
      * @param fromUserName 发送方帐号(一个OpenID)
-     * @param ticket 二维码的ticket
+     * @param eventKey
      * @param token 凭证
      * @param userName 微信名称
      * @return
      */
     @Override
-    public String scanSubscribeEvent(String fromUserName, String ticket,String token,String userName) {
+    public String scanSubscribeEvent(String fromUserName, String eventKey,String token,String userName) {
 
         String message = "";
         //判断是否存在父、子级推广关系
         List<WxSpreadRelation> spreadRelations = wxSpreadRelationService.list(new QueryWrapper<WxSpreadRelation>().eq("openid", fromUserName));
         List<WxSpreadRelation> spreads = wxSpreadRelationService.list(new QueryWrapper<WxSpreadRelation>().eq("parent_openid", fromUserName));
-        String openid = (String) redisTemplate.opsForValue().get(Constants.GZH_TICKET_KEY + ticket);
-
+        String openid = eventKey.substring(8);
         if (spreadRelations.isEmpty() && spreads.isEmpty()){
             //保存推广关系表
             WxSpreadRelation wxSpreadRelation = new WxSpreadRelation();
@@ -107,32 +110,47 @@ public class WxMessageEvenServiceImpl implements IWxMessageEvenService {
      * click获取推广二维码事件
      * @param fromUserName 发送方帐号(一个OpenID)
      * @param token 凭证
+     * @param wxForeverCode
      * @return
      */
     @Override
-    public String gainTicketEvent(String fromUserName,String token) {
+    public String gainTicketEvent(String fromUserName, String token, boolean isForever, WxForeverCode wxForeverCode) {
 
         //发送客服信息
         messageCustomSend(fromUserName,token);
 
         // 根据fromUserName查询缓存 判断用户推广码是否过期
-        if (redisTemplate.hasKey(Constants.GZH_MATERIAL_KEY + fromUserName)){
-            String mediaId = (String) redisTemplate.opsForValue().get(Constants.GZH_MATERIAL_KEY + fromUserName);
-            return mediaId;
+//        if (redisTemplate.hasKey(Constants.GZH_MATERIAL_KEY + fromUserName)){
+//            String mediaId = (String) redisTemplate.opsForValue().get(Constants.GZH_MATERIAL_KEY + fromUserName);
+//            return mediaId;
+//        }
+        String url = null ;
+        if (wxForeverCode != null && wxForeverCode.getUrl() != null){
+            url = wxForeverCode.getUrl();
+        }else{
+            //生成带参数临时二维码ticket
+
+            WxQrTicket wxQrTicket = null ;
+            if (isForever){
+                wxQrTicket = createForeverTicket(fromUserName);
+            }else{
+                wxQrTicket = createShortTimeTicket(fromUserName);
+            }
+
+            String wxTicketResult = wxSendService.generateTicket(token, wxQrTicket);
+            JSONObject jsonStr = JSONObject.parseObject(wxTicketResult);
+            log.info("---------ticket-------" + jsonStr);
+            if (isForever){
+                //更新口令数据对象
+                wxForeverCode.setOpenid(fromUserName);
+                // wxForeverCode.setNickName(jsonObj.getString("nickname"));
+                wxForeverCode.setUrl(jsonStr.getString("url"));
+                wxForeverCodeService.updateById(wxForeverCode);
+            }
+
+            url = jsonStr.getString("url");
         }
 
-        //生成带参数二维码ticket(永久)
-        WxQrTicket wxQrTicket = new WxQrTicket();
-        wxQrTicket.setExpire_seconds(259200);//3天
-        wxQrTicket.setAction_name("QR_SCENE");//临时
-        JSONObject jsonObject1 = new JSONObject();
-        JSONObject jsonObject2 = new JSONObject();
-        jsonObject1.put("scene_id","123");
-        jsonObject2.put("scene",jsonObject1);
-        wxQrTicket.setAction_info(jsonObject2);
-        String wxTicketResult = wxSendService.generateTicket(token, wxQrTicket);
-        JSONObject jsonStr = JSONObject.parseObject(wxTicketResult);
-        log.info("---------ticket-------" + jsonStr);
 
         //获取用户信息
         String userInfoResult = wxSendService.userInfo(token, fromUserName, "zh_CN");
@@ -141,7 +159,7 @@ public class WxMessageEvenServiceImpl implements IWxMessageEvenService {
 
         //根据ticket生成二维码图片存储
         File ticketFile = QrCodeUtil.generate(
-                jsonStr.getString("url"), //二维码内容
+                url, //二维码内容
                 QrConfig.create().setImg(ticketPath + "logo.jpg"), //附带logo
                 FileUtil.file(ticketPath + fromUserName + ".jpg")//写出到的文件
         );
@@ -166,14 +184,17 @@ public class WxMessageEvenServiceImpl implements IWxMessageEvenService {
         );
 
         DateTime date = DateUtil.date();
-        Date newDate = DateUtil.offsetDay(date, 3);
+        Date newDate = DateUtil.offsetDay(date, 30);
         String dateStr = DateUtil.format(newDate, "yyyy-MM-dd");
+        if (isForever){
+            dateStr = "永久";
+        }
         log.info(dateStr);
 
         ImgUtil.pressText(
                 FileUtil.file(ticketPath+fromUserName+"_text1.jpg"),
                 FileUtil.file(ticketPath+fromUserName+"_text2.jpg"),
-                "二维码有效期:"+dateStr, Color.black, //文字
+                "二维码有效期:"+dateStr, Color.black, //文字
                 new Font("黑体", Font.BOLD, 28), //字体
                 0, //x坐标修正值。 默认在中间,偏移量相对于中间偏移
                 -80, //y坐标修正值。 默认在中间,偏移量相对于中间偏移
@@ -191,8 +212,8 @@ public class WxMessageEvenServiceImpl implements IWxMessageEvenService {
             log.info("------result:" + resultJSON);
 
             //缓存用户推广码相关信息
-            redisTemplate.opsForValue().set(Constants.GZH_TICKET_KEY+jsonStr.getString("ticket"),fromUserName,259200, TimeUnit.SECONDS);
-            redisTemplate.opsForValue().set(Constants.GZH_MATERIAL_KEY+fromUserName,resultJSON.getString("media_id"),259200, TimeUnit.SECONDS);
+//            redisTemplate.opsForValue().set(Constants.GZH_TICKET_KEY+jsonStr.getString("ticket"),fromUserName,259200, TimeUnit.SECONDS);
+//            redisTemplate.opsForValue().set(Constants.GZH_MATERIAL_KEY+fromUserName,resultJSON.getString("media_id"),259200, TimeUnit.SECONDS);
 
             //删除服务器文件
             File imgFile = new File(ticketPath + fromUserName+"_img.jpg");
@@ -227,6 +248,29 @@ public class WxMessageEvenServiceImpl implements IWxMessageEvenService {
         return null;
     }
 
+    private WxQrTicket createForeverTicket(String fromUserName) {
+        WxQrTicket wxQrTicket = new WxQrTicket();
+        wxQrTicket.setAction_name("QR_LIMIT_STR_SCENE");//临时字符串参数
+        JSONObject jsonObject1 = new JSONObject();
+        JSONObject jsonObject2 = new JSONObject();
+        jsonObject1.put("scene_str",fromUserName);
+        jsonObject2.put("scene",jsonObject1);
+        wxQrTicket.setAction_info(jsonObject2);
+        return wxQrTicket;
+    }
+
+    private WxQrTicket createShortTimeTicket(String fromUserName) {
+        WxQrTicket wxQrTicket = new WxQrTicket();
+        wxQrTicket.setExpire_seconds(expireTime);
+        wxQrTicket.setAction_name("QR_STR_SCENE");//临时字符串参数
+        JSONObject jsonObject1 = new JSONObject();
+        JSONObject jsonObject2 = new JSONObject();
+        jsonObject1.put("scene_str",fromUserName);
+        jsonObject2.put("scene",jsonObject1);
+        wxQrTicket.setAction_info(jsonObject2);
+        return wxQrTicket;
+    }
+
 
     /**
      * 发送客服消息

+ 32 - 0
twzd-service/src/main/resources/mapper/wx/WxForeverCodeMapper.xml

@@ -0,0 +1,32 @@
+<?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">
+<mapper namespace="com.miaxis.wx.mapper.WxForeverCodeMapper">
+
+    <resultMap type="WxForeverCode" id="WxForeverCodeResult">
+        <result property="id"    column="id"    />
+        <result property="openid"    column="openid"    />
+        <result property="code"    column="code"    />
+        <result property="nickName"    column="nick_name"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="updateTime"    column="update_time"    />
+        <result property="status"    column="status"    />
+    </resultMap>
+
+    <sql id="selectWxForeverCodeVo">
+        select * from wx_forever_code
+    </sql>
+
+    <select id="selectWxForeverCodeList" parameterType="WxForeverCode" resultMap="WxForeverCodeResult">
+        <include refid="selectWxForeverCodeVo"/>
+        <where>
+            <if test="openid != null  and openid != ''"> and openid = #{openid}</if>
+            <if test="code != null  and code != ''"> and code = #{code}</if>
+            <if test="nickName != null "> and nick_name like concat('%', #{nickName}, '%')</if>
+            <if test="status != null "> and status = #{status}</if>
+        </where>
+        order by create_time desc
+    </select>
+
+</mapper>