上传微信公众号
commit
3a39e06292
|
@ -0,0 +1,38 @@
|
|||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
!**/src/main/**/target/
|
||||
!**/src/test/**/target/
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea/modules.xml
|
||||
.idea/jarRepositories.xml
|
||||
.idea/compiler.xml
|
||||
.idea/libraries/
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### Eclipse ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
build/
|
||||
!**/src/main/**/build/
|
||||
!**/src/test/**/build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
|
||||
### Mac OS ###
|
||||
.DS_Store
|
|
@ -0,0 +1,8 @@
|
|||
# 默认忽略的文件
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# 基于编辑器的 HTTP 客户端请求
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding">
|
||||
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="GitToolBoxBlameSettings">
|
||||
<option name="version" value="2" />
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="MaterialThemeProjectNewConfig">
|
||||
<option name="metadata">
|
||||
<MTProjectMetadataState>
|
||||
<option name="migrated" value="true" />
|
||||
<option name="pristineConfig" value="false" />
|
||||
<option name="userId" value="543722b8:191dbece87f:-7ffe" />
|
||||
</MTProjectMetadataState>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="MavenProjectsManager">
|
||||
<option name="originalFiles">
|
||||
<list>
|
||||
<option value="$PROJECT_DIR$/pom.xml" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,68 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.muyu</groupId>
|
||||
<artifactId>cloud-common</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<parent>
|
||||
<groupId>com.muyu</groupId>
|
||||
<artifactId>cloud-modules</artifactId>
|
||||
<version>3.6.3</version>
|
||||
</parent>
|
||||
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
<version>4.9.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.thoughtworks.xstream</groupId>
|
||||
<artifactId>xstream</artifactId>
|
||||
<version>1.4.20</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.34</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
<version>3.3.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<version>3.3.2</version>
|
||||
</dependency>
|
||||
<!-- DOM4J是 dom4j.org 出品的一个开源XML解析包-->
|
||||
<dependency>
|
||||
<groupId>org.dom4j</groupId>
|
||||
<artifactId>dom4j</artifactId>
|
||||
<version>2.1.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.fastjson2</groupId>
|
||||
<artifactId>fastjson2</artifactId>
|
||||
<version>2.0.43</version>
|
||||
</dependency>
|
||||
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>com.muyu</groupId>-->
|
||||
<!-- <artifactId>cloud-common-redis</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package com.muyu;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
/**
|
||||
* @className: WxApplication ️✈️
|
||||
* @author: Yang 鹏 🦅
|
||||
* @date: 2024/9/16 20:39 ⏰
|
||||
* @Version: 1.0
|
||||
* @description:
|
||||
*/
|
||||
@SpringBootApplication
|
||||
public class WxApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(WxApplication.class);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package com.muyu.button;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* @className: AbstractButton ️✈️
|
||||
* @author: Yang 鹏 🦅
|
||||
* @date: 2024/9/18 20:57 ⏰
|
||||
* @Version: 1.0
|
||||
* @description:
|
||||
*/
|
||||
public abstract class AbstractButton {
|
||||
private String name;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public AbstractButton(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package com.muyu.button;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @className: Button ️✈️
|
||||
* @author: Yang 鹏 🦅
|
||||
* @date: 2024/9/18 20:53 ⏰
|
||||
* @Version: 1.0
|
||||
* @description:
|
||||
*/
|
||||
@Data
|
||||
public class Button {
|
||||
private List<AbstractButton> button;
|
||||
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package com.muyu.button;
|
||||
|
||||
/**
|
||||
* @className: ClickButton ️✈️
|
||||
* @author: Yang 鹏 🦅
|
||||
* @date: 2024/9/18 21:00 ⏰
|
||||
* @Version: 1.0
|
||||
* @description:
|
||||
*/
|
||||
public class ClickButton extends AbstractButton{
|
||||
public ClickButton(String name) {
|
||||
super(name);
|
||||
this.type="click";
|
||||
}
|
||||
|
||||
private String type;
|
||||
private String key;
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public void setKey(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package com.muyu.button;
|
||||
|
||||
/**
|
||||
* @className: PhotoOrAlbum ️✈️
|
||||
* @author: Yang 鹏 🦅
|
||||
* @date: 2024/9/18 21:18 ⏰
|
||||
* @Version: 1.0
|
||||
* @description:
|
||||
*/
|
||||
public class PhotoOrAlbumButton extends AbstractButton{
|
||||
public PhotoOrAlbumButton(String name) {
|
||||
super(name);
|
||||
this.type="pic_photo_or_album";
|
||||
}
|
||||
|
||||
private String type;
|
||||
private String key;
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
|
||||
}
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public void setKey(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package com.muyu.button;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @className: SubButton ️✈️
|
||||
* @author: Yang 鹏 🦅
|
||||
* @date: 2024/9/18 21:24 ⏰
|
||||
* @Version: 1.0
|
||||
* @description:
|
||||
*/
|
||||
public class SubButton extends AbstractButton{
|
||||
public SubButton(String name) {
|
||||
super(name);
|
||||
}
|
||||
private List<AbstractButton> sub_button;
|
||||
|
||||
public List<AbstractButton> getSub_button() {
|
||||
return sub_button;
|
||||
}
|
||||
|
||||
public void setSub_button(List<AbstractButton> sub_button) {
|
||||
this.sub_button = sub_button;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package com.muyu.button;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* @className: TestButton ️✈️
|
||||
* @author: Yang 鹏 🦅
|
||||
* @date: 2024/9/18 22:20 ⏰
|
||||
* @Version: 1.0
|
||||
* @description:
|
||||
*/
|
||||
public class TestButton {
|
||||
public static void main(String[] args) {
|
||||
//创建一级菜单
|
||||
Button button = new Button();
|
||||
ArrayList<AbstractButton> buttons = new ArrayList<>();
|
||||
//一级菜单中的第一个按钮
|
||||
ClickButton clickButton = new ClickButton("授权");
|
||||
clickButton.setKey("1");
|
||||
|
||||
//一级菜单中的第二个按钮
|
||||
|
||||
|
||||
|
||||
button.setButton(buttons);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package com.muyu.button;
|
||||
|
||||
/**
|
||||
* @className: ViewButton ️✈️
|
||||
* @author: Yang 鹏 🦅
|
||||
* @date: 2024/9/18 21:14 ⏰
|
||||
* @Version: 1.0
|
||||
* @description:
|
||||
*/
|
||||
public class ViewButton extends AbstractButton{
|
||||
public ViewButton(String name,String url) {
|
||||
super(name);
|
||||
this.type="view";
|
||||
this.url = url;
|
||||
}
|
||||
private String type;
|
||||
private String url;
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,202 @@
|
|||
package com.muyu.controller;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.muyu.domain.Message;
|
||||
import com.muyu.service.WxService;
|
||||
import com.muyu.util.OkHttpUtils;
|
||||
import com.muyu.util.TokenUtil;
|
||||
import com.muyu.util.WechatUtil;
|
||||
import com.thoughtworks.xstream.XStream;
|
||||
import io.micrometer.common.util.StringUtils;
|
||||
import jakarta.servlet.ServletInputStream;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import okhttp3.*;
|
||||
import org.dom4j.Document;
|
||||
import org.dom4j.DocumentException;
|
||||
import org.dom4j.Element;
|
||||
import org.dom4j.io.SAXReader;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @className: GetWxController ️✈️
|
||||
* @author: Yang 鹏 🦅
|
||||
* @date: 2024/9/16 20:38 ⏰
|
||||
* @Version: 1.0
|
||||
* @description:
|
||||
*/
|
||||
@RestController
|
||||
public class WxController {
|
||||
|
||||
// @Autowired
|
||||
// private RedisService redisService;
|
||||
|
||||
@Autowired
|
||||
private WxService wxService;
|
||||
|
||||
/**
|
||||
* 消息验证,验证是否是微信
|
||||
* @param signature
|
||||
* @param timestamp
|
||||
* @param nonce
|
||||
* @param echostr
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/")
|
||||
public String check(@RequestParam("signature") String signature,@RequestParam("timestamp") String timestamp ,
|
||||
@RequestParam("nonce") String nonce, @RequestParam("echostr") String echostr){
|
||||
|
||||
String token ="zzhdzt";
|
||||
List<String> list = Arrays.asList(token, timestamp, nonce);
|
||||
Collections.sort(list);
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
for (String s : list) {
|
||||
stringBuilder.append(s);
|
||||
}
|
||||
try {
|
||||
|
||||
MessageDigest instance = MessageDigest.getInstance("sha1");
|
||||
//使用sha1进行加密,获得byte数组
|
||||
byte[] digest = instance.digest(stringBuilder.toString().getBytes());
|
||||
StringBuilder sum = new StringBuilder();
|
||||
for (byte b : digest) {
|
||||
sum.append(Integer.toHexString((b>>4)&15));
|
||||
sum.append(Integer.toHexString(b&15));
|
||||
}
|
||||
|
||||
if (!StringUtils.isEmpty(signature) && signature.equals(sum.toString())){
|
||||
return echostr;
|
||||
}
|
||||
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 接收消息并自动回复
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/")
|
||||
public String receiveMessage(HttpServletRequest request){
|
||||
|
||||
|
||||
String message = wxService.handleMessage(request);
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/getSignUpUserInfo")
|
||||
public String getSignUpUserInfo(HttpServletRequest request){
|
||||
|
||||
String code = request.getParameter("code");
|
||||
|
||||
return wxService.getSignUpUserInfo(code);
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/send")
|
||||
public void sendWxMsg(@RequestParam("toUser") String toUser,@RequestParam("content") String content) {
|
||||
WechatUtil.send(toUser,content);
|
||||
}
|
||||
|
||||
|
||||
// @GetMapping("/getWxUserList")
|
||||
// public List getUserList(){
|
||||
// String accessToken = TokenUtil.getAccessToken();
|
||||
// String url="https://api.weixin.qq.com/cgi-bin/user/get?access_token="+accessToken;
|
||||
// String request = OkHttpUtils.sendGetRequest(url);
|
||||
//
|
||||
// try {
|
||||
// ObjectMapper mapper = new ObjectMapper();
|
||||
// JsonNode rootNode = mapper.readTree(request);
|
||||
//
|
||||
// int total = rootNode.get("total").asInt();
|
||||
// int count = rootNode.get("count").asInt();
|
||||
// JsonNode itemsNode = rootNode.get("data");
|
||||
// JsonNode openIdNode = itemsNode.get("openid");
|
||||
// List<String> openids = new ArrayList<>();
|
||||
//
|
||||
// // 遍历 JSON 数组中的每个元素
|
||||
// for (JsonNode item : openIdNode) {
|
||||
// // 添加到集合中
|
||||
// openids.add(item.asText());
|
||||
// }
|
||||
//
|
||||
// String nextOpenid = openids.isEmpty() ? null : openids.get(openids.size() - 1);
|
||||
//
|
||||
// // 构建最终的JSON对象
|
||||
// Map<String, Object> map = new HashMap<>();
|
||||
// map.put("total", total);
|
||||
// map.put("count", count);
|
||||
// Map<String, List<String>> data = new HashMap<>();
|
||||
// data.put("openid", openids);
|
||||
// map.put("data", data);
|
||||
// map.put("next_openid", nextOpenid);
|
||||
//
|
||||
// // 根据openid获取用户信息
|
||||
// for (String openid : openids) {
|
||||
// String getUserUrl = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=" + accessToken + "&openid=" + openid + "&lang=zh_CN";
|
||||
// String userInfoRequest = OkHttpUtils.sendGetRequest(getUserUrl);
|
||||
//
|
||||
// // 解析用户信息
|
||||
// JsonNode userInfoNode = mapper.readTree(userInfoRequest);
|
||||
// System.out.println("用户信息: " + userInfoNode);
|
||||
// }
|
||||
// } catch (IOException e) {
|
||||
// // 处理解析错误
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// return null;
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
// @PostMapping("/test")
|
||||
// public void test(){
|
||||
// String accessToken = TokenUtil.getAccessToken();
|
||||
// System.out.println(accessToken);
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
// String message="<xml><ToUserName><![CDATA[gh_746d58eabb43]]></ToUserName><FromUserName><![CDATA[oUjOm6hQ2WPWn1d8YO2-ovVJpfdE]]></FromUserName><CreateTime>12345678</CreateTime><MsgType><![CDATA[text]]></MsgType> <Content><![CDATA[你好]]></Content></xml>";
|
||||
// @PostMapping("/")
|
||||
// public String receiveMessage(HttpServletRequest request){
|
||||
//
|
||||
//
|
||||
//
|
||||
// try {
|
||||
// ServletInputStream inputStream = null;
|
||||
// inputStream = request.getInputStream();
|
||||
//
|
||||
// byte[] bytes = new byte[1024];
|
||||
// int len = 0;
|
||||
// while ((len=inputStream.read(bytes))!=-1){
|
||||
// System.out.println(new String(bytes, 0, len));
|
||||
// }
|
||||
//
|
||||
// } catch (IOException e) {
|
||||
// throw new RuntimeException(e);
|
||||
// }
|
||||
//
|
||||
// return "";
|
||||
// }
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package com.muyu.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @className: AccessToken ️✈️
|
||||
* @author: Yang 鹏 🦅
|
||||
* @date: 2024/9/17 16:49 ⏰
|
||||
* @Version: 1.0
|
||||
* @description:
|
||||
*/
|
||||
@Data
|
||||
public class AccessToken {
|
||||
|
||||
|
||||
private String access_token;
|
||||
|
||||
private Long expires_in;
|
||||
|
||||
public void setExpiresTime(Long expiresIn) {
|
||||
this.expires_in = System.currentTimeMillis()+expiresIn*1000;
|
||||
}
|
||||
|
||||
// public boolean isExpired(Long expiresIn){
|
||||
// long now = System.currentTimeMillis();
|
||||
// return now>expiresIn;
|
||||
// }
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package com.muyu.domain;
|
||||
|
||||
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @className: Message ️✈️
|
||||
* @author: Yang 鹏 🦅
|
||||
* @date: 2024/9/17 16:49 ⏰
|
||||
* @Version: 1.0
|
||||
* @description:
|
||||
*/
|
||||
@Data
|
||||
@XStreamAlias("xml")
|
||||
public class Message {
|
||||
@XStreamAlias("ToUserName")
|
||||
private String toUserName;
|
||||
|
||||
@XStreamAlias("FromUserName")
|
||||
private String fromUserName;
|
||||
|
||||
@XStreamAlias("CreateTime")
|
||||
private Long createTime;
|
||||
|
||||
@XStreamAlias("MsgType")
|
||||
private String msgType;
|
||||
|
||||
@XStreamAlias("Content")
|
||||
private String content;
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package com.muyu.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @className: SubscribedUser ️✈️
|
||||
* @author: Yang 鹏 🦅
|
||||
* @date: 2024/9/18 15:11 ⏰
|
||||
* @Version: 1.0
|
||||
* @description:
|
||||
*/
|
||||
@Data
|
||||
public class SubscribedUser {
|
||||
private String openid;
|
||||
private String nickname;
|
||||
private Integer sex;
|
||||
private String province;
|
||||
private String city;
|
||||
private String country;
|
||||
private String headimgurl;
|
||||
private Long subscribedTime;
|
||||
// private String privilege;
|
||||
// private String unionid;
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
package com.muyu.service.Impl;
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.muyu.domain.Message;
|
||||
import com.muyu.domain.SubscribedUser;
|
||||
import com.muyu.service.WxService;
|
||||
import com.muyu.util.OkHttpUtils;
|
||||
import com.muyu.util.TokenUtil;
|
||||
import com.muyu.util.WechatUtil;
|
||||
import com.thoughtworks.xstream.XStream;
|
||||
import jakarta.servlet.ServletInputStream;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.dom4j.Document;
|
||||
import org.dom4j.DocumentException;
|
||||
import org.dom4j.Element;
|
||||
import org.dom4j.io.SAXReader;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @className: WxServiceImpl ️✈️
|
||||
* @author: Yang 鹏 🦅
|
||||
* @date: 2024/9/18 12:05 ⏰
|
||||
* @Version: 1.0
|
||||
* @description:
|
||||
*/
|
||||
@Service
|
||||
public class WxServiceImpl implements WxService {
|
||||
|
||||
|
||||
/**
|
||||
* 处理信息
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String handleMessage(HttpServletRequest request) {
|
||||
ServletInputStream inputStream = null;
|
||||
|
||||
HashMap<String, String> map = new HashMap<>();
|
||||
try {
|
||||
inputStream = request.getInputStream();
|
||||
|
||||
|
||||
SAXReader saxReader = new SAXReader();
|
||||
|
||||
Document document = saxReader.read(inputStream);
|
||||
Element rootElement = document.getRootElement();
|
||||
List<Element> elements = rootElement.elements();
|
||||
|
||||
for (Element element : elements) {
|
||||
map.put(element.getName(),element.getStringValue());
|
||||
}
|
||||
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (DocumentException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
System.out.println("接受消息:"+map);
|
||||
|
||||
String replyMessage = getReplyMessage(map);
|
||||
|
||||
System.out.println("返回消息:"+replyMessage);
|
||||
return replyMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSignUpUserInfo(String code) {
|
||||
String appId = TokenUtil.APP_ID;
|
||||
String appSecret = TokenUtil.APP_SECRET;
|
||||
String url= String.format("https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code",appId,appSecret,code);
|
||||
|
||||
String request = OkHttpUtils.sendGetRequest(url);
|
||||
String accessToken = JSONObject.parseObject(request).getString("access_token");
|
||||
String openId = JSONObject.parseObject(request).getString("openid");
|
||||
|
||||
String userInfoUrl= String.format("https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN",accessToken,openId);
|
||||
|
||||
String userInfo = OkHttpUtils.sendGetRequest(userInfoUrl);
|
||||
SubscribedUser subscribedUser = JSONObject.parseObject(userInfo, SubscribedUser.class);
|
||||
System.out.println(subscribedUser);
|
||||
//TODO
|
||||
// 添加数据库
|
||||
|
||||
WechatUtil.send(openId,"授权成功");
|
||||
|
||||
return "恭喜你,信息被盗取了";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得回复的消息内容
|
||||
* @param map
|
||||
* @return
|
||||
*/
|
||||
private String getReplyMessage(HashMap<String, String> map) {
|
||||
Message message = new Message();
|
||||
message.setToUserName(map.get("FromUserName"));
|
||||
message.setFromUserName(map.get("ToUserName"));
|
||||
// message.setMsgType(map.get("MsgType"));
|
||||
message.setMsgType("text");
|
||||
message.setCreateTime(System.currentTimeMillis()/1000);
|
||||
String appId = TokenUtil.APP_ID;
|
||||
String appSecret = TokenUtil.APP_SECRET;
|
||||
String redirectDomain = TokenUtil.REDIRECT_DOMAIN;
|
||||
|
||||
//获取用户授权的url
|
||||
String url = String.format("https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=STATE#wechat_redirect",appId,
|
||||
"http://"+redirectDomain+"/getSignUpUserInfo","snsapi_userinfo") ;
|
||||
|
||||
|
||||
message.setContent("点击给公众号授权链接 <a href=\""+url+"\">授权</a>");
|
||||
XStream xStream =new XStream();
|
||||
xStream.processAnnotations(Message.class);
|
||||
String xml = xStream.toXML(message);
|
||||
return xml;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package com.muyu.service;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* @className: WxService ️✈️
|
||||
* @author: Yang 鹏 🦅
|
||||
* @date: 2024/9/18 12:05 ⏰
|
||||
* @Version: 1.0
|
||||
* @description:
|
||||
*/
|
||||
public interface WxService {
|
||||
String handleMessage(HttpServletRequest request);
|
||||
|
||||
String getSignUpUserInfo(String code);
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package com.muyu.util;
|
||||
|
||||
import okhttp3.*;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class OkHttpUtils {
|
||||
|
||||
private static final OkHttpClient client = new OkHttpClient();
|
||||
|
||||
public static String sendGetRequest(String urlString) {
|
||||
Request request = new Request.Builder()
|
||||
.url(urlString)
|
||||
.build();
|
||||
try (Response response = client.newCall(request).execute()) {
|
||||
return response.body().string();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static String sendPostRequest(String urlString, String params) {
|
||||
RequestBody requestBody = RequestBody.create(params, MediaType.parse("application/json; charset=utf-8"));
|
||||
Request request = new Request.Builder()
|
||||
.url(urlString)
|
||||
.post(requestBody)
|
||||
.build();
|
||||
try (Response response = client.newCall(request).execute()) {
|
||||
return response.body().string();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
package com.muyu.util;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.muyu.domain.AccessToken;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @className: TokenUtil ️✈️
|
||||
* @author: Yang 鹏 🦅
|
||||
* @date: 2024/9/17 20:26 ⏰
|
||||
* @Version: 1.0
|
||||
* @description:
|
||||
*/
|
||||
@Component
|
||||
public class TokenUtil {
|
||||
public final static String APP_ID = "wxa10c6f55da3c0553";
|
||||
|
||||
public final static String APP_SECRET ="72d285981f3f51274e79dcda5e498a81";
|
||||
|
||||
|
||||
//域名
|
||||
public final static String REDIRECT_DOMAIN ="3kknv4.natappfree.cc";
|
||||
|
||||
private static AccessToken accessToken = new AccessToken();
|
||||
|
||||
|
||||
|
||||
|
||||
private static void getToken(){
|
||||
String url = String.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s",APP_ID,APP_SECRET);
|
||||
String request = OkHttpUtils.sendGetRequest(url);
|
||||
AccessToken wechatToken = JSON.parseObject(request, AccessToken.class);
|
||||
//redisService.setCacheObject("WECHAT_TOKEN",wechatToken.getAccessToken(),wechatToken.getExpiresIn(), TimeUnit.SECONDS);
|
||||
if (wechatToken != null) {
|
||||
accessToken.setExpiresTime(wechatToken.getExpires_in());
|
||||
accessToken.setAccess_token(wechatToken.getAccess_token());
|
||||
}
|
||||
}
|
||||
public static String getAccessToken(){
|
||||
getToken();
|
||||
return accessToken.getAccess_token();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package com.muyu.util;
|
||||
|
||||
|
||||
import io.micrometer.common.util.StringUtils;
|
||||
import okhttp3.*;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class WechatUtil {
|
||||
|
||||
public static void send(String toUser,String content) {
|
||||
String accessToken = TokenUtil.getAccessToken();
|
||||
if (!StringUtils.isBlank(accessToken)) {
|
||||
String url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=" + accessToken;
|
||||
String jsonStr = "{\"touser\":\"" + toUser + "\",\"msgtype\":\"text\",\"text\":{\"content\":\"" + content + "\"}}";
|
||||
OkHttpClient client = new OkHttpClient();
|
||||
|
||||
// 构建请求
|
||||
RequestBody requestBody = RequestBody.create(jsonStr, MediaType.get("application/json; charset=utf-8"));
|
||||
Request request = new Request.Builder()
|
||||
.url(url)
|
||||
.post(requestBody)
|
||||
.addHeader("Content-Type", "application/json; charset=utf-8")
|
||||
.build();
|
||||
|
||||
// 发送请求
|
||||
try (Response response = client.newCall(request).execute()) {
|
||||
if (!response.isSuccessful()) {
|
||||
throw new IOException("Unexpected code " + response);
|
||||
}
|
||||
// 输出响应
|
||||
System.out.println(response.body().string());
|
||||
}catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
# Tomcat
|
||||
server:
|
||||
port: 8088
|
||||
##用户授权的重定向域名
|
||||
#redirect:
|
||||
# domain:123
|
||||
##公众号appId和secret
|
||||
#wx:
|
||||
# appId:123
|
||||
# secret:123
|
||||
|
||||
|
Loading…
Reference in New Issue