|
@@ -1,31 +1,52 @@
|
|
|
package com.xy.service;
|
|
|
|
|
|
import cn.hutool.core.collection.CollUtil;
|
|
|
+import cn.hutool.core.text.CharSequenceUtil;
|
|
|
+import cn.hutool.core.util.IdUtil;
|
|
|
import cn.hutool.core.util.StrUtil;
|
|
|
import cn.hutool.json.JSONUtil;
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
import com.github.yitter.idgen.YitIdHelper;
|
|
|
+import com.google.common.base.Throwables;
|
|
|
import com.xy.annotation.Lock;
|
|
|
+import com.xy.collections.list.JArrayList;
|
|
|
+import com.xy.collections.list.JList;
|
|
|
+import com.xy.config.WeChatOfficialConfig;
|
|
|
import com.xy.config.WebMqttConfig;
|
|
|
+import com.xy.device.EnumDeviceQrCode;
|
|
|
+import com.xy.device.EnumDeviceType;
|
|
|
+import com.xy.dto.MercDeviceQrConfigDto;
|
|
|
import com.xy.dto.SysWorkUser.AddDto;
|
|
|
import com.xy.dto.SysWorkUser.DelDto;
|
|
|
import com.xy.dto.SysWorkUser.UpdateDto;
|
|
|
import com.xy.dto.UserInfoDto;
|
|
|
+import com.xy.dto.WxServiceMsgDto;
|
|
|
import com.xy.entity.UserInfo;
|
|
|
+import com.xy.error.CommRuntimeException;
|
|
|
import com.xy.mapper.UserInfoMapper;
|
|
|
import com.xy.utils.*;
|
|
|
import io.swagger.annotations.Api;
|
|
|
import io.swagger.annotations.ApiOperation;
|
|
|
import lombok.AllArgsConstructor;
|
|
|
+import lombok.SneakyThrows;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
+import me.chanjar.weixin.mp.api.WxMpMessageHandler;
|
|
|
+import me.chanjar.weixin.mp.api.WxMpMessageRouter;
|
|
|
+import me.chanjar.weixin.mp.api.WxMpService;
|
|
|
+import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.validation.annotation.Validated;
|
|
|
import org.springframework.web.bind.annotation.PostMapping;
|
|
|
import org.springframework.web.bind.annotation.RequestBody;
|
|
|
+import org.springframework.web.bind.annotation.RequestMapping;
|
|
|
|
|
|
+import javax.servlet.http.HttpServletRequest;
|
|
|
import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
|
|
|
import static com.xy.utils.Beans.copy;
|
|
|
import static com.xy.utils.PlusBeans.toIPage;
|
|
@@ -50,6 +71,10 @@ public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> i
|
|
|
|
|
|
private WebMqttConfig webMqttConfig;
|
|
|
|
|
|
+
|
|
|
+ private WeChatOfficialConfig weChatOfficialConfig;
|
|
|
+
|
|
|
+
|
|
|
@Override
|
|
|
@ApiOperation("集合查询")
|
|
|
public R<List<UserInfoDto.Vo>> list(UserInfoDto.SelectListDto selectList) {
|
|
@@ -216,4 +241,143 @@ public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> i
|
|
|
return R.ok();
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+ @SneakyThrows
|
|
|
+ @PostMapping("wxQrCode")
|
|
|
+ @ApiOperation("获取微信服务号二维码-扫码关注公众号并绑定")
|
|
|
+ public R<UserInfoDto.WxQrCodeVO> getQrCode(@RequestBody @Validated UserInfoDto.WxQrCode wxQrCode) {
|
|
|
+ WxMpService wxMpService = weChatOfficialConfig.getWxMpService();
|
|
|
+ if (wxMpService == null) {
|
|
|
+ throw new CommRuntimeException("获取微信公众号配置信息失败!");
|
|
|
+ }
|
|
|
+ //指定用户
|
|
|
+ String userId = wxQrCode.getUserId();
|
|
|
+ if (StrUtil.isEmpty(userId)) {
|
|
|
+ //当前登录用户
|
|
|
+ userId = AuthorizeUtils.getLoginId(String.class);
|
|
|
+ }
|
|
|
+ WxMpQrCodeTicket ticket = wxMpService.getQrcodeService().qrCodeCreateTmpTicket(userId, 2592000);
|
|
|
+ String tk = ticket.getTicket();
|
|
|
+ String url = wxMpService.getQrcodeService().qrCodePictureUrl(tk);
|
|
|
+ JList<String> contents = new JArrayList<>();
|
|
|
+ contents.set(url);
|
|
|
+ JList<String> text = new JArrayList<>();
|
|
|
+ text.set("使用微信[扫一扫]关注");
|
|
|
+ List<String> base64s = QRCodeUtils.create(contents, 400, 400, "back1.png", text).base64();
|
|
|
+ UserInfoDto.WxQrCodeVO vo = new UserInfoDto.WxQrCodeVO();
|
|
|
+ log.info("获取微信服务号二维码 usrId:{},tk:{}", userId, tk);
|
|
|
+ return R.ok(vo.setImgList(base64s).setTicket(tk));
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private Map<String, WxMpMessageHandler> wxMpMessageHandlers;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 接收微信的事件消息
|
|
|
+ * https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Access_Overview.html
|
|
|
+ *
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @RequestMapping(value = "/receipt", produces = {"application/xml; charset=UTF-8"})
|
|
|
+ @ApiOperation("接收微信的事件消息")
|
|
|
+ public String receiptMessage(@RequestBody(required = false) WxServiceMsgDto wxServiceMsgDto, HttpServletRequest request) {
|
|
|
+
|
|
|
+ WxMpService wxMpService = weChatOfficialConfig.getWxMpService();
|
|
|
+ if (wxMpService == null) {
|
|
|
+ throw new CommRuntimeException("获取微信公众号配置信息失败!");
|
|
|
+ }
|
|
|
+ String echoStr = request.getParameter(WeChatOfficialConfig.ECHO_STR);
|
|
|
+ // echoStr!=null,说明只是微信调试的请求
|
|
|
+ if (CharSequenceUtil.isNotBlank(echoStr)) {
|
|
|
+ return echoStr;
|
|
|
+ }
|
|
|
+ String signature = request.getParameter(WeChatOfficialConfig.SIGNATURE);
|
|
|
+ String nonce = request.getParameter(WeChatOfficialConfig.NONCE);
|
|
|
+ String timestamp = request.getParameter(WeChatOfficialConfig.TIMESTAMP);
|
|
|
+ if (!wxMpService.checkSignature(timestamp, nonce, signature)) {
|
|
|
+ throw new CommRuntimeException("接收微信的事件消息,验签异常!");
|
|
|
+ }
|
|
|
+ log.info("接收微信的事件消息:{}", wxServiceMsgDto);
|
|
|
+ //处理带参数请求
|
|
|
+ if (null != wxServiceMsgDto &&
|
|
|
+ !StrUtil.isEmpty(wxServiceMsgDto.getMsgType()) &&
|
|
|
+ !StrUtil.isEmpty(wxServiceMsgDto.getEvent()) &&
|
|
|
+ !StrUtil.isEmpty(wxServiceMsgDto.getEventKey()) && !wxServiceMsgDto.getEventKey().equals("null") &&
|
|
|
+ (wxServiceMsgDto.getEventKey().equals("subscribe") || wxServiceMsgDto.getEvent().equals("SCAN"))
|
|
|
+ ) {
|
|
|
+
|
|
|
+ //关注
|
|
|
+ if (wxServiceMsgDto.getEvent().equals("subscribe")) {
|
|
|
+ log.info("关注: " + wxServiceMsgDto.getFromUserName());
|
|
|
+ setCacheTicket("1", wxServiceMsgDto.getFromUserName());
|
|
|
+ if (wxServiceMsgDto.getEventKey().contains("FenXiangMa")) {
|
|
|
+ log.info("优惠券领取");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //扫码
|
|
|
+ if (wxServiceMsgDto.getEvent().equals("SCAN")) {
|
|
|
+ log.info("扫码: " + wxServiceMsgDto.getFromUserName());
|
|
|
+ if (wxServiceMsgDto.getEventKey().contains("YaoQingMa")) {
|
|
|
+ log.info("新用户邀请");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ log.info("参数: " + wxServiceMsgDto.getEventKey());
|
|
|
+ }
|
|
|
+ return "";
|
|
|
+
|
|
|
+
|
|
|
+//
|
|
|
+// String encryptType = CharSequenceUtil.isBlank(request.getParameter(WeChatOfficialConfig.ENCRYPT_TYPE)) ? WeChatOfficialConfig.RAW : request.getParameter(WeChatOfficialConfig.ENCRYPT_TYPE);
|
|
|
+// if (WeChatOfficialConfig.RAW.equals(encryptType)) {
|
|
|
+// WxMpXmlMessage inMessage = WxMpXmlMessage.fromXml(request.getInputStream());
|
|
|
+// log.info("raw inMessage:{}", JSON.toJSONString(inMessage));
|
|
|
+// WxMpXmlOutMessage outMessage = weChatOfficialConfig.getWxMpMessageRouter().route(inMessage);
|
|
|
+// return outMessage.toXml();
|
|
|
+// } else if (WeChatOfficialConfig.AES.equals(encryptType)) {
|
|
|
+// String msgSignature = request.getParameter(WeChatOfficialConfig.MSG_SIGNATURE);
|
|
|
+// WxMpXmlMessage inMessage = WxMpXmlMessage.fromEncryptedXml(request.getInputStream(), weChatOfficialConfig.getConfig(), timestamp, nonce, msgSignature);
|
|
|
+// log.info("aes inMessage:{}", JSON.toJSONString(inMessage));
|
|
|
+// WxMpXmlOutMessage outMessage = weChatOfficialConfig.getWxMpMessageRouter().route(inMessage);
|
|
|
+// return outMessage.toEncryptedXml(weChatOfficialConfig.getConfig());
|
|
|
+// }
|
|
|
+// return "ok";
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 缓存ticket
|
|
|
+ *
|
|
|
+ * @param tk
|
|
|
+ * @param openId
|
|
|
+ */
|
|
|
+ public static void setCacheTicket(String tk, String openId) {
|
|
|
+ RedisService<String> redisService = SpringBeanUtils.getBean(RedisService.class);
|
|
|
+ redisService.set("wechat:scan:ticket:" + tk, openId, 3600);//1h
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取tk
|
|
|
+ *
|
|
|
+ * @param tk
|
|
|
+ * @return {@link String}
|
|
|
+ */
|
|
|
+ public static String getCacheTicket(String tk) {
|
|
|
+ RedisService<String> redisService = SpringBeanUtils.getBean(RedisService.class);
|
|
|
+ return redisService.get("wechat:scan:ticket:" + tk);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 刪除ticket
|
|
|
+ *
|
|
|
+ * @param tk
|
|
|
+ */
|
|
|
+ public static void delCacheTicket(String tk) {
|
|
|
+ RedisService<String> redisService = SpringBeanUtils.getBean(RedisService.class);
|
|
|
+ redisService.remove("wechat:scan:ticket:" + tk);
|
|
|
+ }
|
|
|
+
|
|
|
}
|