diff --git a/util/src/main/java/com/ccsens/util/CodeError.java b/util/src/main/java/com/ccsens/util/CodeError.java index 23e59d42..b3b90dfb 100644 --- a/util/src/main/java/com/ccsens/util/CodeError.java +++ b/util/src/main/java/com/ccsens/util/CodeError.java @@ -10,6 +10,7 @@ public class CodeError { public static final Code SUCCESS = new Code(200, "ok", true); public static final Code SYS_ERROR = new Code(500, "网络繁忙,请您稍后重试", false); public static final Code THIRD_ERROR = new Code(-1, "调用第三方刚接口异常", false); + public static final Code PARAM_ERROR = new Code(1, "参数异常", false); @Getter public static class Code{ diff --git a/util/src/main/java/com/ccsens/util/enterprisewx/SHA1.java b/util/src/main/java/com/ccsens/util/enterprisewx/SHA1.java index fe58515d..38a5a2fb 100644 --- a/util/src/main/java/com/ccsens/util/enterprisewx/SHA1.java +++ b/util/src/main/java/com/ccsens/util/enterprisewx/SHA1.java @@ -9,6 +9,7 @@ package com.ccsens.util.enterprisewx; import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import java.util.Arrays; /** @@ -16,7 +17,7 @@ import java.util.Arrays; * * 计算消息签名接口. */ -class SHA1 { +public class SHA1 { /** * 用SHA1算法生成安全签名 @@ -38,24 +39,28 @@ class SHA1 { 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(); + return getSha1(str); } catch (Exception e) { e.printStackTrace(); throw new AesException(AesException.ComputeSignatureError); } } + + public static String getSha1(String str) throws NoSuchAlgorithmException { + // 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(); + } } diff --git a/wechatutil/src/main/java/com/ccsens/wechatutil/bean/dto/wxmini/NoticeDto.java b/wechatutil/src/main/java/com/ccsens/wechatutil/bean/dto/wxmini/NoticeDto.java new file mode 100644 index 00000000..629efc8d --- /dev/null +++ b/wechatutil/src/main/java/com/ccsens/wechatutil/bean/dto/wxmini/NoticeDto.java @@ -0,0 +1,75 @@ +package com.ccsens.wechatutil.bean.dto.wxmini; + +import cn.hutool.core.util.ArrayUtil; +import com.ccsens.util.enterprisewx.SHA1; +import io.swagger.annotations.ApiModelProperty; +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 + public static class Notice { + /** + * 小程序的原始ID + */ + private String ToUserName; + /** + * 发送者的openid + */ + private String FromUserName; + private String CreateTime; + /** + * text: 文本 Content + * image:PicUrl 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; + /** + * 图片消息媒体id,可以调用[获取临时素材]((getTempMedia)接口拉取数据。 + */ + private String MediaId; + private String Title; + private String AppId; + private String PagePath; + private String ThumbUrl; + private String ThumbMediaId; + } +} diff --git a/wechatutil/src/main/java/com/ccsens/wechatutil/bean/vo/wxmini/Custom.java b/wechatutil/src/main/java/com/ccsens/wechatutil/bean/vo/wxmini/Custom.java new file mode 100644 index 00000000..757c7d56 --- /dev/null +++ b/wechatutil/src/main/java/com/ccsens/wechatutil/bean/vo/wxmini/Custom.java @@ -0,0 +1,76 @@ +package com.ccsens.wechatutil.bean.vo.wxmini; + +import lombok.Data; + +/** + * @description: + * @author: whj + * @time: 2021/10/21 16:44 + */ +public class Custom { + + public static enum Type{ + TEXT("text", "发送文本消息"), + IMAGE("image", "发送图片消息"), + LINK("link", "发送图文链接"), + MINI_PROGRAM_PAGE("miniprogrampage", "发送小程序卡片"), + ; + private String type; + private String message; + + Type(String type, String message) { + this.type = type; + this.message = message; + } + + public String getType() { + return type; + } + + public String getMessage() { + return message; + } + } + + @Data + public static class Message{ + private String touser; + private String msgtype; + private Text text; + private Image image; + private Link link; + private MiniProgramPage miniprogrampage; + + } + @Data + public static class Text{ + private String content; + + } + @Data + public static class Image{ + private String media_id; + } + @Data + public static class Link{ + private String title; + private String description; + private String url; + /** + * 图文链接消息的图片链接,支持 JPG、PNG 格式,较好的效果为大图 640 X 320,小图 80 X 80 + */ + private String thumb_url; + } + @Data + public static class MiniProgramPage { + private String title; + /** + * 小程序的页面路径,跟app.json对齐,支持参数,比如pages/index/index?foo=bar + */ + private String pagepath; + /** + * 小程序消息卡片的封面, image 类型的 media_id,通过 新增素材接口 上传图片文件获得,建议大小为 520*416 + */ + private String thumb_media_id; + } +} diff --git a/wechatutil/src/main/java/com/ccsens/wechatutil/wxmini/MiniCustomSendUtil.java b/wechatutil/src/main/java/com/ccsens/wechatutil/wxmini/MiniCustomSendUtil.java new file mode 100644 index 00000000..87032ae1 --- /dev/null +++ b/wechatutil/src/main/java/com/ccsens/wechatutil/wxmini/MiniCustomSendUtil.java @@ -0,0 +1,72 @@ +package com.ccsens.wechatutil.wxmini; + +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSONObject; +import com.ccsens.util.CodeError; +import com.ccsens.util.RestTemplateUtil; +import com.ccsens.util.exception.BaseException; +import com.ccsens.wechatutil.bean.po.WxBaseEntity; +import com.ccsens.wechatutil.bean.vo.wxmini.Custom; +import com.ccsens.wechatutil.wxcommon.WxCommonUtil; +import lombok.extern.slf4j.Slf4j; +import org.apache.poi.ss.formula.functions.T; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +/** + * @description: + * @author: whj + * @time: 2021/10/21 16:31 + */ +@Slf4j +@Component +public class MiniCustomSendUtil { + private static String miniAppId; + private static String miniSecret; + private static final String url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token={}"; + + public static WxBaseEntity send(String openId, Custom.Type type, Object data){ + log.info("发送客服消息:{},{},{}", openId, type, data); + if (StrUtil.isEmpty(openId) || type == null || data == null) { + throw new BaseException(CodeError.PARAM_ERROR); + } + String accessToken = WxCommonUtil.getAccessToken(miniAppId, miniSecret); + String sendUrl = StrUtil.format(url, accessToken); + Custom.Message message = new Custom.Message(); + message.setTouser(openId); + message.setMsgtype(type.getType()); + switch (type) { + case IMAGE: + message.setImage((Custom.Image) data); + break; + case TEXT: + message.setText((Custom.Text) data); + break; + case LINK: + message.setLink((Custom.Link) data); + break; + case MINI_PROGRAM_PAGE: + message.setMiniprogrampage((Custom.MiniProgramPage) data); + break; + default: + throw new BaseException(CodeError.PARAM_ERROR); + } + log.info("发送客服消息路径:{}, 请求:{}", sendUrl, message); + String result = RestTemplateUtil.postBody(sendUrl, message); + log.info("发送客服消息结果:{}", result); + WxBaseEntity wxBaseEntity = JSONObject.parseObject(result, WxBaseEntity.class); + return wxBaseEntity; + } + + + + + @Value("${mini.appId:}") + public void setMiniAppId(String miniAppId) { + MiniCustomSendUtil.miniAppId = miniAppId; + } + @Value("${mini.secret:}") + public void setMiniSecret(String miniSecret) { + MiniCustomSendUtil.miniSecret = miniSecret; + } +}