Browse Source

Merge branch 'master' of ssh://101.201.226.163:50022/ccsens_wiki/ccsens_ptos

master
zy_Java 3 years ago
parent
commit
7036dc170d
  1. 23
      util/src/test/java/com/ccsens/util/JacksonUtilTest.java
  2. 86
      util/src/test/java/com/ccsens/util/NoticeDto.java
  3. 4
      wechatutil/pom.xml
  4. 20
      wechatutil/src/main/java/com/ccsens/wechatutil/WechatutilApplication.java
  5. 6
      wechatutil/src/main/java/com/ccsens/wechatutil/bean/dto/wxmini/NoticeDto.java
  6. 54
      wechatutil/src/main/java/com/ccsens/wechatutil/bean/dto/wxofficial/WxQrCodeDto.java
  7. 25
      wechatutil/src/main/java/com/ccsens/wechatutil/bean/vo/wxofficial/WxQrCodeVo.java
  8. 26
      wechatutil/src/main/java/com/ccsens/wechatutil/util/WeiXinPropUtil.java
  9. 30
      wechatutil/src/main/java/com/ccsens/wechatutil/util/WxConstant.java
  10. 62
      wechatutil/src/main/java/com/ccsens/wechatutil/wxofficial/OfficialQrCodeUtil.java

23
util/src/test/java/com/ccsens/util/JacksonUtilTest.java

@ -0,0 +1,23 @@
package com.ccsens.util;
import org.junit.Test;
import java.io.IOException;
/**
* @description:
* @author: whj
* @time: 2022/3/9 11:36
*/
public class JacksonUtilTest {
@Test
public void test01() throws IOException {
String xml = "<xml><ToUserName><![CDATA[gh_4bbe9a56a99d]]></ToUserName><FromUserName><![CDATA[oVyk85japz_obxoz9SoEAeLSm2fs]]></FromUserName><CreateTime>1646796877</CreateTime><MsgType><![CDATA[event]]></MsgType><Event><![CDATA[subscribe]]></Event><EventKey><![CDATA[qrscene_0]]></EventKey><Ticket><![CDATA[gQHq7zwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAyUnJXRzR3bkZjWUMxN3RnTjF5MVMAAgRdFihiAwSAOgkA]]></Ticket></xml>";
System.out.println(JacksonUtil.xmlToJson(xml));
System.out.println(JacksonUtil.xmlToBean(xml, NoticeDto.Notice.class));
}
}

86
util/src/test/java/com/ccsens/util/NoticeDto.java

@ -0,0 +1,86 @@
package com.ccsens.util;
import cn.hutool.core.util.ArrayUtil;
import com.ccsens.util.enterprisewx.SHA1;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
/**
* @description:
* @author: whj
* @time: 2021/10/21 15:51
*/
public class NoticeDto {
/**
* 微信小程序通知校验
*/
@Data
public static class ValidMsg{
@NotEmpty
private String signature;
@NotEmpty
private String timestamp;
@NotEmpty
private String nonce;
@NotEmpty
private String echostr;
public boolean check(String token) throws NoSuchAlgorithmException {
String[] dict = {token, timestamp, nonce};
Arrays.sort(dict);
String str = ArrayUtil.join(dict, "");
String shaStr = SHA1.getSha1(str);
return signature.equals(shaStr);
}
}
@Data
@JacksonXmlRootElement(localName = "xml")
public static class Notice {
/**
* 小程序的原始ID
*/
@JacksonXmlProperty(localName = "ToUserName")
private String ToUserName;
/**
* 发送者的openid
*/
@JacksonXmlProperty(localName = "FromUserName")
private String FromUserName;
@JacksonXmlProperty(localName = "CreateTime")
private String CreateTime;
/**
* text: 文本 Content
* imagePicUrl MediaId
* miniprogrampage: 小程序卡片 Title AppId PagePath ThumbUrl ThumbMediaId
*/
private String MsgType;
private String Event;
private String SessionFrom;
private String Content;
private String MsgId;
private String PicUrl;
/**事件KEY值,qrscene_为前缀,后面为二维码的参数值*/
private String EventKey;
/**二维码的ticket,可用来换取二维码图片*/
private String Ticket;
/**
* 图片消息媒体id可以调用[获取临时素材]((getTempMedia)接口拉取数据
*/
private String MediaId;
private String Title;
private String AppId;
private String PagePath;
private String ThumbUrl;
private String ThumbMediaId;
}
}

4
wechatutil/pom.xml

@ -16,11 +16,11 @@
<dependencies>
<!--cloud 工具类-->
<dependency>
<!--<dependency>
<artifactId>cloudutil</artifactId>
<groupId>com.ccsensptos</groupId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependency>-->
<!--util 工具类-->
<dependency>
<artifactId>util</artifactId>

20
wechatutil/src/main/java/com/ccsens/wechatutil/WechatutilApplication.java

@ -1,15 +1,15 @@
package com.ccsens.wechatutil;
import com.ccsens.cloudutil.ribbon.RibbonConfiguration;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.FilterType;
import org.springframework.scheduling.annotation.EnableAsync;
//import com.ccsens.cloudutil.ribbon.RibbonConfiguration;
//import org.mybatis.spring.annotation.MapperScan;
//import org.springframework.boot.SpringApplication;
//import org.springframework.boot.autoconfigure.SpringBootApplication;
//import org.springframework.boot.web.servlet.ServletComponentScan;
//import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
//import org.springframework.cloud.openfeign.EnableFeignClients;
//import org.springframework.context.annotation.ComponentScan;
//import org.springframework.context.annotation.FilterType;
//import org.springframework.scheduling.annotation.EnableAsync;
/**
* @author

6
wechatutil/src/main/java/com/ccsens/wechatutil/bean/dto/wxmini/NoticeDto.java

@ -62,6 +62,12 @@ public class NoticeDto {
private String Content;
private String MsgId;
private String PicUrl;
/**事件KEY值,qrscene_为前缀,后面为二维码的参数值*/
private String EventKey;
/**二维码的ticket,可用来换取二维码图片*/
private String Ticket;
/**
* 图片消息媒体id可以调用[获取临时素材]((getTempMedia)接口拉取数据
*/

54
wechatutil/src/main/java/com/ccsens/wechatutil/bean/dto/wxofficial/WxQrCodeDto.java

@ -0,0 +1,54 @@
package com.ccsens.wechatutil.bean.dto.wxofficial;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @description:
* @author: whj
* @time: 2022/3/7 9:09
*/
public class WxQrCodeDto {
@Data
@ApiModel("生成带参数的二维码-公众号")
public static class Create{
@ApiModelProperty("该二维码有效时间,以秒为单位。 最大不超过2592000(即30天),此字段如果不填,则默认有效期为60秒。")
private Long expire_seconds;
@ApiModelProperty("二维码类型,QR_SCENE为临时的整型参数值,QR_STR_SCENE为临时的字符串参数值,QR_LIMIT_SCENE为永久的整型参数值,QR_LIMIT_STR_SCENE为永久的字符串参数值")
private String action_name;
@ApiModelProperty
private ActionInfo action_info;
public Create(){}
public Create(Long expire_seconds, String action_name, Integer scene_id, String scene_str) {
this.expire_seconds = expire_seconds;
this.action_name = action_name;
this.action_info = new ActionInfo();
Scene scene = new Scene();
scene.setScene_id(scene_id);
scene.setScene_str(scene_str);
this.action_info.setScene(scene);
}
}
@Data
@ApiModel("生成带参数的二维码场景值1-公众号")
public static class ActionInfo {
private Scene scene;
}
@Data
@ApiModel("生成带参数的二维码场景值2-公众号")
public static class Scene {
@ApiModelProperty("场景值ID,临时二维码时为32位非0整型,永久二维码时最大值为100000(目前参数只支持1--100000)")
private Integer scene_id;
@ApiModelProperty("场景值ID(字符串形式的ID),字符串类型,长度限制为1到64")
private String scene_str;
}
}

25
wechatutil/src/main/java/com/ccsens/wechatutil/bean/vo/wxofficial/WxQrCodeVo.java

@ -0,0 +1,25 @@
package com.ccsens.wechatutil.bean.vo.wxofficial;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @description:
* @author: whj
* @time: 2022/3/7 9:52
*/
public class WxQrCodeVo {
@Data
@ApiModel("生成带参数的二维码-公众号返回")
public static class QrCodeUrl{
@ApiModelProperty("获取的二维码ticket,凭借此ticket可以在有效时间内换取二维码")
private String ticket;
@ApiModelProperty("该二维码有效时间,以秒为单位。 最大不超过2592000(即30天)")
private Long expire_seconds;
@ApiModelProperty("二维码图片解析后的地址,开发者可根据该地址自行生成需要的二维码图片")
private String url;
}
}

26
wechatutil/src/main/java/com/ccsens/wechatutil/util/WeiXinPropUtil.java

@ -0,0 +1,26 @@
package com.ccsens.wechatutil.util;
import com.ccsens.wechatutil.wxofficial.OfficialAccountSigninUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* @description:
* @author: whj
* @time: 2022/3/4 17:22
*/
@Component
public class WeiXinPropUtil {
public static String appIdOfficial;
public static String secretOfficial;
@Value("${official.appId:}")
public void setAppIdOfficial(String appIdOfficial) {
WeiXinPropUtil.appIdOfficial = appIdOfficial;
}
@Value("${official.secret:}")
public void setApplication(String secretOfficial) {
WeiXinPropUtil.secretOfficial = secretOfficial;
}
}

30
wechatutil/src/main/java/com/ccsens/wechatutil/util/WxConstant.java

@ -1,5 +1,11 @@
package com.ccsens.wechatutil.util;
import cn.hutool.core.util.StrUtil;
import com.ccsens.util.JacksonUtil;
import com.ccsens.util.exception.BaseException;
import com.ccsens.wechatutil.bean.po.WxBaseEntity;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@ -12,10 +18,16 @@ public class WxConstant {
public static final String ANYRING = "anyring";
/*** 小程序登录路径 */
public static final String MINI_PROGRAM_LOGIN = "https://api.weixin.qq.com/sns/jscode2session?appid=%1$s&secret=%2$s&js_code=%3$s&grant_type=%4$s";
/*** 公众号获取accessToken */
public static final String URL_GET_OAUTH2_ACCESS_TOKEN = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%1$s&secret=%2$s&code=%3$s&grant_type=authorization_code";
/*** 公众号发送订阅消息 */
public static final String MESSAGE_TEMPLATE_SEND = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%1$s";
/** 创建二维码 */
public static final String QR_CODE_CREATE = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token={}";
/*** 小程序登录路径 */
public static final String MINI_PROGRAM_LOGIN = "https://api.weixin.qq.com/sns/jscode2session?appid=%1$s&secret=%2$s&js_code=%3$s&grant_type=%4$s";
/*** 通过网页授权和openId获取用户信息 */
public static final String URL_GET_OAUTH2_USER_INFO = "https://api.weixin.qq.com/sns/userinfo?access_token=%1$s&openid=%2$s";
/*** 获取小程序码A */
@ -26,16 +38,12 @@ public class WxConstant {
public static final String URL_GET_WX_CODE_C = "https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token=%1$s";
/*** 小程序获取accessToken */
public static final String URL_GET_ACCESS_TOKEN = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%1$s&secret=%2$s";
/*** 公众号发送订阅消息 */
public static final String MESSAGE_TEMPLATE_SEND = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%1$s";
/*** 小程序发送订阅消息 */
public static final String URL_SEND_SUBSCRIBE_MESSAGE = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=%1$s";
/*** 小程序消息模板--支付 */
public static String SUBSCRIBE_MSG_ID_BUY = "bqdx4FW51G-JLU6HjL6LyvUbjpo4rFK6CPor2-w3VwM";
/*** 小程序消息模板--订单发送 */
public static String SUBSCRIBE_MSG_ID_ORDERSEND = "5-rhM8h3x1W82tHCt18g9iXyGELyUKQtBDZiFjgItOo";
/*** 小程序登录路径内的type */
public static final String GRANT_TYPE = "authorization_code";
@ -106,4 +114,14 @@ public class WxConstant {
}
public static void pageResult(String result) {
try {
if (StrUtil.isEmpty(result) || null == JacksonUtil.jsonToBean(result, WxBaseEntity.class)) {
throw new BaseException(WxCodeError.WX_HTTP_ERROR);
}
} catch (IOException e) {
throw new BaseException(e.getMessage());
}
}
}

62
wechatutil/src/main/java/com/ccsens/wechatutil/wxofficial/OfficialQrCodeUtil.java

@ -0,0 +1,62 @@
package com.ccsens.wechatutil.wxofficial;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.ccsens.util.RestTemplateUtil;
import com.ccsens.wechatutil.bean.dto.wxofficial.WxQrCodeDto;
import com.ccsens.wechatutil.bean.vo.wxofficial.WxQrCodeVo;
import com.ccsens.wechatutil.util.WeiXinPropUtil;
import com.ccsens.wechatutil.util.WxConstant;
import com.ccsens.wechatutil.wxcommon.WxCommonUtil;
import lombok.extern.slf4j.Slf4j;
/**
* @description:
* @author: whj
* @time: 2022/3/4 17:14
*/
@Slf4j
public class OfficialQrCodeUtil {
/**临时的整型参数值*/
public static final String QR_SCENE = "QR_SCENE";
/**临时的字符串参数值*/
public static final String QR_STR_SCENE = "QR_STR_SCENE";
/**永久的整型参数值*/
public static final String QR_LIMIT_SCENE = "QR_LIMIT_SCENE";
/**永久的字符串参数值*/
public static final String QR_LIMIT_STR_SCENE = "QR_LIMIT_STR_SCENE";
/**
* 生成带参数的二维码
* @param expire_seconds 有效时间
* @param action_name 应用名
* @param scene_id 场景值ID临时二维码时为32位非0整型永久二维码时最大值为100000
* @param scene_str 场景值ID字符串形式的ID字符串类型长度限制为1到64
* @return 二维码路径
*/
public static WxQrCodeVo.QrCodeUrl send (Long expire_seconds, String action_name, Integer scene_id, String scene_str){
WxQrCodeDto.Create create = new WxQrCodeDto.Create(expire_seconds, action_name, scene_id, scene_str);
String url = String.format(WxConstant.QR_CODE_CREATE, WxCommonUtil.getAccessToken(WeiXinPropUtil.appIdOfficial, WeiXinPropUtil.secretOfficial));
String response = RestTemplateUtil.postBody(url, create);
log.info("url: {}\nresponse: {}", url, response);
WxConstant.pageResult(response);
return JSONObject.parseObject(response, WxQrCodeVo.QrCodeUrl.class);
}
/**
* 生成带参数的二维码
* @param create 二维码参数
* @param appIdOfficia appId
* @param secretOfficial secret
* @return 二维码路径
*/
public static WxQrCodeVo.QrCodeUrl send (WxQrCodeDto.Create create, String appIdOfficia, String secretOfficial){
String url = StrUtil.format(WxConstant.QR_CODE_CREATE, WxCommonUtil.getAccessToken(appIdOfficia,secretOfficial));
String response = RestTemplateUtil.postBody(url, create);
log.info("url: {}\nresponse: {}", url, response);
WxConstant.pageResult(response);
return JSONObject.parseObject(response, WxQrCodeVo.QrCodeUrl.class);
}
}
Loading…
Cancel
Save