feat:first commit

This commit is contained in:
xiang
2025-07-17 22:45:09 +08:00
commit 2acfac4341
15 changed files with 698 additions and 0 deletions

169
pom.xml Normal file
View File

@@ -0,0 +1,169 @@
<?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.xiang</groupId>
<artifactId>xservice-basic</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>xservice-common</module>
<module>xservice-cache</module>
<module>xservice-third-part</module>
</modules>
<properties>
<java.version>17</java.version>
<spring.boot.version>2.7.18</spring.boot.version>
<spring.cloud.version>2021.0.8</spring.cloud.version>
<mybatis.spring.boot.version>2.2.2</mybatis.spring.boot.version>
<rocketmq.version>5.1.4</rocketmq.version>
<mysql.version>8.0.33</mysql.version>
<lombok.version>1.18.30</lombok.version>
<fastjson2.version>2.0.51</fastjson2.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<encoding>UTF-8</encoding>
<guava.version>16.0.1</guava.version>
<mybatis-spring-boot.version>2.3.1</mybatis-spring-boot.version>
<mysql.version>8.0.33</mysql.version>
<lombok.version>1.18.30</lombok.version>
<spring-data-redis.version>3.23.6</spring-data-redis.version>
<rocketmq.version>2.2.3</rocketmq.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- Spring Boot BOM -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- Spring Cloud BOM -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring.cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- MySQL -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!-- MyBatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis-spring-boot.version}</version>
</dependency>
<!-- Redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- RocketMQ -->
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
<version>${rocketmq.version}</version>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<!-- 常用工具 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- http -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
<!-- collections -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>32.0.1-android</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.2</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.15.0</version>
</dependency>
<!-- json -->
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.51</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>${encoding}</encoding>
<parameters>true</parameters>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<distributionManagement>
<repository>
<id>releases</id>
<url>http://192.168.2.10:33010/repository/maven-releases/</url>
</repository>
<snapshotRepository>
<id>snapshot</id>
<url>http://192.168.2.10:33010/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
</project>

20
xservice-cache/pom.xml Normal file
View File

@@ -0,0 +1,20 @@
<?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>
<parent>
<groupId>com.xiang</groupId>
<artifactId>xservice-basic</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>xservice-cache</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>

View File

@@ -0,0 +1,17 @@
package com.xiang.xservice.basic;
//TIP To <b>Run</b> code, press <shortcut actionId="Run"/> or
// click the <icon src="AllIcons.Actions.Execute"/> icon in the gutter.
public class Main {
public static void main(String[] args) {
//TIP Press <shortcut actionId="ShowIntentionActions"/> with your caret at the highlighted text
// to see how IntelliJ IDEA suggests fixing it.
System.out.printf("Hello and welcome!");
for (int i = 1; i <= 5; i++) {
//TIP Press <shortcut actionId="Debug"/> to start debugging your code. We have set one <icon src="AllIcons.Debugger.Db_set_breakpoint"/> breakpoint
// for you, but you can always add more by pressing <shortcut actionId="ToggleLineBreakpoint"/>.
System.out.println("i = " + i);
}
}
}

22
xservice-common/pom.xml Normal file
View File

@@ -0,0 +1,22 @@
<?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>
<parent>
<groupId>com.xiang</groupId>
<artifactId>xservice-basic</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>xservice-common</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>

View File

@@ -0,0 +1,33 @@
package com.xiang.xservice.basic.common.req;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class BaseRequest {
/**
* 操作人
*/
private String operator;
/**
* 分页大小
*/
private Integer pageSize;
/**
* 当前页数
*/
private Integer current;
/**
* 时间
*/
private LocalDateTime dateTime;
}

View File

@@ -0,0 +1,17 @@
package com.xiang.xservice.basic.common.req;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class IdRequest {
/**
* ID
*/
private Long id;
}

View File

@@ -0,0 +1,51 @@
package com.xiang.xservice.basic.common.resp;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Collections;
import java.util.List;
/**
* @Author: xiang
* @Date: 2025-05-09 14:09
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Result<T> {
private String code;
private String message;
private List<T> data;
public static Result<Void> success(String message) {
return new Result<Void>("200", message, null);
}
public static <T> Result<T> success(String message, List<T> data) {
return new Result<T>("200", message, data);
}
public static <T> Result<T> success(String message, T data) {
return new Result<T>("200", message, Collections.singletonList(data));
}
public static <T> Result<T> error(String message) {
return new Result<T>("500", message, null);
}
public static <T> Result<T> error(String message, T data) {
return new Result<T>("500", message, Collections.singletonList(data));
}
public static <T> Result<T> error(String message, List<T> data) {
return new Result<T>("500", message, data);
}
public static Result<Void> error(String code, String message) {
return new Result<Void>(code, message, null);
}
}

View File

@@ -0,0 +1,23 @@
package com.xiang.xservice.basic.config;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;
public class MyThreadFactory implements ThreadFactory {
private final String threadName;
private final boolean daemon;
private final AtomicInteger threadNum = new AtomicInteger();
public MyThreadFactory(String threadName, boolean daemon) {
this.threadName = threadName;
this.daemon = daemon;
}
@Override
public Thread newThread(Runnable r) {
Thread thread = new Thread(r, this.threadName + "[#" + threadNum.incrementAndGet() + "]");
thread.setDaemon(this.daemon);
return thread;
}
}

View File

@@ -0,0 +1,16 @@
package com.xiang.xservice.basic.enums;
import lombok.Getter;
@Getter
public enum HttpMethodEnums {
GET("get"),
POST("post"),
;
final String method;
HttpMethodEnums(String method) {
this.method = method;
}
}

View File

@@ -0,0 +1,4 @@
package com.xiang.xservice.basic.utils;
public class DateUtils {
}

View File

@@ -0,0 +1,126 @@
package com.xiang.xservice.basic.utils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import java.io.Closeable;
import java.io.IOException;
import java.util.Map;
import java.util.Set;
/**
* @Author: xiang
* @Date: 2025-05-08 14:39
*/
@Slf4j
public class HttpUtils {
private static final int socketTimeOut = 60 * 1000;
private static final int connectTimeout = 60 * 1000;
private static final int connectionRequestTimeout = 15 * 1000;
private static final int defaultMaxPerRoute = 500;
private static final int maxTotal = 2000;
public static String doPost(String url, Map<String, String> header, String jsonParams) {
RequestConfig requestConfig = RequestConfig.custom()
// 设置连接超时时间
.setConnectTimeout(connectTimeout)
// 设置Socket超时时间
.setSocketTimeout(socketTimeOut)
.setConnectionRequestTimeout(connectionRequestTimeout)
.build();
//创建httpClient对象
CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(requestConfig).build();
CloseableHttpResponse response = null;
String result = "";
try {
// 创建http请求
HttpPost httpPost = getPost(url, header, jsonParams);
response = httpClient.execute(httpPost);
result = EntityUtils.toString(response.getEntity(), "utf-8");
} catch (Exception e) {
log.error("doPost异常", e);
} finally {
//关闭资源
closeResource(response, httpClient);
}
return result;
}
private static HttpPost getPost(String url, Map<String, String> header, String jsonParams) {
HttpPost httpPost = new HttpPost(url);
httpPost.addHeader("Content-Type", "application/json");
// 创建请求内容
StringEntity entity = new StringEntity(jsonParams, "utf-8");
entity.setContentType("application/json");
httpPost.setEntity(entity);
// 设置请求头
if (null != header && !header.isEmpty()) {
Set<Map.Entry<String, String>> entries = header.entrySet();
for (Map.Entry<String, String> e : entries) {
httpPost.setHeader(e.getKey(), e.getValue());
}
}
return httpPost;
}
public static String doGet(String url, Map<String, String> header, Map<String, String> param) {
RequestConfig requestConfig = RequestConfig.custom()
// 设置连接超时时间
.setConnectTimeout(connectTimeout)
// 设置Socket超时时间
.setSocketTimeout(socketTimeOut)
.setConnectionRequestTimeout(connectionRequestTimeout)
.build();
CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(requestConfig).build();
CloseableHttpResponse response;
String result = "";
try {
String request = "";
if (MapUtils.isNotEmpty(param)) {
StringBuilder req = new StringBuilder("?");
for (Map.Entry<String, String> entry : param.entrySet()) {
req.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
}
request = req.substring(0, req.length() - 1);
}
HttpGet httpGet = new HttpGet(url + request);
httpGet.addHeader("Content-Type", "application/json");
if (MapUtils.isNotEmpty(header)) {
for (Map.Entry<String, String> entry : header.entrySet()) {
httpGet.setHeader(entry.getKey(), entry.getValue());
}
}
log.info("doGet请求请求地址{}", url + request);
response = httpClient.execute(httpGet);
result = EntityUtils.toString(response.getEntity(), "utf-8");
} catch (Exception e) {
log.error("doGet异常", e);
}
return result;
}
/**
* @Description 关闭资源
*/
private static void closeResource(Closeable... resources) {
try {
for (Closeable resource : resources) {
if (resource != null) {
resource.close();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,21 @@
package com.xiang.xservice.basic.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 HttpUtils.doGet(PUBLIC_IP_URL, header, null).trim();
}
}

View File

@@ -0,0 +1,42 @@
<?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>
<parent>
<groupId>com.xiang</groupId>
<artifactId>xservice-basic</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>xservice-third-part</artifactId>
<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.xiang</groupId>
<artifactId>xservice-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- 钉钉jar包 -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>alibaba-dingtalk-service-sdk</artifactId>
<version>2.0.0</version>
</dependency>
<!-- aliyun dns解析 -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>alidns20150109</artifactId>
<version>3.4.7</version>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,26 @@
package com.xiang.xservice.basic.xservice.dingTalk.enums;
import lombok.Getter;
@Getter
public enum DingTalkUrlEnum {
/**
* 钉钉接口枚举
*/
DING_TALK_GET_ENTERPRISE_INTER_TOKEN("https://oapi.dingtalk.com/gettoken", "获取企业内部应用Token"),
DING_TALK_ASYNC_SEND_MESSAGE("https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2", "异步发送工作通知"),
DING_TALK_CHAR_MESSAGE("https://oapi.dingtalk.com/chat/send", "发送消息到企业群旧版SDK"),
;
final String url;
final String desc;
DingTalkUrlEnum(String url, String desc) {
this.url = url;
this.desc = desc;
}
}

View File

@@ -0,0 +1,111 @@
package com.xiang.xservice.basic.xservice.dingTalk.service;
import com.alibaba.fastjson2.JSONObject;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiChatSendRequest;
import com.dingtalk.api.request.OapiGettokenRequest;
import com.dingtalk.api.request.OapiMessageCorpconversationAsyncsendV2Request;
import com.dingtalk.api.response.OapiChatSendResponse;
import com.dingtalk.api.response.OapiGettokenResponse;
import com.dingtalk.api.response.OapiMessageCorpconversationAsyncsendV2Response;
import com.xiang.xservice.basic.xservice.dingTalk.enums.DingTalkUrlEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@Slf4j
@Service
public class DingTalkService {
/**
* 应用凭证id
* https://open-dev.dingtalk.com/fe/ai?hash=%23%2Fapp%2F3fa4c9a7-27f2-4d6f-bbe7-41d2a17b5c11%2Fbaseinfo#/app/3fa4c9a7-27f2-4d6f-bbe7-41d2a17b5c11/baseinfo
*/
private static final String APP_ID = "3fa4c9a7-27f2-4d6f-bbe7-41d2a17b5c11";
/**
* 原企业内部应用AgentID
*/
private static final String AGENT_ID = "3829551658";
/**
* 组织ID
*
*/
private static final String CORP_ID = "dingf2c4425cd179a26ef2c783f7214b6d69";
private static final String CLIENT_ID = "dingcc9fikz1c0e5wb9v";
private static final String CLIENT_SECRET = "wyapsH6y8P1K_wuTPKGKwG0mquj1uth9Dxn6HcRpta3sh8Syukl0C8nOmR1PeBzs";
private static final String GRANT_TYPE = "client_credentials";
private static final String USER_ID = "450841600726084717";
private static final String MSG_TYPE = "text";
/**
* 发送消息到企业群
* @return
*/
public String sendChatMessage(String chatId, String message) throws Exception{
String token = getToken();
DefaultDingTalkClient client = new DefaultDingTalkClient(DingTalkUrlEnum.DING_TALK_CHAR_MESSAGE.getUrl());
OapiChatSendRequest req = new OapiChatSendRequest();
req.setChatid(chatId);
OapiChatSendRequest.Msg msg = new OapiChatSendRequest.Msg();
OapiChatSendRequest.Text text = new OapiChatSendRequest.Text();
text.setContent(message);
msg.setText(text);
msg.setMsgtype("text");
req.setMsg(msg);
OapiChatSendResponse rsp = client.execute(req, token);
log.info("[DingTalk] send chat message, req:{}, token:{}, response:{}", JSONObject.toJSONString(req), token, JSONObject.toJSONString(rsp));
return rsp.getMessageId();
}
/**
* 异步发送工作同志--文本类型
* @param userId
* @param message
* @return
* @throws Exception
*/
public String asyncSendMessage(String userId, String message) throws Exception {
String token = getToken();
DingTalkClient client = new DefaultDingTalkClient(DingTalkUrlEnum.DING_TALK_ASYNC_SEND_MESSAGE.getUrl());
OapiMessageCorpconversationAsyncsendV2Request req = new OapiMessageCorpconversationAsyncsendV2Request();
req.setAgentId(Long.parseLong(AGENT_ID));
req.setUseridList(userId);
req.setToAllUser(false);
OapiMessageCorpconversationAsyncsendV2Request.Msg obj1 = new OapiMessageCorpconversationAsyncsendV2Request.Msg();
obj1.setMsgtype(MSG_TYPE);
OapiMessageCorpconversationAsyncsendV2Request.Text obj2 = new OapiMessageCorpconversationAsyncsendV2Request.Text();
obj2.setContent(message);
obj1.setText(obj2);
req.setMsg(obj1);
log.info("send Ding Talk message, userId:{}, message:{}", userId, message);
OapiMessageCorpconversationAsyncsendV2Response rsp = client.execute(req, token);
log.info("send Ding Talk message response, taskId:{}", JSONObject.toJSONString(rsp));
return rsp.getTaskId().toString();
}
/**
* 获取企业内部应用token
*
* @return
* @throws Exception
*/
public String getToken() throws Exception {
DingTalkClient client = new DefaultDingTalkClient(DingTalkUrlEnum.DING_TALK_GET_ENTERPRISE_INTER_TOKEN.getUrl());
OapiGettokenRequest req = new OapiGettokenRequest();
req.setAppkey(CLIENT_ID);
req.setAppsecret(CLIENT_SECRET);
req.setHttpMethod("GET");
OapiGettokenResponse rsp = client.execute(req);
return rsp.getAccessToken();
}
}