diff --git a/hai-cweb/src/main/java/com/cweb/controller/HighUserController.java b/hai-cweb/src/main/java/com/cweb/controller/HighUserController.java index 6a0fa5ae..7691bfef 100644 --- a/hai-cweb/src/main/java/com/cweb/controller/HighUserController.java +++ b/hai-cweb/src/main/java/com/cweb/controller/HighUserController.java @@ -148,7 +148,7 @@ public class HighUserController { if (StringUtils.isBlank(body.getString("password")) || body.getString("password").length() != 6){ log.error("HighUserController --> setUserPayPwd() error!", "请设置6位支付密码"); - throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "请设置6支付密码"); + throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "请设置6位支付密码"); } // 查询用户密码 diff --git a/hai-service/src/main/java/com/hai/common/utils/WxUtils.java b/hai-service/src/main/java/com/hai/common/utils/WxUtils.java index 6aac9c4c..874dcae7 100644 --- a/hai-service/src/main/java/com/hai/common/utils/WxUtils.java +++ b/hai-service/src/main/java/com/hai/common/utils/WxUtils.java @@ -7,25 +7,21 @@ import com.hai.common.pay.util.sdk.WXPayXmlUtil; import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.io.naming.NoNameCoder; import com.thoughtworks.xstream.io.xml.XppDriver; + import net.sf.cglib.beans.BeanMap; import org.apache.commons.lang3.StringUtils; -import org.apache.http.conn.ssl.SSLConnectionSocketFactory; -import org.apache.http.conn.ssl.SSLContexts; + import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSocket; -import javax.net.ssl.SSLSocketFactory; + import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; -import java.io.File; -import java.io.FileInputStream; + import java.io.StringWriter; -import java.security.KeyStore; import java.security.MessageDigest; import java.security.SecureRandom; import java.util.*; @@ -504,4 +500,44 @@ public class WxUtils { } } + /** + * 用SHA1算法生成安全签名 + * @param token 票据 + * @param timestamp 时间戳 + * @param nonce 随机字符串 + * @return 安全签名 + * @throws Exception + */ + public static String getSHA1(String token, String timestamp, String nonce) throws Exception + { + try { + String[] array = new String[] { token, timestamp, nonce}; + StringBuffer sb = new StringBuffer(); + // 字符串排序 + Arrays.sort(array); + for (int i = 0; i < 3; i++) { + sb.append(array[i]); + } + String str = sb.toString(); + // SHA1签名生成 + MessageDigest md = MessageDigest.getInstance("SHA-1"); + md.update(str.getBytes()); + byte[] digest = md.digest(); + + StringBuffer hexstr = new StringBuffer(); + String shaHex = ""; + for (int i = 0; i < digest.length; i++) { + shaHex = Integer.toHexString(digest[i] & 0xFF); + if (shaHex.length() < 2) { + hexstr.append(0); + } + hexstr.append(shaHex); + } + return hexstr.toString(); + } catch (Exception e) { + e.printStackTrace(); + throw new Exception(String.format("Invalid sign_type: %s")); + } + } + } diff --git a/hai-service/src/main/java/com/hai/service/CommonService.java b/hai-service/src/main/java/com/hai/service/CommonService.java index e79dfd4a..a2ed2a4d 100644 --- a/hai-service/src/main/java/com/hai/service/CommonService.java +++ b/hai-service/src/main/java/com/hai/service/CommonService.java @@ -15,6 +15,8 @@ import com.hai.model.IndexCountModel; import com.hai.model.LineCountModel; import com.hai.model.OrderCountModel; import com.hai.model.OrderSumModel; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket; import org.apache.ibatis.type.BigDecimalTypeHandler; import java.math.BigDecimal; @@ -293,4 +295,5 @@ public interface CommonService { */ ApiCity findCityByName(String name); + } diff --git a/hai-service/src/main/java/com/hai/service/impl/CommonServiceImpl.java b/hai-service/src/main/java/com/hai/service/impl/CommonServiceImpl.java index 25e37784..6ff7a0ed 100644 --- a/hai-service/src/main/java/com/hai/service/impl/CommonServiceImpl.java +++ b/hai-service/src/main/java/com/hai/service/impl/CommonServiceImpl.java @@ -17,7 +17,9 @@ import com.hai.service.CommonService; import com.hai.service.HighOrderService; import com.hai.service.HighUserService; import com.hai.service.SecConfigService; + import org.apache.commons.lang3.StringUtils; + import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; @@ -40,7 +42,7 @@ public class CommonServiceImpl implements CommonService { private long lastReadTime = 0; private long regionLastReadTime = 0; - + @Resource private SecRegionMapper regionMapper; @@ -694,5 +696,4 @@ public class CommonServiceImpl implements CommonService { } - } diff --git a/v1/src/main/java/com/v1/config/WeChatQrcodeUtils.java b/v1/src/main/java/com/v1/config/WeChatQrcodeUtils.java new file mode 100644 index 00000000..ced8374d --- /dev/null +++ b/v1/src/main/java/com/v1/config/WeChatQrcodeUtils.java @@ -0,0 +1,121 @@ +package com.v1.config; + + +import lombok.extern.slf4j.Slf4j; +import me.chanjar.weixin.common.error.WxErrorException; +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.Component; + +import javax.annotation.Resource; +import java.io.File; + +/** + * @serviceName WeChatQrcodeUtils.java + * @author Sum1Dream + * @version 1.0.0 + * @Description // 生成带参数的二维码 + * @createTime 16:11 2022/9/2 + **/ +@Slf4j +@Component +public class WeChatQrcodeUtils { + + @Autowired + private WxMpService wxMpService; + + /** + *
+     * 创建临时二维码ticket
+     * @param sceneId       场景值ID,临时二维码时为32位非0整型
+     * @param expireSeconds 该二维码有效时间,以秒为单位。 最大不超过2592000(即30天),此字段如果不填,则默认有效期为30秒。
+     * @auther: cao_wencao
+     * @date: 2019/2/18 16:58
+     * 
+ */ + public WxMpQrCodeTicket qrCodeCreateTmpTicket(int sceneId, Integer expireSeconds) throws WxErrorException { + WxMpQrCodeTicket wxMpQrCodeTicket = wxMpService.getQrcodeService().qrCodeCreateTmpTicket(sceneId, expireSeconds); + return wxMpQrCodeTicket; + } + + /** + *
+     * 创建临时二维码ticket
+     * @param sceneStr      场景值ID(字符串形式的ID),字符串类型,长度限制为1到64
+     * @param expireSeconds 该二维码有效时间,以秒为单位。 最大不超过2592000(即30天),此字段如果不填,则默认有效期为30秒。
+     * @auther: cao_wencao
+     * @date: 2019/2/18 17:01
+     * 
+ */ + public WxMpQrCodeTicket qrCodeCreateTmpTicket(String sceneStr, Integer expireSeconds) throws WxErrorException { + WxMpQrCodeTicket wxMpQrCodeTicket = wxMpService.getQrcodeService().qrCodeCreateTmpTicket(sceneStr, expireSeconds); + return wxMpQrCodeTicket; + } + + /** + *
+     * 创建永久二维码ticket
+     * @param sceneId 场景值ID,最大值为100000(目前参数只支持1--100000)
+     * @auther: cao_wencao
+     * @date: 2019/2/18 17:03
+     * 
+ */ + public WxMpQrCodeTicket qrCodeCreateLastTicket(int sceneId) throws WxErrorException { + return wxMpService.getQrcodeService().qrCodeCreateLastTicket(sceneId); + } + + /** + *
+     * 创建永久字符串二维码ticket
+     * @param sceneStr 参数。字符串类型长度现在为1到64
+     * @auther: cao_wencao
+     * @date: 2019/2/18 17:05
+     * 
+ */ + public WxMpQrCodeTicket qrCodeCreateLastTicket(String sceneStr) throws WxErrorException { + return wxMpService.getQrcodeService().qrCodeCreateLastTicket(sceneStr); + } + + /** + *
+     * 换取二维码图片文件,jpg格式
+     * @param ticket 二维码ticket
+     * @auther: cao_wencao
+     * @date: 2019/2/18 17:07
+     * 
+ */ + public File qrCodePicture(WxMpQrCodeTicket ticket) throws WxErrorException { + return wxMpService.getQrcodeService().qrCodePicture(ticket); + + } + + /** + *
+     * 换取二维码图片url地址(可以选择是否生成压缩的网址)
+     * @param ticket       二维码ticket
+     * @param needShortUrl 是否需要压缩的二维码地址
+     * @auther: cao_wencao
+     * @date: 2019/2/18 17:10
+     * 
+ */ + public String qrCodePictureUrl(String ticket, boolean needShortUrl) throws WxErrorException { + String qrCodeUrl = wxMpService.getQrcodeService().qrCodePictureUrl(ticket, needShortUrl); + return qrCodeUrl; + } + + /** + *
+     * 换取二维码图片url地址
+     * @param ticket 二维码ticket
+     * @auther: cao_wencao
+     * @date: 2019/2/18 17:11
+     * 
+ */ + public String qrCodePictureUrl(String ticket) throws WxErrorException { + String url = wxMpService.getQrcodeService().qrCodePictureUrl(ticket); + return url; + } + + +} diff --git a/v1/src/main/java/com/v1/config/WxConfig.java b/v1/src/main/java/com/v1/config/WxConfig.java new file mode 100644 index 00000000..286afac7 --- /dev/null +++ b/v1/src/main/java/com/v1/config/WxConfig.java @@ -0,0 +1,51 @@ +package com.v1.config; + +import com.hai.config.CommonSysConst; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl; +import me.chanjar.weixin.mp.config.WxMpConfigStorage; +import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * @serviceName .java + * @author Sum1Dream + * @version 1.0.0 + * @Description //TODO + * @createTime 16:24 2022/9/2 + **/ +@Configuration +public class WxConfig { + + + /** + * 微信客户端配置存储 + * + * @return + */ + @Bean + public WxMpConfigStorage wxMpConfigStorage() { + WxMpDefaultConfigImpl configStorage = new WxMpDefaultConfigImpl(); + // 公众号appId + configStorage.setAppId(SysConst.getSysConfig().getWxH5AppId()); + // 公众号appSecret + configStorage.setSecret(SysConst.getSysConfig().getWxH5AppSecret()); + return configStorage; + } + + /** + * @Author Sum1Dream + * @Name wxMpService + * @Description //TODO + * @Date 16:24 2022/9/2 + * @Param [] + * @Return WxMpService + */ + @Bean + public WxMpService wxMpService() { + WxMpService wxMpService = new WxMpServiceImpl(); + wxMpService.setWxMpConfigStorage(wxMpConfigStorage()); + return wxMpService; + } +} diff --git a/v1/src/main/java/com/v1/controller/WxMsgController.java b/v1/src/main/java/com/v1/controller/WxMsgController.java index 1dd3adc2..12e0928d 100644 --- a/v1/src/main/java/com/v1/controller/WxMsgController.java +++ b/v1/src/main/java/com/v1/controller/WxMsgController.java @@ -4,24 +4,35 @@ import com.alibaba.fastjson.JSONObject; import com.hai.common.exception.ErrorCode; import com.hai.common.exception.ErrorHelp; import com.hai.common.exception.SysCode; +import com.hai.common.pay.util.IOUtil; +import com.hai.common.pay.util.XmlUtil; import com.hai.common.utils.HttpsUtils; import com.hai.common.utils.ResponseMsgUtil; import com.hai.common.utils.WxUtils; import com.hai.model.ResponseData; +import com.hai.service.CommonService; import com.v1.config.SysConst; +import com.v1.config.WeChatQrcodeUtils; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; -import me.chanjar.weixin.common.util.crypto.SHA1; + +import me.chanjar.weixin.common.error.WxErrorException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; + +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; +import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; + import java.util.HashMap; import java.util.Map; +import java.util.SortedMap; /** * @author sum1dream @@ -34,31 +45,30 @@ public class WxMsgController { private static Logger log = LoggerFactory.getLogger(ThirdPartyController.class); - @RequestMapping(value = "/verifyWxToken", method = RequestMethod.POST) + @Autowired + private WeChatQrcodeUtils weChatQrcodeUtils; + + + + @RequestMapping(value = "/verifyWxToken", method = RequestMethod.GET) @ResponseBody @ApiOperation(value = "验证servlet") public String verifyWxToken(HttpServletRequest request) { try { - log.info("进入验证servlet!!!!!"); - log.info(String.valueOf(request)); - String msgSignature = request.getParameter("signature"); - String msgTimestamp = request.getParameter("timestamp"); - String msgNonce = request.getParameter("nonce"); - String echoStr = request.getParameter("echoStr"); - - - Map params = new HashMap<>(); - params.put("timestamp", msgTimestamp); - params.put("nonce", msgNonce); - String signatureStr = WxUtils.generateSignature(params); - String sign = SHA1.gen(signatureStr); - - if (msgSignature.equals(sign)) { - log.info("验证通过!!!!!"); - return echoStr; - } - log.info("验证失败!!!!!"); + log.info("进入公众号!!!!!!!"); + // 反馈给微信服务器 + String resXml = ""; + // 微信支付系统发送的数据(格式) + String notifyXml; + notifyXml = IOUtil.inputStreamToString(request.getInputStream(), "UTF-8"); + + log.info("微信支付系统发送的数据:" + notifyXml); + SortedMap map = XmlUtil.parseXmlToTreeMap(notifyXml, "UTF-8"); + + // 区分消息类型 + String msgType = map.get("MsgType"); + log.info("微信支付系统发送的数据:" + msgType); return null; } catch (Exception e) { return null; @@ -89,4 +99,42 @@ public class WxMsgController { } } + /** + *
+     * @desc: 创建生成二维码
+     * @auth: cao_wencao
+     * @date: 2019/4/10 14:00
+     * 
+ */ + + @RequestMapping(value = "/createQrcode", method = RequestMethod.GET) + @ResponseBody + @ApiOperation(value = "创建生成二维码") + public ResponseData createQrcode(@RequestParam(name = "sceneId", required = false) Integer sceneId) { + try { + return ResponseMsgUtil.success(weChatQrcodeUtils.qrCodeCreateLastTicket(sceneId)); + } catch (WxErrorException e) { + return ResponseMsgUtil.exception(e); + } + } + + /** + *
+     * @desc: 通过ticket获取二维码(长链接URL)
+     * @auth: cao_wencao
+     * @date: 2019/4/10 14:00
+     * 
+ */ + @RequestMapping(value = "/getQrcodeUrl", method = RequestMethod.GET) + @ResponseBody + @ApiOperation(value = "创建生成二维码") + public ResponseData getQrcodeUrl(@RequestParam(name = "ticket", required = false) String ticket) { + try { + return ResponseMsgUtil.success(weChatQrcodeUtils.qrCodePictureUrl(ticket)); + } catch (WxErrorException e) { + return ResponseMsgUtil.exception(e); + } + } + + } diff --git a/v1/src/main/resources/dev/config.properties b/v1/src/main/resources/dev/config.properties index a85b033e..b7bbc8e8 100644 --- a/v1/src/main/resources/dev/config.properties +++ b/v1/src/main/resources/dev/config.properties @@ -1,2 +1,2 @@ -wxH5AppId=wxb05f4cb44994a960 -wxH5AppSecret=68b540ebce7a4020420f4e5997b1531b +wxH5AppId=wxa075e8509802f826 +wxH5AppSecret=0e606fc1378d35e359fcf3f15570b2c5