江体小程序和zlb接口开发 #1
8
pom.xml
8
pom.xml
@@ -145,6 +145,14 @@
|
|||||||
<artifactId>alibaba-dingtalk-service-sdk</artifactId>
|
<artifactId>alibaba-dingtalk-service-sdk</artifactId>
|
||||||
<version>2.0.0</version>
|
<version>2.0.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- aliyun dns解析 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.aliyun</groupId>
|
||||||
|
<artifactId>alidns20150109</artifactId>
|
||||||
|
<version>3.4.7</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package com.xiang.common.config;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@ConfigurationProperties(prefix = "aliyun.dns")
|
||||||
|
@Data
|
||||||
|
public class AliyunDnsPropertyConfig {
|
||||||
|
|
||||||
|
private List<String> RR;
|
||||||
|
|
||||||
|
private String rootDomain;
|
||||||
|
}
|
||||||
@@ -3,8 +3,6 @@ package com.xiang.common.config;
|
|||||||
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
||||||
import com.fasterxml.jackson.annotation.PropertyAccessor;
|
import com.fasterxml.jackson.annotation.PropertyAccessor;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.xiang.common.utils.RedisService;
|
|
||||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.Primary;
|
import org.springframework.context.annotation.Primary;
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package com.xiang.common.enums;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: xiang
|
||||||
|
* @Date: 2026-01-04 16:13
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public enum DingTalkBizTypeEnum implements BaseDingTalkBizType {
|
||||||
|
|
||||||
|
JT("venue", "江南体育中心"),
|
||||||
|
XB("xb", "股票基金变化通知"),
|
||||||
|
SCRIPT("script", "脚本运行通知群")
|
||||||
|
;
|
||||||
|
private final String bizName;
|
||||||
|
private final String desc;
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package com.xiang.common.factory;
|
||||||
|
|
||||||
|
import com.xiang.common.config.DingTalkRobotProperties;
|
||||||
|
import com.xiang.common.enums.DingTalkBizTypeEnum;
|
||||||
|
import com.xiang.common.utils.dingTalk.AbstractDingTalkFactory;
|
||||||
|
import com.xiang.common.utils.dingTalk.DingTalkSender;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class ScriptDingTalkFactory extends AbstractDingTalkFactory {
|
||||||
|
public ScriptDingTalkFactory(DingTalkRobotProperties dingTalkRobotProperties, DingTalkSender dingTalkSender) {
|
||||||
|
super(dingTalkRobotProperties, dingTalkSender);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendMsg(String msg) {
|
||||||
|
getClient(DingTalkBizTypeEnum.SCRIPT).sendDingTalkMsg(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
21
src/main/java/com/xiang/common/utils/IpUtils.java
Normal file
21
src/main/java/com/xiang/common/utils/IpUtils.java
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package com.xiang.common.utils;
|
||||||
|
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: xiang
|
||||||
|
* @Date: 2025-06-10 16:50
|
||||||
|
*/
|
||||||
|
public class IpUtils {
|
||||||
|
|
||||||
|
private final static String PUBLIC_IP_URL = "https://api-ipv4.ip.sb/ip";
|
||||||
|
|
||||||
|
public static String getPublicIp() throws IOException {
|
||||||
|
Map<String, String> header = Maps.newHashMap();
|
||||||
|
header.put("User-Agent", "Mozilla/5.0");
|
||||||
|
return HttpService.doGet(PUBLIC_IP_URL, header, null).trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package com.xiang.service.module.domain.schedule;
|
||||||
|
|
||||||
|
import com.xiang.common.utils.IpUtils;
|
||||||
|
import com.xiang.service.module.domain.service.IDomainService;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class DomainDynamicAnalysisTask {
|
||||||
|
private final IDomainService IDomainService;
|
||||||
|
|
||||||
|
@Scheduled(cron = "0 0/30 * * * ? ")
|
||||||
|
public void dynamicDomainSchedule() {
|
||||||
|
String publicIp = "";
|
||||||
|
try {
|
||||||
|
publicIp = IpUtils.getPublicIp();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("获取公网ip失败,", e);
|
||||||
|
}
|
||||||
|
if (StringUtils.isNotBlank(publicIp)) {
|
||||||
|
try {
|
||||||
|
IDomainService.dynamicDomainAnalysis(publicIp);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("动态解析公网ip失败, ip:{}", publicIp, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
package com.xiang.service.module.domain.server;
|
||||||
|
|
||||||
|
import com.xiang.common.utils.IpUtils;
|
||||||
|
import com.xiang.service.module.domain.service.IDomainService;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@RequestMapping("/script/domain")
|
||||||
|
public class DomainController {
|
||||||
|
|
||||||
|
private final IDomainService domainService;
|
||||||
|
@GetMapping("/ddns")
|
||||||
|
public void dynamicDomainAnalysis() {
|
||||||
|
String publicIp = "";
|
||||||
|
try {
|
||||||
|
publicIp = IpUtils.getPublicIp();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("获取公网ip失败,", e);
|
||||||
|
}
|
||||||
|
if (StringUtils.isNotBlank(publicIp)) {
|
||||||
|
try {
|
||||||
|
domainService.dynamicDomainAnalysis(publicIp);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("动态解析公网ip失败, ip:{}", publicIp, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/ddns4ip")
|
||||||
|
public void dynamicDomainAnalysis(@RequestParam("ip") String ip, @RequestParam("rr") String rr) {
|
||||||
|
try {
|
||||||
|
domainService.dynamicDomainAnalysis(ip, rr);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("动态解析公网ip失败, ip:{}", ip, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package com.xiang.service.module.domain.service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: xiang
|
||||||
|
* @Date: 2025-06-10 16:48
|
||||||
|
*/
|
||||||
|
public interface IDomainService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 动态域名解析
|
||||||
|
* @param publicIp 动态ip
|
||||||
|
*/
|
||||||
|
void dynamicDomainAnalysis(String publicIp) throws Exception;
|
||||||
|
void dynamicDomainAnalysis(String publicIp, String rr) throws Exception;
|
||||||
|
}
|
||||||
@@ -0,0 +1,111 @@
|
|||||||
|
package com.xiang.service.module.domain.service;
|
||||||
|
|
||||||
|
|
||||||
|
import com.aliyun.alidns20150109.Client;
|
||||||
|
import com.aliyun.alidns20150109.models.AddDomainRecordRequest;
|
||||||
|
import com.aliyun.alidns20150109.models.DescribeSubDomainRecordsRequest;
|
||||||
|
import com.aliyun.alidns20150109.models.DescribeSubDomainRecordsResponse;
|
||||||
|
import com.aliyun.alidns20150109.models.DescribeSubDomainRecordsResponseBody;
|
||||||
|
import com.aliyun.alidns20150109.models.UpdateDomainRecordRequest;
|
||||||
|
import com.aliyun.teaopenapi.models.Config;
|
||||||
|
import com.xiang.common.config.AliyunDnsPropertyConfig;
|
||||||
|
import com.xiang.common.factory.ScriptDingTalkFactory;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: xiang
|
||||||
|
* @Date: 2025-06-10 16:48
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@Slf4j
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class IDomainServiceImpl implements IDomainService {
|
||||||
|
|
||||||
|
private static final String ACCESS_KEY_ID = "LTAI5tDMjaVF8Bbqcpp4dmvP";
|
||||||
|
private static final String ACCESS_KEY_SECRET = "nkmnaNjWQy5984C5kjyS0oDmdMKGQd";
|
||||||
|
/**
|
||||||
|
* 根域名
|
||||||
|
*/
|
||||||
|
@Value("${aliyun.dns.rootDomain}")
|
||||||
|
private String rootDomain;
|
||||||
|
/**
|
||||||
|
* 主机记录,例如 home.example.com
|
||||||
|
*/
|
||||||
|
private final AliyunDnsPropertyConfig aliyunDnsPropertyConfig;
|
||||||
|
private static final String TYPE = "A";
|
||||||
|
|
||||||
|
private final ScriptDingTalkFactory dingTalkService;
|
||||||
|
@Override
|
||||||
|
public void dynamicDomainAnalysis(String publicIp) throws Exception {
|
||||||
|
Client client = createClient();
|
||||||
|
|
||||||
|
for (String rr : aliyunDnsPropertyConfig.getRR()) {
|
||||||
|
record(client, publicIp, rr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dynamicDomainAnalysis(String publicIp, String rr) throws Exception {
|
||||||
|
Client client = createClient();
|
||||||
|
record(client, publicIp, rr);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void record(Client client, String publicIp, String rr) throws Exception{
|
||||||
|
// 查询记录
|
||||||
|
DescribeSubDomainRecordsRequest query = new DescribeSubDomainRecordsRequest()
|
||||||
|
.setSubDomain(rr + "." + rootDomain)
|
||||||
|
.setType(TYPE);
|
||||||
|
DescribeSubDomainRecordsResponse response = client.describeSubDomainRecords(query);
|
||||||
|
List<DescribeSubDomainRecordsResponseBody.DescribeSubDomainRecordsResponseBodyDomainRecordsRecord> records =
|
||||||
|
response.getBody().getDomainRecords().getRecord();
|
||||||
|
|
||||||
|
if (records.isEmpty()) {
|
||||||
|
log.info("未找到记录,添加记录..., ip:{}", publicIp);
|
||||||
|
addDnsRecord(client, publicIp, rr);
|
||||||
|
dingTalkService.sendMsg("动态解析公网ip成功,域名:" + rr + "." + rootDomain + ", 新ip:" + publicIp);
|
||||||
|
} else {
|
||||||
|
String recordId = records.get(0).getRecordId();
|
||||||
|
String currentValue = records.get(0).getValue();
|
||||||
|
if (!publicIp.equals(currentValue)) {
|
||||||
|
log.info("IP变更,更新记录...,ip:{}", publicIp);
|
||||||
|
updateDnsRecord(client, recordId, publicIp, rr);
|
||||||
|
dingTalkService.sendMsg("动态解析公网ip成功,域名:" + rr + "." + rootDomain + ", 新ip:" + publicIp);
|
||||||
|
} else {
|
||||||
|
log.info("ip未变更,无需修改,ip:{}", publicIp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Client createClient() throws Exception {
|
||||||
|
Config config = new Config()
|
||||||
|
.setAccessKeyId(ACCESS_KEY_ID)
|
||||||
|
.setAccessKeySecret(ACCESS_KEY_SECRET)
|
||||||
|
.setEndpoint("alidns.cn-hangzhou.aliyuncs.com");
|
||||||
|
return new Client(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateDnsRecord(Client client, String recordId, String newIp, String rr) throws Exception {
|
||||||
|
UpdateDomainRecordRequest request = new UpdateDomainRecordRequest()
|
||||||
|
.setRecordId(recordId)
|
||||||
|
.setRR(rr)
|
||||||
|
.setType(TYPE)
|
||||||
|
.setValue(newIp);
|
||||||
|
client.updateDomainRecord(request);
|
||||||
|
log.info("更新成功: ,newIP:{}", newIp);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addDnsRecord(Client client, String ip, String rr) throws Exception {
|
||||||
|
AddDomainRecordRequest request = new AddDomainRecordRequest()
|
||||||
|
.setDomainName(rootDomain)
|
||||||
|
.setRR(rr)
|
||||||
|
.setType(TYPE)
|
||||||
|
.setValue(ip);
|
||||||
|
client.addDomainRecord(request);
|
||||||
|
log.info("添加成功: ip:{}", ip);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,7 +15,7 @@ spring:
|
|||||||
host: r-bp1wt59a6nfyt4e3ltpd.redis.rds.aliyuncs.com
|
host: r-bp1wt59a6nfyt4e3ltpd.redis.rds.aliyuncs.com
|
||||||
port: 6379
|
port: 6379
|
||||||
password: Xiang0000
|
password: Xiang0000
|
||||||
database: 11
|
database: 10
|
||||||
timeout: 3000
|
timeout: 3000
|
||||||
lettuce:
|
lettuce:
|
||||||
pool:
|
pool:
|
||||||
@@ -23,3 +23,32 @@ spring:
|
|||||||
max-idle: 10
|
max-idle: 10
|
||||||
min-idle: 2
|
min-idle: 2
|
||||||
max-wait: 3000
|
max-wait: 3000
|
||||||
|
|
||||||
|
aliyun:
|
||||||
|
dns:
|
||||||
|
rootDomain: xiangtech.xyz
|
||||||
|
RR:
|
||||||
|
- local
|
||||||
|
|
||||||
|
|
||||||
|
dingtalk:
|
||||||
|
robot:
|
||||||
|
properties:
|
||||||
|
venue:
|
||||||
|
name: 江南体育中心通知群
|
||||||
|
token: 6a218646972c684c75832b0229ea93a234778af537d7469ce96bef290faf530e
|
||||||
|
secret: SEC9018755ba86d3e5c1ed2fbfa1d6953d84bb2a6c8ebe7ed4e318457bfed5e0465
|
||||||
|
users:
|
||||||
|
- 450841600726084717
|
||||||
|
script:
|
||||||
|
name: 脚本运行通知群
|
||||||
|
token: 797be7f32062e31dec1d567f8b490a5649a5366083618e236c7a1263df1f4af3
|
||||||
|
secret: SEC9aca642c0c29c9da261462869c464d34623247583d98fc82343a0a4464abbe91
|
||||||
|
users:
|
||||||
|
- 450841600726084717
|
||||||
|
xb:
|
||||||
|
name: 股票基金变化通知群
|
||||||
|
token: ad21ead99f0fdc63aa00d6732b7b0888c17590f7612c68297edfcb71844d1437
|
||||||
|
secret: SECc09d8aad6635f1a4cbadb7c0ab365523c46299f138438cd885e445e0f5f4d730
|
||||||
|
users:
|
||||||
|
- 450841600726084717
|
||||||
Reference in New Issue
Block a user