wrapper = new QueryWrapper<>();
+ wrapper.eq("phone_number", phoneNumberToSearch);
+ QyWeChatURL result = qyWeChatURLMapper.selectOne(wrapper);
+ if (result == null){
+ logger.error("queryLRL error");
+ }
+ sendTextCardMessageUrl = result.getSendTextCardMessageUrl();
+ qyWechatGetTokenUrl = result.getQyWechatGetTokenUrl();
+ };
+}
diff --git a/src/main/java/com/kimgo/wepush/service/SMSService.java b/src/main/java/com/kimgo/wepush/service/SMSService.java
new file mode 100644
index 0000000..cfdabeb
--- /dev/null
+++ b/src/main/java/com/kimgo/wepush/service/SMSService.java
@@ -0,0 +1,107 @@
+package com.kimgo.wepush.service;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.kimgo.wepush.common.QyWeChatSendMessageApiResponse;
+import com.kimgo.wepush.config.URLConfig;
+import com.kimgo.wepush.model.SMSInfo;
+import com.kimgo.wepush.model.TextCardMessage;
+import com.kimgo.wepush.response.ServerResponseEntity;
+import okhttp3.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.kimgo.wepush.config.UserConfig;
+import java.io.IOException;
+
+@Service
+public class SMSService {
+ private final Logger logger = LoggerFactory.getLogger(SMSService.class);
+ @Autowired
+ private UserConfig userConfig;
+ @Autowired
+ private ApiSettingService apiSettingService;
+ @Autowired
+ private TokenService tokenService;
+ @Autowired
+ private URLConfig urlConfig;
+
+ public ServerResponseEntity getSMSInfo(String accessToken, SMSInfo smsInfo){
+ String correctAccessToken = tokenService.getApiAccessToken();
+ logger.info("accessToken: {} correctAccessToken: {}",accessToken,correctAccessToken);
+ if (!correctAccessToken.equals(accessToken)){
+ return ServerResponseEntity.fail("Invalid accessToken");
+ }
+ String qyAccessToken = tokenService.getAccessToken();
+ QyWeChatSendMessageApiResponse qyWeChatSendMessageApiResponse = requestWithOkhttp(qyAccessToken,smsInfo);
+ if (qyWeChatSendMessageApiResponse != null){
+ return ServerResponseEntity.success(qyWeChatSendMessageApiResponse.getMsgid());
+ }
+ return ServerResponseEntity.fail("request qyWeChat error,please check server error log.");
+ }
+
+ public QyWeChatSendMessageApiResponse requestWithOkhttp(String accessToken,SMSInfo smsInfo){
+ OkHttpClient client = new OkHttpClient();
+ String url = urlConfig.getSendTextCardMessageUrl() + accessToken;
+
+ TextCardMessage textCardMessage = setTextCardMessage(smsInfo);
+ // 使用Jackson进行序列化
+ ObjectMapper objectMapper = new ObjectMapper();
+ String jsonBody = null;
+ try {
+ jsonBody = objectMapper.writeValueAsString(textCardMessage);
+ logger.info("jsonBody: {}",jsonBody);
+ } catch (JsonProcessingException e) {
+ logger.error("JSON processing error", e);
+ return null;
+ }
+ // 构建请求体
+ RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), jsonBody);
+ Request request = new Request.Builder().url(url).post(body).build();
+ try (Response response = client.newCall(request).execute()) {
+ String responseBody = response.body().string();
+ logger.info("Response: {}", responseBody);
+
+ ObjectMapper objectMapper1 = new ObjectMapper();
+ QyWeChatSendMessageApiResponse apiResponse = objectMapper1.readValue(responseBody, QyWeChatSendMessageApiResponse.class);
+
+ if (apiResponse.getErrcode() == 0) {
+ return apiResponse;
+ } else if (apiResponse.getErrcode() == 42001 || apiResponse.getErrcode() == 40014) {
+ logger.info("Access token expired. Refreshing token...");
+ tokenService.setAccessToken(); // 一个方法来刷新accessToken
+ String newAccessToken = tokenService.getAccessToken();
+ return requestWithOkhttp(newAccessToken, smsInfo);
+ } else {
+ // 处理其他错误情况
+ logger.error("Error: {}", apiResponse.getErrmsg());
+ return apiResponse;
+ }
+ } catch (IOException e) {
+ logger.error("OkHttp request error", e);
+ return null;
+ }
+ }
+
+ public TextCardMessage setTextCardMessage(SMSInfo smsInfo) {
+ TextCardMessage textCardMessage = new TextCardMessage();
+
+ textCardMessage.setTouser(apiSettingService.getApiSetting().getTouser());
+ textCardMessage.setMsgtype(apiSettingService.getApiSetting().getMsgtype());
+ textCardMessage.setAgentid(apiSettingService.getApiSetting().getAgentid());
+ textCardMessage.setEnable_duplicate_check(apiSettingService.getApiSetting().getEnable_duplicate_check());
+ textCardMessage.setDuplicate_check_interval(apiSettingService.getApiSetting().getDuplicate_check_interval());
+
+ TextCardMessage.TextCard textCard = new TextCardMessage.TextCard();
+ textCard.setTitle("新短信通知");
+ textCard.setDescription("您有一条新短信
短信号码: " + smsInfo.getSmsNumber() + "
接受短信时间: " + smsInfo.getSmsAcceptanceTime() + "
" + smsInfo.getSmsContent());
+ textCard.setUrl("https://kimgo.cn");
+ // 将TextCard对象设置到TextCardMessage中
+ textCardMessage.setTextcard(textCard);
+
+ logger.info("TextCardMessage: {}", textCardMessage.toString());
+
+ return textCardMessage;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/kimgo/wepush/service/TokenService.java b/src/main/java/com/kimgo/wepush/service/TokenService.java
new file mode 100644
index 0000000..5de768d
--- /dev/null
+++ b/src/main/java/com/kimgo/wepush/service/TokenService.java
@@ -0,0 +1,95 @@
+package com.kimgo.wepush.service;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.kimgo.wepush.config.UserConfig;
+import com.kimgo.wepush.mapper.ApiSettingMapper;
+import com.kimgo.wepush.mapper.QyWeChatAppInfoMapper;
+import com.kimgo.wepush.model.QyWeChatAppInfo;
+import com.kimgo.wepush.request.WeChatAPI;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class TokenService {
+ private final Logger logger = LoggerFactory.getLogger(TokenService.class);
+ @Autowired
+ private UserConfig userConfig;
+ @Autowired
+ private QyWeChatAppInfoMapper qyWeChatAppInfoMapper;
+ @Autowired
+ private ApiSettingMapper apiSettingMapper;
+ private String accessToken;
+ private String apiAccessToken;
+
+ public String getAccessToken() {
+ if (accessToken == null) {
+ updateAccessToken();
+ }
+ return accessToken;
+ }
+
+ public String getApiAccessToken(){
+ if (apiAccessToken == null){
+ updateApiAccessToken();
+ }
+ return apiAccessToken;
+ }
+
+
+ public void updateAccessToken() {
+ String phoneNumberToSearch = userConfig.getPhoneNumber();
+ QueryWrapper wrapper = new QueryWrapper<>();
+ wrapper.eq("phone_number", phoneNumberToSearch);
+ QyWeChatAppInfo result = qyWeChatAppInfoMapper.selectOne(wrapper);
+ if (result == null){
+ accessToken = null;
+ logger.error("updateAccessToken error");
+ }
+ accessToken = result.getAccessToken();
+ logger.info("get accessToken from mysql,accessToken: {}",accessToken);
+ }
+ public void setAccessToken(){
+ String phoneNumberToSearch = userConfig.getPhoneNumber();
+ QueryWrapper wrapper = new QueryWrapper<>();
+ wrapper.eq("phone_number", phoneNumberToSearch);
+ QyWeChatAppInfo result = qyWeChatAppInfoMapper.selectOne(wrapper);
+ if (result != null){
+ WeChatAPI weChatAPI = new WeChatAPI();
+ String accessToken1 = weChatAPI.getAccessToken(result.getCorpId(), result.getCorpSecret());
+ if (accessToken1 == null){
+ logger.error("accessToken1 == null");
+ }
+ accessToken = accessToken1;
+ updateAccessTokenToMysql(accessToken,phoneNumberToSearch);
+ }
+ }
+
+ public void updateAccessTokenToMysql(String accessToken,String phoneNumber){
+ UpdateWrapper updateWrapper = new UpdateWrapper<>();
+ updateWrapper.eq("phone_number", phoneNumber); // 根据 phoneNumber 更新
+ updateWrapper.set("access_token", accessToken); // 设置新的 accessToken
+
+ int result = qyWeChatAppInfoMapper.update(null, updateWrapper);
+ if (result > 0) {
+ logger.info("Update successful");
+ } else {
+ logger.warn("Update failed: No rows affected");
+ }
+ }
+
+ public void updateApiAccessToken(){
+ String phoneNumberToSearch = userConfig.getPhoneNumber();
+ QueryWrapper wrapper = new QueryWrapper<>();
+ wrapper.eq("phone_number", phoneNumberToSearch);
+ ApiSetting result = apiSettingMapper.selectOne(wrapper);
+ if (result == null){
+ apiAccessToken = null;
+ logger.error("updateApiAccessToken error");
+ }
+ apiAccessToken = result.getAccessToken();
+ logger.info("get ApiAccessToken from mysql,accessToken: {}",apiAccessToken);
+ }
+}
diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml
new file mode 100644
index 0000000..8ca7728
--- /dev/null
+++ b/src/main/resources/application-dev.yml
@@ -0,0 +1,13 @@
+custom:
+ phoneNumber: "18281561650"
+ accessToken: "gKGCDSgWV82XbU0H"
+ touser: "@all"
+url:
+ sendTextCardMessageUrl: "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token="
+spring:
+ datasource:
+ url: jdbc:mysql://42.193.20.110:8006/qywechatpush?useSSL=false
+ username: qywechatpush
+ password: JSckhtke1wFdzq3E
+ driver-class-name: com.mysql.cj.jdbc.Driver
+mybatis-plus:
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
new file mode 100644
index 0000000..9064036
--- /dev/null
+++ b/src/main/resources/application.yml
@@ -0,0 +1,6 @@
+server:
+ address: 127.0.0.1
+ port: 8080
+spring:
+ profiles:
+ active: dev
\ No newline at end of file
diff --git a/src/test/java/com/kimgo/wepush/ApiSettingServiceTest.java b/src/test/java/com/kimgo/wepush/ApiSettingServiceTest.java
new file mode 100644
index 0000000..69c7ef5
--- /dev/null
+++ b/src/test/java/com/kimgo/wepush/ApiSettingServiceTest.java
@@ -0,0 +1,18 @@
+package com.kimgo.wepush;
+
+import com.kimgo.wepush.service.ApiSettingService;
+import com.kimgo.wepush.service.TokenService;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+public class ApiSettingServiceTest {
+
+ @Autowired
+ private ApiSettingService apiSettingService;
+ @Test
+ public void testQueryApiSetting(){
+ apiSettingService.getApiSetting();
+ }
+}
diff --git a/src/test/java/com/kimgo/wepush/QyWeChatAppInfoMapperTest.java b/src/test/java/com/kimgo/wepush/QyWeChatAppInfoMapperTest.java
new file mode 100644
index 0000000..88d5a24
--- /dev/null
+++ b/src/test/java/com/kimgo/wepush/QyWeChatAppInfoMapperTest.java
@@ -0,0 +1,43 @@
+package com.kimgo.wepush;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.kimgo.wepush.mapper.QyWeChatAppInfoMapper;
+import com.kimgo.wepush.model.QyWeChatAppInfo;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import java.util.List;
+
+@SpringBootTest
+public class QyWeChatAppInfoMapperTest {
+
+ @Autowired
+ private QyWeChatAppInfoMapper qyWeChatAppInfoMapper;
+ @Test
+ public void testSelect() {
+ System.out.println(("----- select by id test ------"));
+ QyWeChatAppInfo qyWeChatAppInfo = qyWeChatAppInfoMapper.selectById("1");
+ System.out.printf(qyWeChatAppInfo.toString());
+ System.out.printf("test complete");
+ }
+
+ @Test
+ public void testSelectByPhoneNumber() {
+ System.out.println("----- select by phoneNumber test ------");
+
+ QueryWrapper wrapper = new QueryWrapper<>();
+ wrapper.eq("phone_number", "18281561650");
+
+ QyWeChatAppInfo result = qyWeChatAppInfoMapper.selectOne(wrapper);
+
+ // 打印结果
+ if (result != null) {
+ System.out.println(result);
+ } else {
+ System.out.println("No record found.");
+ }
+
+ System.out.println("Test complete");
+ }
+}
diff --git a/src/test/java/com/kimgo/wepush/QyWeChatURLServiceTest.java b/src/test/java/com/kimgo/wepush/QyWeChatURLServiceTest.java
new file mode 100644
index 0000000..cc62ce3
--- /dev/null
+++ b/src/test/java/com/kimgo/wepush/QyWeChatURLServiceTest.java
@@ -0,0 +1,14 @@
+package com.kimgo.wepush;
+
+import com.kimgo.wepush.service.QyWeChatURLService;
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+public class QyWeChatURLServiceTest {
+ private QyWeChatURLService qyWeChatURLService;
+ @Test
+ public void testUpdateAccessToken(){
+ System.out.printf(qyWeChatURLService.getSendTextCardMessageUrl());
+ }
+}
diff --git a/src/test/java/com/kimgo/wepush/TokenServiceTest.java b/src/test/java/com/kimgo/wepush/TokenServiceTest.java
new file mode 100644
index 0000000..8f01c48
--- /dev/null
+++ b/src/test/java/com/kimgo/wepush/TokenServiceTest.java
@@ -0,0 +1,32 @@
+package com.kimgo.wepush;
+
+import com.kimgo.wepush.service.TokenService;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.stereotype.Service;
+
+@SpringBootTest
+public class TokenServiceTest {
+ @Autowired
+ private TokenService tokenService;
+ @Test
+ public void testUpdateAccessToken(){
+ System.out.printf(tokenService.getAccessToken());
+ }
+ @Test
+ public void testUpdateAccessTokenToMysql(){
+ String token = "1dfeibiffekjbfe";
+ String phoneNumber = "18281561650";
+ tokenService.updateAccessTokenToMysql(token,phoneNumber);
+ }
+ @Test
+ public void testSetAccessTokenToMysql(){
+ tokenService.setAccessToken();
+ }
+
+ @Test
+ public void testUpdateApiAccessToken(){
+ tokenService.updateApiAccessToken();
+ }
+}
diff --git a/src/test/java/com/kimgo/wepush/WePushApplicationTests.java b/src/test/java/com/kimgo/wepush/WePushApplicationTests.java
new file mode 100644
index 0000000..0957a09
--- /dev/null
+++ b/src/test/java/com/kimgo/wepush/WePushApplicationTests.java
@@ -0,0 +1,13 @@
+package com.kimgo.wepush;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+class WePushApplicationTests {
+
+ @Test
+ void contextLoads() {
+ }
+
+}