27 changed files with 1271 additions and 7 deletions
@ -0,0 +1,28 @@ |
|||||||
|
package com.mh.common.config.wechat; |
||||||
|
|
||||||
|
import org.springframework.boot.web.client.RestTemplateBuilder; |
||||||
|
import org.springframework.context.annotation.Bean; |
||||||
|
import org.springframework.context.annotation.Configuration; |
||||||
|
import org.springframework.http.client.BufferingClientHttpRequestFactory; |
||||||
|
import org.springframework.http.client.SimpleClientHttpRequestFactory; |
||||||
|
import org.springframework.web.client.RestTemplate; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author LJF |
||||||
|
* @version 1.0 |
||||||
|
* @project EEMCS |
||||||
|
* @description restTemplate配置 |
||||||
|
* @date 2025-06-30 14:35:10 |
||||||
|
*/ |
||||||
|
@Configuration |
||||||
|
public class RestTemplateConfig { |
||||||
|
|
||||||
|
// 配置类中定义Bean(全局禁用分块传输)
|
||||||
|
@Bean |
||||||
|
public RestTemplate restTemplate() { |
||||||
|
return new RestTemplateBuilder() |
||||||
|
.requestFactory(() -> new BufferingClientHttpRequestFactory(new SimpleClientHttpRequestFactory())) |
||||||
|
.build(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,94 @@ |
|||||||
|
package com.mh.common.config.wechat; |
||||||
|
|
||||||
|
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.beans.factory.annotation.Value; |
||||||
|
import org.springframework.context.annotation.Bean; |
||||||
|
import org.springframework.context.annotation.Configuration; |
||||||
|
import org.springframework.stereotype.Component; |
||||||
|
|
||||||
|
import java.net.URLEncoder; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author chison |
||||||
|
* @date 2020-04-03 15:42 |
||||||
|
* @Description 微信网页授权信息配置类 |
||||||
|
*/ |
||||||
|
@Component |
||||||
|
@Configuration |
||||||
|
public class WechatMpConfig { |
||||||
|
|
||||||
|
@Value("${wechat.mpAppId}") |
||||||
|
private String mpAppId; |
||||||
|
@Value("${wechat.mpAppSecret}") |
||||||
|
private String mpAppSecret; |
||||||
|
@Value("${wechat.redirectUri}") |
||||||
|
private String redirectUri; |
||||||
|
@Value("${wechat.authorizedUrl}") |
||||||
|
private String authorizedUrl; |
||||||
|
@Value("${wechat.access_token}") |
||||||
|
private String accessToken; |
||||||
|
@Value("${wechat.userinfo}") |
||||||
|
private String userinfo; |
||||||
|
@Value("${wechat.pushUrl}") |
||||||
|
private String pushUrl; |
||||||
|
@Value("${wechat.baseUrl}") |
||||||
|
private String baseUrl; |
||||||
|
|
||||||
|
public String getBaseUrl() { |
||||||
|
return baseUrl; |
||||||
|
} |
||||||
|
|
||||||
|
public void setBaseUrl(String baseUrl) { |
||||||
|
this.baseUrl = baseUrl; |
||||||
|
} |
||||||
|
|
||||||
|
public String getAuthorizedUrl() { |
||||||
|
return authorizedUrl.replace("mpAppId", mpAppId).replace("REDIRECT_URI", URLEncoder.encode(redirectUri)); |
||||||
|
} |
||||||
|
|
||||||
|
public String getAccessTokenUrl() { |
||||||
|
return accessToken.replace("APPID", mpAppId).replace("SECRET", mpAppSecret); |
||||||
|
} |
||||||
|
|
||||||
|
public String getUserInfo(String accessToken, String openId) { |
||||||
|
return userinfo.replace("ACCESS_TOKEN", accessToken).replace("OPENID", openId); |
||||||
|
} |
||||||
|
|
||||||
|
public String getPushMsgUrl(String accessToken) { |
||||||
|
return pushUrl.replace("ACCESS_TOKEN", accessToken); |
||||||
|
} |
||||||
|
|
||||||
|
public String getMpAppId() { |
||||||
|
return mpAppId; |
||||||
|
} |
||||||
|
|
||||||
|
public String getMpAppSecret() { |
||||||
|
return mpAppSecret; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 配置WxMpService所需信息 |
||||||
|
* |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
@Bean // 此注解指定在Spring容器启动时,就执行该方法并将该方法返回的对象交由Spring容器管理
|
||||||
|
public WxMpService wxMpService() { |
||||||
|
WxMpService wxMpService = new WxMpServiceImpl(); |
||||||
|
// 设置配置信息的存储位置
|
||||||
|
wxMpService.setWxMpConfigStorage(wxMpConfigStorage()); |
||||||
|
|
||||||
|
return wxMpService; |
||||||
|
} |
||||||
|
|
||||||
|
public WxMpConfigStorage wxMpConfigStorage() { |
||||||
|
// 使用这个实现类则表示将配置信息存储在内存中
|
||||||
|
WxMpDefaultConfigImpl wxMpInMemoryConfigStorage = new WxMpDefaultConfigImpl(); |
||||||
|
wxMpInMemoryConfigStorage.setAppId(getMpAppId()); |
||||||
|
wxMpInMemoryConfigStorage.setSecret(getMpAppSecret()); |
||||||
|
|
||||||
|
return wxMpInMemoryConfigStorage; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,62 @@ |
|||||||
|
package com.mh.common.config.wechat; |
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j; |
||||||
|
|
||||||
|
import java.security.MessageDigest; |
||||||
|
import java.security.NoSuchAlgorithmException; |
||||||
|
import java.util.Base64; |
||||||
|
import java.util.Map; |
||||||
|
import java.util.TreeMap; |
||||||
|
|
||||||
|
/** |
||||||
|
* @Author : Rainbow |
||||||
|
* @date : 2024-09-14 |
||||||
|
*/ |
||||||
|
@Slf4j |
||||||
|
public class WechatSignUtil { |
||||||
|
|
||||||
|
/** |
||||||
|
* SHA-1加密 |
||||||
|
* @param params |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static String generateSignature(Map<String, String> params) { |
||||||
|
// 使用TreeMap进行自然排序(按照key的ASCII码排序)
|
||||||
|
TreeMap<String, String> sortedParams = new TreeMap<>(params); |
||||||
|
|
||||||
|
// 拼接字符串
|
||||||
|
StringBuilder stringBuilder = new StringBuilder(); |
||||||
|
for (Map.Entry<String, String> entry : sortedParams.entrySet()) { |
||||||
|
if (stringBuilder.length() > 0) { |
||||||
|
stringBuilder.append("&"); |
||||||
|
} |
||||||
|
stringBuilder.append(entry.getKey()).append("=").append(entry.getValue()); |
||||||
|
} |
||||||
|
String string1 = stringBuilder.toString(); |
||||||
|
|
||||||
|
// SHA-1加密
|
||||||
|
try { |
||||||
|
// 获取SHA-1实例
|
||||||
|
MessageDigest digest = MessageDigest.getInstance("SHA-1"); |
||||||
|
|
||||||
|
// 将输入字符串转换为字节数组
|
||||||
|
byte[] encodedHash = digest.digest(string1.getBytes()); |
||||||
|
|
||||||
|
// 可选:将字节数组转换为Base64字符串,便于显示和传输
|
||||||
|
String base64Encoded = Base64.getEncoder().encodeToString(encodedHash); |
||||||
|
log.info("SHA-1 (Base64 Encoded): {}", base64Encoded); |
||||||
|
|
||||||
|
// 或者,直接以16进制形式输出
|
||||||
|
StringBuilder hexString = new StringBuilder(); |
||||||
|
for (byte b : encodedHash) { |
||||||
|
String hex = Integer.toHexString(0xff & b); |
||||||
|
if(hex.length() == 1) hexString.append('0'); |
||||||
|
hexString.append(hex); |
||||||
|
} |
||||||
|
log.info("SHA-1 (Hexadecimal): {}", hexString); |
||||||
|
return hexString.toString(); |
||||||
|
} catch (NoSuchAlgorithmException e) { |
||||||
|
throw new RuntimeException("SHA-1 algorithm not found", e); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,35 @@ |
|||||||
|
package com.mh.common.core.domain.wechat; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author chison |
||||||
|
* @date 2020-09-14 10:59 |
||||||
|
* @Description |
||||||
|
*/ |
||||||
|
public class First { |
||||||
|
public String value; |
||||||
|
public String color; |
||||||
|
|
||||||
|
public First() { |
||||||
|
} |
||||||
|
|
||||||
|
public First(String value, String color) { |
||||||
|
this.value = value; |
||||||
|
this.color = color; |
||||||
|
} |
||||||
|
|
||||||
|
public String getValue() { |
||||||
|
return value; |
||||||
|
} |
||||||
|
|
||||||
|
public void setValue(String value) { |
||||||
|
this.value = value; |
||||||
|
} |
||||||
|
|
||||||
|
public String getColor() { |
||||||
|
return color; |
||||||
|
} |
||||||
|
|
||||||
|
public void setColor(String color) { |
||||||
|
this.color = color; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,35 @@ |
|||||||
|
package com.mh.common.core.domain.wechat; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author chison |
||||||
|
* @date 2020-09-14 10:59 |
||||||
|
* @Description |
||||||
|
*/ |
||||||
|
public class Key1 { |
||||||
|
public String value; |
||||||
|
public String color; |
||||||
|
|
||||||
|
public Key1() { |
||||||
|
} |
||||||
|
|
||||||
|
public Key1(String value, String color) { |
||||||
|
this.value = value; |
||||||
|
this.color = color; |
||||||
|
} |
||||||
|
|
||||||
|
public String getValue() { |
||||||
|
return value; |
||||||
|
} |
||||||
|
|
||||||
|
public void setValue(String value) { |
||||||
|
this.value = value; |
||||||
|
} |
||||||
|
|
||||||
|
public String getColor() { |
||||||
|
return color; |
||||||
|
} |
||||||
|
|
||||||
|
public void setColor(String color) { |
||||||
|
this.color = color; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,36 @@ |
|||||||
|
package com.mh.common.core.domain.wechat; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author chison |
||||||
|
* @date 2020-09-14 10:59 |
||||||
|
* @Description |
||||||
|
*/ |
||||||
|
public class Key2 { |
||||||
|
|
||||||
|
public String value; |
||||||
|
public String color; |
||||||
|
|
||||||
|
public Key2() { |
||||||
|
} |
||||||
|
|
||||||
|
public Key2(String value, String color) { |
||||||
|
this.value = value; |
||||||
|
this.color = color; |
||||||
|
} |
||||||
|
|
||||||
|
public String getValue() { |
||||||
|
return value; |
||||||
|
} |
||||||
|
|
||||||
|
public void setValue(String value) { |
||||||
|
this.value = value; |
||||||
|
} |
||||||
|
|
||||||
|
public String getColor() { |
||||||
|
return color; |
||||||
|
} |
||||||
|
|
||||||
|
public void setColor(String color) { |
||||||
|
this.color = color; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,36 @@ |
|||||||
|
package com.mh.common.core.domain.wechat; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author chison |
||||||
|
* @date 2020-09-14 11:00 |
||||||
|
* @Description |
||||||
|
*/ |
||||||
|
public class Key3 { |
||||||
|
|
||||||
|
public String value; |
||||||
|
public String color; |
||||||
|
|
||||||
|
public Key3() { |
||||||
|
} |
||||||
|
|
||||||
|
public Key3(String value, String color) { |
||||||
|
this.value = value; |
||||||
|
this.color = color; |
||||||
|
} |
||||||
|
|
||||||
|
public String getValue() { |
||||||
|
return value; |
||||||
|
} |
||||||
|
|
||||||
|
public void setValue(String value) { |
||||||
|
this.value = value; |
||||||
|
} |
||||||
|
|
||||||
|
public String getColor() { |
||||||
|
return color; |
||||||
|
} |
||||||
|
|
||||||
|
public void setColor(String color) { |
||||||
|
this.color = color; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,36 @@ |
|||||||
|
package com.mh.common.core.domain.wechat; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author chison |
||||||
|
* @date 2020-09-14 11:00 |
||||||
|
* @Description |
||||||
|
*/ |
||||||
|
public class Key4 { |
||||||
|
|
||||||
|
public String value; |
||||||
|
public String color; |
||||||
|
|
||||||
|
public Key4() { |
||||||
|
} |
||||||
|
|
||||||
|
public Key4(String value, String color) { |
||||||
|
this.value = value; |
||||||
|
this.color = color; |
||||||
|
} |
||||||
|
|
||||||
|
public String getValue() { |
||||||
|
return value; |
||||||
|
} |
||||||
|
|
||||||
|
public void setValue(String value) { |
||||||
|
this.value = value; |
||||||
|
} |
||||||
|
|
||||||
|
public String getColor() { |
||||||
|
return color; |
||||||
|
} |
||||||
|
|
||||||
|
public void setColor(String color) { |
||||||
|
this.color = color; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,36 @@ |
|||||||
|
package com.mh.common.core.domain.wechat; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author chison |
||||||
|
* @date 2020-09-14 11:00 |
||||||
|
* @Description |
||||||
|
*/ |
||||||
|
public class Key5 { |
||||||
|
|
||||||
|
public String value; |
||||||
|
public String color; |
||||||
|
|
||||||
|
public Key5() { |
||||||
|
} |
||||||
|
|
||||||
|
public Key5(String value, String color) { |
||||||
|
this.value = value; |
||||||
|
this.color = color; |
||||||
|
} |
||||||
|
|
||||||
|
public String getValue() { |
||||||
|
return value; |
||||||
|
} |
||||||
|
|
||||||
|
public void setValue(String value) { |
||||||
|
this.value = value; |
||||||
|
} |
||||||
|
|
||||||
|
public String getColor() { |
||||||
|
return color; |
||||||
|
} |
||||||
|
|
||||||
|
public void setColor(String color) { |
||||||
|
this.color = color; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,115 @@ |
|||||||
|
package com.mh.common.core.domain.wechat; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author chison |
||||||
|
* @date 2020-09-14 10:58 |
||||||
|
* @Description 推送消息实体类 |
||||||
|
*/ |
||||||
|
public class PushMsgEntity { |
||||||
|
public String touser; //接收人
|
||||||
|
public String templateId; //微信提供模板id
|
||||||
|
public String url; //消息推送消息url
|
||||||
|
public First first; //消息头消息
|
||||||
|
public Key1 key1; |
||||||
|
public Key2 key2; |
||||||
|
public Key3 key3; |
||||||
|
public Key4 key4; |
||||||
|
public Key5 key5; |
||||||
|
public Remark remark; |
||||||
|
|
||||||
|
public String getTouser() { |
||||||
|
return touser; |
||||||
|
} |
||||||
|
|
||||||
|
public void setTouser(String touser) { |
||||||
|
this.touser = touser; |
||||||
|
} |
||||||
|
|
||||||
|
public String getTemplateId() { |
||||||
|
return templateId; |
||||||
|
} |
||||||
|
|
||||||
|
public void setTemplateId(String templateId) { |
||||||
|
this.templateId = templateId; |
||||||
|
} |
||||||
|
|
||||||
|
public String getUrl() { |
||||||
|
return url; |
||||||
|
} |
||||||
|
|
||||||
|
public void setUrl(String url) { |
||||||
|
this.url = url; |
||||||
|
} |
||||||
|
|
||||||
|
public First getFirst() { |
||||||
|
return first; |
||||||
|
} |
||||||
|
|
||||||
|
public void setFirst(First first) { |
||||||
|
this.first = first; |
||||||
|
} |
||||||
|
|
||||||
|
public Key1 getKey1() { |
||||||
|
return key1; |
||||||
|
} |
||||||
|
|
||||||
|
public void setKey1(Key1 key1) { |
||||||
|
this.key1 = key1; |
||||||
|
} |
||||||
|
|
||||||
|
public Key2 getKey2() { |
||||||
|
return key2; |
||||||
|
} |
||||||
|
|
||||||
|
public void setKey2(Key2 key2) { |
||||||
|
this.key2 = key2; |
||||||
|
} |
||||||
|
|
||||||
|
public Key3 getKey3() { |
||||||
|
return key3; |
||||||
|
} |
||||||
|
|
||||||
|
public void setKey3(Key3 key3) { |
||||||
|
this.key3 = key3; |
||||||
|
} |
||||||
|
|
||||||
|
public Key4 getKey4() { |
||||||
|
return key4; |
||||||
|
} |
||||||
|
|
||||||
|
public void setKey4(Key4 key4) { |
||||||
|
this.key4 = key4; |
||||||
|
} |
||||||
|
|
||||||
|
public Key5 getKey5() { |
||||||
|
return key5; |
||||||
|
} |
||||||
|
|
||||||
|
public void setKey5(Key5 key5) { |
||||||
|
this.key5 = key5; |
||||||
|
} |
||||||
|
|
||||||
|
public Remark getRemark() { |
||||||
|
return remark; |
||||||
|
} |
||||||
|
|
||||||
|
public void setRemark(Remark remark) { |
||||||
|
this.remark = remark; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String toString() { |
||||||
|
return "PushMsgEntity{" + |
||||||
|
"touser='" + touser + '\'' + |
||||||
|
", templateId='" + templateId + '\'' + |
||||||
|
", url='" + url + '\'' + |
||||||
|
", first=" + first + |
||||||
|
", key1=" + key1 + |
||||||
|
", key2=" + key2 + |
||||||
|
", key3=" + key3 + |
||||||
|
", key4=" + key4 + |
||||||
|
", key5=" + key5 + |
||||||
|
", remark=" + remark + |
||||||
|
'}'; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,36 @@ |
|||||||
|
package com.mh.common.core.domain.wechat; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author chison |
||||||
|
* @date 2020-09-14 15:47 |
||||||
|
* @Description |
||||||
|
*/ |
||||||
|
public class Remark { |
||||||
|
|
||||||
|
public String value; |
||||||
|
public String color; |
||||||
|
|
||||||
|
public Remark() { |
||||||
|
} |
||||||
|
|
||||||
|
public Remark(String value, String color) { |
||||||
|
this.value = value; |
||||||
|
this.color = color; |
||||||
|
} |
||||||
|
|
||||||
|
public String getValue() { |
||||||
|
return value; |
||||||
|
} |
||||||
|
|
||||||
|
public void setValue(String value) { |
||||||
|
this.value = value; |
||||||
|
} |
||||||
|
|
||||||
|
public String getColor() { |
||||||
|
return color; |
||||||
|
} |
||||||
|
|
||||||
|
public void setColor(String color) { |
||||||
|
this.color = color; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,70 @@ |
|||||||
|
package com.mh.common.core.domain.wechat; |
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType; |
||||||
|
import com.baomidou.mybatisplus.annotation.TableId; |
||||||
|
import com.baomidou.mybatisplus.annotation.TableName; |
||||||
|
import lombok.Data; |
||||||
|
import org.apache.commons.lang3.builder.ToStringBuilder; |
||||||
|
|
||||||
|
import java.util.Date; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author LJF |
||||||
|
* @version 1.0 |
||||||
|
* @project EEMCS |
||||||
|
* @description 微信模板 |
||||||
|
* @date 2025-06-27 11:43:54 |
||||||
|
*/ |
||||||
|
@Data |
||||||
|
@TableName("wechat_template") |
||||||
|
public class WechatTemplate { |
||||||
|
|
||||||
|
@TableId(value = "id", type = IdType.AUTO) |
||||||
|
private Long id; |
||||||
|
|
||||||
|
private String templateId; |
||||||
|
|
||||||
|
private String templateName; |
||||||
|
|
||||||
|
private String title; |
||||||
|
|
||||||
|
private String content1; |
||||||
|
|
||||||
|
private String content2; |
||||||
|
|
||||||
|
private String content3; |
||||||
|
|
||||||
|
private String content4; |
||||||
|
|
||||||
|
private String content5; |
||||||
|
|
||||||
|
private String remark; |
||||||
|
|
||||||
|
private Date createTime; |
||||||
|
|
||||||
|
private Date updateTime; |
||||||
|
|
||||||
|
/** |
||||||
|
* 0:正常 1:不使用 |
||||||
|
*/ |
||||||
|
private int grade; |
||||||
|
|
||||||
|
@Override |
||||||
|
public String toString() { |
||||||
|
return new ToStringBuilder(this) |
||||||
|
.append("id", id) |
||||||
|
.append("templateId", templateId) |
||||||
|
.append("templateName", templateName) |
||||||
|
.append("title", title) |
||||||
|
.append("content1", content1) |
||||||
|
.append("content2", content2) |
||||||
|
.append("content3", content3) |
||||||
|
.append("content4", content4) |
||||||
|
.append("content5", content5) |
||||||
|
.append("remark", remark) |
||||||
|
.append("createTime", createTime) |
||||||
|
.append("updateTime", updateTime) |
||||||
|
.append("grade", grade) |
||||||
|
.toString(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,52 @@ |
|||||||
|
package com.mh.common.core.domain.wechat; |
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType; |
||||||
|
import com.baomidou.mybatisplus.annotation.TableId; |
||||||
|
import com.baomidou.mybatisplus.annotation.TableName; |
||||||
|
import lombok.Data; |
||||||
|
import org.apache.commons.lang3.builder.ToStringBuilder; |
||||||
|
|
||||||
|
import java.util.Date; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author LJF |
||||||
|
* @version 1.0 |
||||||
|
* @project EEMCS |
||||||
|
* @description 微信模板 |
||||||
|
* @date 2025-06-27 11:43:54 |
||||||
|
*/ |
||||||
|
@Data |
||||||
|
@TableName("wechat_template_project") |
||||||
|
public class WechatTemplateProject { |
||||||
|
|
||||||
|
@TableId(value = "id", type = IdType.AUTO) |
||||||
|
private Long id; |
||||||
|
|
||||||
|
private Long templateId; |
||||||
|
|
||||||
|
private Long projectId; |
||||||
|
|
||||||
|
private Long wechatUserId; |
||||||
|
|
||||||
|
private Date createTime; |
||||||
|
|
||||||
|
private Date updateTime; |
||||||
|
|
||||||
|
/** |
||||||
|
* 0:正常 1:不使用 |
||||||
|
*/ |
||||||
|
private int grade; |
||||||
|
|
||||||
|
@Override |
||||||
|
public String toString() { |
||||||
|
return new ToStringBuilder(this) |
||||||
|
.append("id", id) |
||||||
|
.append("templateId", templateId) |
||||||
|
.append("projectId", projectId) |
||||||
|
.append("wechatUserId", wechatUserId) |
||||||
|
.append("createTime", createTime) |
||||||
|
.append("updateTime", updateTime) |
||||||
|
.append("grade", grade) |
||||||
|
.toString(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,172 @@ |
|||||||
|
package com.mh.common.core.domain.wechat; |
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType; |
||||||
|
import com.baomidou.mybatisplus.annotation.TableId; |
||||||
|
import com.baomidou.mybatisplus.annotation.TableName; |
||||||
|
|
||||||
|
import java.util.Date; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author LJF |
||||||
|
* @version 1.0 |
||||||
|
* @project mh_esi |
||||||
|
* @description 微信用户实体类 |
||||||
|
* @date 2024-11-27 16:58:55 |
||||||
|
*/ |
||||||
|
@TableName("wechat_user_info") |
||||||
|
public class WechatUserInfo { |
||||||
|
|
||||||
|
@TableId(value = "id", type = IdType.AUTO) |
||||||
|
private Long id; |
||||||
|
|
||||||
|
private String userName; |
||||||
|
|
||||||
|
private String telNum; |
||||||
|
|
||||||
|
private String openId; |
||||||
|
|
||||||
|
private String nickName; |
||||||
|
|
||||||
|
private int sex; |
||||||
|
|
||||||
|
private String province; |
||||||
|
|
||||||
|
private String city; |
||||||
|
|
||||||
|
private String country; |
||||||
|
|
||||||
|
private String headimgurl; |
||||||
|
|
||||||
|
private int isStatus; |
||||||
|
|
||||||
|
private Date createTime; |
||||||
|
|
||||||
|
private Date updateTime; |
||||||
|
|
||||||
|
public Long getId() { |
||||||
|
return id; |
||||||
|
} |
||||||
|
|
||||||
|
public void setId(Long id) { |
||||||
|
this.id = id; |
||||||
|
} |
||||||
|
|
||||||
|
public String getUserName() { |
||||||
|
return userName; |
||||||
|
} |
||||||
|
|
||||||
|
public void setUserName(String userName) { |
||||||
|
this.userName = userName; |
||||||
|
} |
||||||
|
|
||||||
|
public String getTelNum() { |
||||||
|
return telNum; |
||||||
|
} |
||||||
|
|
||||||
|
public void setTelNum(String telNum) { |
||||||
|
this.telNum = telNum; |
||||||
|
} |
||||||
|
|
||||||
|
public String getOpenId() { |
||||||
|
return openId; |
||||||
|
} |
||||||
|
|
||||||
|
public void setOpenId(String openId) { |
||||||
|
this.openId = openId; |
||||||
|
} |
||||||
|
|
||||||
|
public String getNickName() { |
||||||
|
return nickName; |
||||||
|
} |
||||||
|
|
||||||
|
public void setNickName(String nickName) { |
||||||
|
this.nickName = nickName; |
||||||
|
} |
||||||
|
|
||||||
|
public int getSex() { |
||||||
|
return sex; |
||||||
|
} |
||||||
|
|
||||||
|
public void setSex(Integer sex) { |
||||||
|
this.sex = sex; |
||||||
|
} |
||||||
|
|
||||||
|
public String getProvince() { |
||||||
|
return province; |
||||||
|
} |
||||||
|
|
||||||
|
public void setProvince(String province) { |
||||||
|
this.province = province; |
||||||
|
} |
||||||
|
|
||||||
|
public String getCity() { |
||||||
|
return city; |
||||||
|
} |
||||||
|
|
||||||
|
public void setCity(String city) { |
||||||
|
this.city = city; |
||||||
|
} |
||||||
|
|
||||||
|
public String getCountry() { |
||||||
|
return country; |
||||||
|
} |
||||||
|
|
||||||
|
public void setCountry(String country) { |
||||||
|
this.country = country; |
||||||
|
} |
||||||
|
|
||||||
|
public void setSex(int sex) { |
||||||
|
this.sex = sex; |
||||||
|
} |
||||||
|
|
||||||
|
public String getHeadimgurl() { |
||||||
|
return headimgurl; |
||||||
|
} |
||||||
|
|
||||||
|
public void setHeadimgurl(String headimgurl) { |
||||||
|
this.headimgurl = headimgurl; |
||||||
|
} |
||||||
|
|
||||||
|
public int getIsStatus() { |
||||||
|
return isStatus; |
||||||
|
} |
||||||
|
|
||||||
|
public void setIsStatus(int isStatus) { |
||||||
|
this.isStatus = isStatus; |
||||||
|
} |
||||||
|
|
||||||
|
public Date getCreateTime() { |
||||||
|
return createTime; |
||||||
|
} |
||||||
|
|
||||||
|
public void setCreateTime(Date createTime) { |
||||||
|
this.createTime = createTime; |
||||||
|
} |
||||||
|
|
||||||
|
public Date getUpdateTime() { |
||||||
|
return updateTime; |
||||||
|
} |
||||||
|
|
||||||
|
public void setUpdateTime(Date updateTime) { |
||||||
|
this.updateTime = updateTime; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String toString() { |
||||||
|
return "WechatUserInfoEntity{" + |
||||||
|
"id=" + id + |
||||||
|
", userName='" + userName + '\'' + |
||||||
|
", telNum='" + telNum + '\'' + |
||||||
|
", openId='" + openId + '\'' + |
||||||
|
", nickName='" + nickName + '\'' + |
||||||
|
", sex=" + sex + |
||||||
|
", province='" + province + '\'' + |
||||||
|
", city='" + city + '\'' + |
||||||
|
", country='" + country + '\'' + |
||||||
|
", headimgurl='" + headimgurl + '\'' + |
||||||
|
", isStatus=" + isStatus + |
||||||
|
", createTime=" + createTime + |
||||||
|
", updateTime=" + updateTime + |
||||||
|
'}'; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,126 @@ |
|||||||
|
package com.mh.quartz.task; |
||||||
|
|
||||||
|
import com.mh.common.constant.Constants; |
||||||
|
import com.mh.common.core.domain.entity.AlarmRecords; |
||||||
|
import com.mh.common.core.domain.wechat.*; |
||||||
|
import com.mh.common.utils.DateUtils; |
||||||
|
import com.mh.common.utils.DictUtils; |
||||||
|
import com.mh.system.service.IWechatService; |
||||||
|
import com.mh.system.service.operation.IAlarmRecordsService; |
||||||
|
import jakarta.annotation.Resource; |
||||||
|
import lombok.extern.slf4j.Slf4j; |
||||||
|
import org.springframework.stereotype.Component; |
||||||
|
|
||||||
|
import java.util.Date; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author LJF |
||||||
|
* @version 1.0 |
||||||
|
* @project EEMCS |
||||||
|
* @description 微信推送数据 |
||||||
|
* @date 2025-06-27 10:54:23 |
||||||
|
*/ |
||||||
|
@Slf4j |
||||||
|
@Component("pushDataToWechatTask") |
||||||
|
public class PushDataToWechatTask { |
||||||
|
|
||||||
|
@Resource |
||||||
|
private IAlarmRecordsService alarmRecordsService; |
||||||
|
|
||||||
|
@Resource |
||||||
|
private IWechatService wechatService; |
||||||
|
|
||||||
|
public void pushDataToWechat() { |
||||||
|
// 查询报警内容
|
||||||
|
AlarmRecords alarmRecords = new AlarmRecords(); |
||||||
|
alarmRecords.setStatus(0); |
||||||
|
alarmRecords.setIsSend(0); |
||||||
|
Map<String, Object> param = new HashMap<>(); |
||||||
|
param.put("beginTime", DateUtils.dateToString(new Date(), "yyyy-MM-dd 00:00:00")); |
||||||
|
param.put("endTime", DateUtils.dateToString(new Date(), "yyyy-MM-dd 23:59:59")); |
||||||
|
alarmRecords.setParams(param); |
||||||
|
List<AlarmRecords> alarmRecords1 = alarmRecordsService.selectAlarmRecordsList(alarmRecords); |
||||||
|
if (null == alarmRecords1 || alarmRecords1.isEmpty()) { |
||||||
|
return; |
||||||
|
} |
||||||
|
alarmRecords1.forEach(alarmRecords2 -> { |
||||||
|
// 查询需要推送的微信用户
|
||||||
|
List<Map<String, Object>> wechatUserList = wechatService.queryWechatUser(0); |
||||||
|
if (null == wechatUserList || wechatUserList.isEmpty()) { |
||||||
|
log.info("没有查询到微信用户"); |
||||||
|
} |
||||||
|
// 开始推送数据
|
||||||
|
for (Map<String, Object> map : wechatUserList) { |
||||||
|
PushMsgEntity pushMsgEntity = new PushMsgEntity(); |
||||||
|
try { |
||||||
|
// 判断模板id种类
|
||||||
|
switch (map.get("template_id").toString()) { |
||||||
|
case "fqAXCFXSBCqHLJjBLIjD-Wr_dN8RLsTcsatUQa3Ktx4": |
||||||
|
// 设备异常告警提醒
|
||||||
|
pushDeviceExceptionParams(map, pushMsgEntity, alarmRecords2); |
||||||
|
break; |
||||||
|
case "qG3Odr74o4BRx8QigZuoil3l3ZC2aAdDeO49robRLC8": |
||||||
|
// 推送用电量、用冷量、EER数据
|
||||||
|
// pushAllParams(projectInfoEntity, map, pushMsgEntity, energyDataEntity);
|
||||||
|
break; |
||||||
|
default: |
||||||
|
break; |
||||||
|
} |
||||||
|
|
||||||
|
} catch (Exception e) { |
||||||
|
throw new RuntimeException(e); |
||||||
|
} |
||||||
|
if (!pushMsgEntity.getTouser().isEmpty()) { |
||||||
|
String result = wechatService.pushMsg(pushMsgEntity); |
||||||
|
if (Constants.SUCCESS.equals(result)) { |
||||||
|
// 更新数据:已发送通知
|
||||||
|
alarmRecordsService.updateAlarmRecordById(alarmRecords2.getId(), 1); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 推送设备异常告警提醒 |
||||||
|
* @param map |
||||||
|
* @param pushMsgEntity |
||||||
|
* @param alarmRecords2 |
||||||
|
*/ |
||||||
|
private void pushDeviceExceptionParams(Map<String, Object> map, PushMsgEntity pushMsgEntity, AlarmRecords alarmRecords2) { |
||||||
|
pushMsgEntity.setTouser(map.get("open_id").toString()); |
||||||
|
pushMsgEntity.setTemplateId(map.get("template_id").toString()); |
||||||
|
pushMsgEntity.setUrl("http://jnd2.mhwsh.net:8765/"); |
||||||
|
First first = new First(); |
||||||
|
first.setValue("设备异常告警提醒"); |
||||||
|
pushMsgEntity.setFirst(first); |
||||||
|
Key1 key1 = new Key1(); |
||||||
|
key1.setValue(alarmRecords2.getDeviceName()); |
||||||
|
pushMsgEntity.setKey1(key1); |
||||||
|
|
||||||
|
Key2 key2 = new Key2(); |
||||||
|
// 通过告警等级id得到value值
|
||||||
|
String alarmLevel = alarmRecords2.getAlarmLevel(); |
||||||
|
String alarmLevel1 = DictUtils.getDictLabel("alarm_level", alarmLevel); |
||||||
|
key2.setValue(alarmLevel1); |
||||||
|
pushMsgEntity.setKey2(key2); |
||||||
|
|
||||||
|
Key3 key3 = new Key3(); |
||||||
|
// 通过告警类型id得到value值
|
||||||
|
String alarmType = alarmRecords2.getAlarmType(); |
||||||
|
String alarmType1 = DictUtils.getDictLabel( "alarm_type", alarmType); |
||||||
|
key3.setValue(alarmType1); |
||||||
|
pushMsgEntity.setKey3(key3); |
||||||
|
|
||||||
|
Key4 key4 = new Key4(); |
||||||
|
key4.setValue(alarmRecords2.getContent().substring(0, 20)); |
||||||
|
pushMsgEntity.setKey4(key4); |
||||||
|
|
||||||
|
Key5 key5 = new Key5(); |
||||||
|
key5.setValue(DateUtils.dateToString(alarmRecords2.getCreateTime(), "yyyy-MM-dd HH:mm:ss")); |
||||||
|
pushMsgEntity.setKey5(key5); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,26 @@ |
|||||||
|
package com.mh.system.mapper; |
||||||
|
|
||||||
|
import org.apache.ibatis.annotations.Mapper; |
||||||
|
import org.apache.ibatis.annotations.Param; |
||||||
|
import org.apache.ibatis.annotations.Select; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author LJF |
||||||
|
* @version 1.0 |
||||||
|
* @project EEMCS |
||||||
|
* @description 微信相关mapper |
||||||
|
* @date 2025-06-27 14:02:37 |
||||||
|
*/ |
||||||
|
@Mapper |
||||||
|
public interface WechatMapper { |
||||||
|
|
||||||
|
|
||||||
|
@Select("select wt.template_id, wui.open_id from wechat_template_project wtp " + |
||||||
|
" join wechat_template wt on wtp.template_id = wt.id " + |
||||||
|
" join wechat_user_info wui on wtp.wechat_user_id = wui.id" + |
||||||
|
" where wtp.grade = #{grade} and wui.is_status = 1 ") |
||||||
|
List<Map<String, Object>> queryWechatUser(@Param("grade") int grade); |
||||||
|
} |
@ -0,0 +1,20 @@ |
|||||||
|
package com.mh.system.service; |
||||||
|
|
||||||
|
import com.mh.common.core.domain.wechat.PushMsgEntity; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author LJF |
||||||
|
* @version 1.0 |
||||||
|
* @project EEMCS |
||||||
|
* @description 微信相关服务类 |
||||||
|
* @date 2025-06-27 13:48:09 |
||||||
|
*/ |
||||||
|
public interface IWechatService { |
||||||
|
|
||||||
|
List<Map<String, Object>> queryWechatUser(int grade); |
||||||
|
|
||||||
|
String pushMsg(PushMsgEntity pushMsgEntity); |
||||||
|
} |
@ -0,0 +1,169 @@ |
|||||||
|
package com.mh.system.service.impl; |
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSONObject; |
||||||
|
import com.mh.common.config.wechat.WechatMpConfig; |
||||||
|
import com.mh.common.constant.Constants; |
||||||
|
import com.mh.common.core.domain.wechat.PushMsgEntity; |
||||||
|
import com.mh.common.core.redis.RedisCache; |
||||||
|
import com.mh.system.mapper.WechatMapper; |
||||||
|
import com.mh.system.service.IWechatService; |
||||||
|
import jakarta.annotation.Resource; |
||||||
|
import lombok.extern.slf4j.Slf4j; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.http.*; |
||||||
|
import org.springframework.http.converter.StringHttpMessageConverter; |
||||||
|
import org.springframework.stereotype.Service; |
||||||
|
import org.springframework.web.client.RestClientException; |
||||||
|
import org.springframework.web.client.RestTemplate; |
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream; |
||||||
|
import java.io.IOException; |
||||||
|
import java.nio.charset.StandardCharsets; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
import java.util.Objects; |
||||||
|
import java.util.concurrent.TimeUnit; |
||||||
|
import java.util.zip.GZIPOutputStream; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author LJF |
||||||
|
* @version 1.0 |
||||||
|
* @project EEMCS |
||||||
|
* @description 微信服务实现类 |
||||||
|
* @date 2025-06-27 13:48:32 |
||||||
|
*/ |
||||||
|
@Slf4j |
||||||
|
@Service |
||||||
|
public class WechatServiceImpl implements IWechatService { |
||||||
|
|
||||||
|
@Autowired |
||||||
|
private WechatMapper wechatMapper; |
||||||
|
|
||||||
|
@Autowired |
||||||
|
private WechatMpConfig wechatMpConfig; |
||||||
|
|
||||||
|
@Autowired |
||||||
|
private RedisCache redisCache; |
||||||
|
|
||||||
|
@Autowired |
||||||
|
private RestTemplate restTemplate; |
||||||
|
|
||||||
|
@Override |
||||||
|
public List<Map<String, Object>> queryWechatUser(int grade) { |
||||||
|
return wechatMapper.queryWechatUser(grade); |
||||||
|
} |
||||||
|
public String getAccessToken() { |
||||||
|
String tokenResult = restTemplate.getForObject(wechatMpConfig.getAccessTokenUrl(),String.class); |
||||||
|
JSONObject jsonObj = JSONObject.parseObject(tokenResult); |
||||||
|
if (jsonObj == null || !jsonObj.containsKey("access_token")) { |
||||||
|
return ""; |
||||||
|
} |
||||||
|
String accessToken = jsonObj.get("access_token").toString(); |
||||||
|
log.info("获取access_token==>{}", accessToken); |
||||||
|
redisCache.setCacheObject("accessToken", accessToken , 7000, TimeUnit.SECONDS); |
||||||
|
return accessToken; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String pushMsg(PushMsgEntity pushMsgEntity) { |
||||||
|
String result = Constants.FAIL; |
||||||
|
// 判断cache中是否存在access_token
|
||||||
|
String accessToken = ""; |
||||||
|
if (redisCache.hasKey("accessToken")) { |
||||||
|
log.info("ConcurrentHashMap中存在access_token的cache,直接使用"); |
||||||
|
// 再次判断是否存在access_token
|
||||||
|
if (!redisCache.hasKey("accessToken")) { |
||||||
|
log.info("cache中不存在access_token,重新获取"); |
||||||
|
accessToken = getAccessToken(); |
||||||
|
} else { |
||||||
|
accessToken = Objects.requireNonNull(redisCache.getCacheObject("accessToken")).toString(); |
||||||
|
} |
||||||
|
} else { |
||||||
|
|
||||||
|
String tokenResult = restTemplate.getForObject(wechatMpConfig.getAccessTokenUrl(), String.class); |
||||||
|
JSONObject jsonObj = JSONObject.parseObject(tokenResult); |
||||||
|
if (jsonObj == null || !jsonObj.containsKey("access_token")) { |
||||||
|
return result; |
||||||
|
} |
||||||
|
accessToken = getAccessToken(); |
||||||
|
} |
||||||
|
if (accessToken.isEmpty()) { |
||||||
|
return result; |
||||||
|
} |
||||||
|
// 封装推送内容
|
||||||
|
JSONObject jsonObject = new JSONObject(); |
||||||
|
jsonObject.put("touser", pushMsgEntity.getTouser()); |
||||||
|
jsonObject.put("template_id", pushMsgEntity.getTemplateId()); |
||||||
|
jsonObject.put("url", pushMsgEntity.getUrl()); |
||||||
|
JSONObject data = new JSONObject(); |
||||||
|
|
||||||
|
// 判断模板id属于哪一个,切换对应的参数
|
||||||
|
switch (pushMsgEntity.getTemplateId()) { |
||||||
|
case "fqAXCFXSBCqHLJjBLIjD-Wr_dN8RLsTcsatUQa3Ktx4": |
||||||
|
// 设备名称
|
||||||
|
data.put("thing11", pushMsgEntity.getKey1()); |
||||||
|
// 告警等级
|
||||||
|
data.put("thing4", pushMsgEntity.getKey2()); |
||||||
|
// // 告警类型
|
||||||
|
// data.put("thing3", pushMsgEntity.getKey3());
|
||||||
|
// 告警明细
|
||||||
|
data.put("thing6", pushMsgEntity.getKey4()); |
||||||
|
// 告警时间
|
||||||
|
data.put("time5", pushMsgEntity.getKey5()); |
||||||
|
break; |
||||||
|
default: |
||||||
|
break; |
||||||
|
|
||||||
|
} |
||||||
|
data.put("remark", pushMsgEntity.getRemark()); |
||||||
|
jsonObject.put("data", data); |
||||||
|
|
||||||
|
HttpHeaders headers = new HttpHeaders(); |
||||||
|
headers.setContentType(MediaType.APPLICATION_JSON); |
||||||
|
|
||||||
|
// 使用StringHttpMessageConverter来处理请求体
|
||||||
|
String requestBody = jsonObject.toJSONString(); |
||||||
|
HttpEntity<String> entity = new HttpEntity<>(requestBody, headers); |
||||||
|
|
||||||
|
String requestUrl = wechatMpConfig.getPushMsgUrl(accessToken); |
||||||
|
log.info("请求URL: {}", requestUrl); |
||||||
|
log.info("请求体: {}", requestBody); |
||||||
|
|
||||||
|
try { |
||||||
|
// 使用配置了StringHttpMessageConverter的RestTemplate
|
||||||
|
RestTemplate restTemplate = new RestTemplate(); |
||||||
|
restTemplate.getMessageConverters().add(0, new StringHttpMessageConverter(StandardCharsets.UTF_8)); |
||||||
|
|
||||||
|
ResponseEntity<String> response = restTemplate.exchange( |
||||||
|
requestUrl, |
||||||
|
HttpMethod.POST, |
||||||
|
entity, |
||||||
|
String.class |
||||||
|
); |
||||||
|
|
||||||
|
String resultBody = response.getBody(); |
||||||
|
|
||||||
|
// 可以检查响应状态码
|
||||||
|
if (!response.getStatusCode().is2xxSuccessful()) { |
||||||
|
log.error("微信推送失败,状态码: {}", response.getStatusCode()); |
||||||
|
} |
||||||
|
|
||||||
|
// {
|
||||||
|
// "errcode": 0,
|
||||||
|
// "errmsg": "ok",
|
||||||
|
// "msgid": 4054699362939830276
|
||||||
|
//}
|
||||||
|
// 增加判断逻辑,判断errcode=0,errmsg=ok,返回success
|
||||||
|
JSONObject resultJson = JSONObject.parseObject(resultBody); |
||||||
|
assert resultJson != null; |
||||||
|
if (resultJson.getInteger("errcode") != 0) { |
||||||
|
log.error("微信推送失败,错误码: {}", resultBody); |
||||||
|
} else { |
||||||
|
result = Constants.SUCCESS; |
||||||
|
} |
||||||
|
} catch (RestClientException e) { |
||||||
|
log.error("推送消息失败", e); |
||||||
|
} |
||||||
|
return result; |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue