From 2acfac4341cf7523d085b92453df57f464ac631f Mon Sep 17 00:00:00 2001 From: xiang Date: Thu, 17 Jul 2025 22:45:09 +0800 Subject: [PATCH] feat:first commit --- pom.xml | 169 ++++++++++++++++++ xservice-cache/pom.xml | 20 +++ .../java/com/xiang/xservice/basic/Main.java | 17 ++ xservice-common/pom.xml | 22 +++ .../basic/common/req/BaseRequest.java | 33 ++++ .../xservice/basic/common/req/IdRequest.java | 17 ++ .../xservice/basic/common/resp/Result.java | 51 ++++++ .../basic/config/MyThreadFactory.java | 23 +++ .../xservice/basic/enums/HttpMethodEnums.java | 16 ++ .../xiang/xservice/basic/utils/DateUtils.java | 4 + .../xiang/xservice/basic/utils/HttpUtils.java | 126 +++++++++++++ .../xiang/xservice/basic/utils/IpUtils.java | 21 +++ xservice-third-part/pom.xml | 42 +++++ .../dingTalk/enums/DingTalkUrlEnum.java | 26 +++ .../dingTalk/service/DingTalkService.java | 111 ++++++++++++ 15 files changed, 698 insertions(+) create mode 100644 pom.xml create mode 100644 xservice-cache/pom.xml create mode 100644 xservice-cache/src/main/java/com/xiang/xservice/basic/Main.java create mode 100644 xservice-common/pom.xml create mode 100644 xservice-common/src/main/java/com/xiang/xservice/basic/common/req/BaseRequest.java create mode 100644 xservice-common/src/main/java/com/xiang/xservice/basic/common/req/IdRequest.java create mode 100644 xservice-common/src/main/java/com/xiang/xservice/basic/common/resp/Result.java create mode 100644 xservice-common/src/main/java/com/xiang/xservice/basic/config/MyThreadFactory.java create mode 100644 xservice-common/src/main/java/com/xiang/xservice/basic/enums/HttpMethodEnums.java create mode 100644 xservice-common/src/main/java/com/xiang/xservice/basic/utils/DateUtils.java create mode 100644 xservice-common/src/main/java/com/xiang/xservice/basic/utils/HttpUtils.java create mode 100644 xservice-common/src/main/java/com/xiang/xservice/basic/utils/IpUtils.java create mode 100644 xservice-third-part/pom.xml create mode 100644 xservice-third-part/src/main/java/com/xiang/xservice/basic/xservice/dingTalk/enums/DingTalkUrlEnum.java create mode 100644 xservice-third-part/src/main/java/com/xiang/xservice/basic/xservice/dingTalk/service/DingTalkService.java diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..f2fecf3 --- /dev/null +++ b/pom.xml @@ -0,0 +1,169 @@ + + + 4.0.0 + + com.xiang + xservice-basic + 1.0-SNAPSHOT + pom + + xservice-common + xservice-cache + xservice-third-part + + + + 17 + 2.7.18 + 2021.0.8 + 2.2.2 + 5.1.4 + 8.0.33 + 1.18.30 + 2.0.51 + ${java.version} + ${java.version} + UTF-8 + 16.0.1 + 2.3.1 + 8.0.33 + 1.18.30 + 3.23.6 + 2.2.3 + + + + + + + org.springframework.boot + spring-boot-dependencies + ${spring.boot.version} + pom + import + + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + + mysql + mysql-connector-java + ${mysql.version} + + + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + ${mybatis-spring-boot.version} + + + + + org.springframework.boot + spring-boot-starter-data-redis + + + + + org.apache.rocketmq + rocketmq-spring-boot-starter + ${rocketmq.version} + + + + + org.projectlombok + lombok + ${lombok.version} + provided + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + + + org.apache.httpcomponents + httpclient + 4.5.13 + + + + + com.google.guava + guava + 32.0.1-android + + + org.apache.commons + commons-collections4 + 4.2 + + + org.apache.commons + commons-lang3 + 3.15.0 + + + + + com.alibaba.fastjson2 + fastjson2 + 2.0.51 + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.11.0 + + ${java.version} + ${java.version} + ${encoding} + true + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + + releases + http://192.168.2.10:33010/repository/maven-releases/ + + + snapshot + http://192.168.2.10:33010/repository/maven-snapshots/ + + + \ No newline at end of file diff --git a/xservice-cache/pom.xml b/xservice-cache/pom.xml new file mode 100644 index 0000000..3507ef3 --- /dev/null +++ b/xservice-cache/pom.xml @@ -0,0 +1,20 @@ + + + 4.0.0 + + com.xiang + xservice-basic + 1.0-SNAPSHOT + + + xservice-cache + + + 17 + 17 + UTF-8 + + + \ No newline at end of file diff --git a/xservice-cache/src/main/java/com/xiang/xservice/basic/Main.java b/xservice-cache/src/main/java/com/xiang/xservice/basic/Main.java new file mode 100644 index 0000000..983d37d --- /dev/null +++ b/xservice-cache/src/main/java/com/xiang/xservice/basic/Main.java @@ -0,0 +1,17 @@ +package com.xiang.xservice.basic; + +//TIP To Run code, press or +// click the icon in the gutter. +public class Main { + public static void main(String[] args) { + //TIP Press 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 to start debugging your code. We have set one breakpoint + // for you, but you can always add more by pressing . + System.out.println("i = " + i); + } + } +} \ No newline at end of file diff --git a/xservice-common/pom.xml b/xservice-common/pom.xml new file mode 100644 index 0000000..10f07ac --- /dev/null +++ b/xservice-common/pom.xml @@ -0,0 +1,22 @@ + + + 4.0.0 + + com.xiang + xservice-basic + 1.0-SNAPSHOT + + + xservice-common + + + 17 + 17 + UTF-8 + + + + + \ No newline at end of file diff --git a/xservice-common/src/main/java/com/xiang/xservice/basic/common/req/BaseRequest.java b/xservice-common/src/main/java/com/xiang/xservice/basic/common/req/BaseRequest.java new file mode 100644 index 0000000..43627cc --- /dev/null +++ b/xservice-common/src/main/java/com/xiang/xservice/basic/common/req/BaseRequest.java @@ -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; +} diff --git a/xservice-common/src/main/java/com/xiang/xservice/basic/common/req/IdRequest.java b/xservice-common/src/main/java/com/xiang/xservice/basic/common/req/IdRequest.java new file mode 100644 index 0000000..b7783ad --- /dev/null +++ b/xservice-common/src/main/java/com/xiang/xservice/basic/common/req/IdRequest.java @@ -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; + +} diff --git a/xservice-common/src/main/java/com/xiang/xservice/basic/common/resp/Result.java b/xservice-common/src/main/java/com/xiang/xservice/basic/common/resp/Result.java new file mode 100644 index 0000000..78d7708 --- /dev/null +++ b/xservice-common/src/main/java/com/xiang/xservice/basic/common/resp/Result.java @@ -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 { + + private String code; + + private String message; + + private List data; + + public static Result success(String message) { + return new Result("200", message, null); + } + + + public static Result success(String message, List data) { + return new Result("200", message, data); + } + public static Result success(String message, T data) { + return new Result("200", message, Collections.singletonList(data)); + } + + public static Result error(String message) { + return new Result("500", message, null); + } + + public static Result error(String message, T data) { + return new Result("500", message, Collections.singletonList(data)); + } + public static Result error(String message, List data) { + return new Result("500", message, data); + } + + public static Result error(String code, String message) { + return new Result(code, message, null); + } +} \ No newline at end of file diff --git a/xservice-common/src/main/java/com/xiang/xservice/basic/config/MyThreadFactory.java b/xservice-common/src/main/java/com/xiang/xservice/basic/config/MyThreadFactory.java new file mode 100644 index 0000000..fb2c925 --- /dev/null +++ b/xservice-common/src/main/java/com/xiang/xservice/basic/config/MyThreadFactory.java @@ -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; + } +} diff --git a/xservice-common/src/main/java/com/xiang/xservice/basic/enums/HttpMethodEnums.java b/xservice-common/src/main/java/com/xiang/xservice/basic/enums/HttpMethodEnums.java new file mode 100644 index 0000000..3847b3d --- /dev/null +++ b/xservice-common/src/main/java/com/xiang/xservice/basic/enums/HttpMethodEnums.java @@ -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; + } +} diff --git a/xservice-common/src/main/java/com/xiang/xservice/basic/utils/DateUtils.java b/xservice-common/src/main/java/com/xiang/xservice/basic/utils/DateUtils.java new file mode 100644 index 0000000..8c2180f --- /dev/null +++ b/xservice-common/src/main/java/com/xiang/xservice/basic/utils/DateUtils.java @@ -0,0 +1,4 @@ +package com.xiang.xservice.basic.utils; + +public class DateUtils { +} diff --git a/xservice-common/src/main/java/com/xiang/xservice/basic/utils/HttpUtils.java b/xservice-common/src/main/java/com/xiang/xservice/basic/utils/HttpUtils.java new file mode 100644 index 0000000..8f3d9c5 --- /dev/null +++ b/xservice-common/src/main/java/com/xiang/xservice/basic/utils/HttpUtils.java @@ -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 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 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> entries = header.entrySet(); + for (Map.Entry e : entries) { + httpPost.setHeader(e.getKey(), e.getValue()); + } + } + return httpPost; + } + + public static String doGet(String url, Map header, Map 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 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 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(); + } + } +} diff --git a/xservice-common/src/main/java/com/xiang/xservice/basic/utils/IpUtils.java b/xservice-common/src/main/java/com/xiang/xservice/basic/utils/IpUtils.java new file mode 100644 index 0000000..f3648a2 --- /dev/null +++ b/xservice-common/src/main/java/com/xiang/xservice/basic/utils/IpUtils.java @@ -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 header = Maps.newHashMap(); + header.put("User-Agent", "Mozilla/5.0"); + return HttpUtils.doGet(PUBLIC_IP_URL, header, null).trim(); + } +} diff --git a/xservice-third-part/pom.xml b/xservice-third-part/pom.xml new file mode 100644 index 0000000..a2acabf --- /dev/null +++ b/xservice-third-part/pom.xml @@ -0,0 +1,42 @@ + + + 4.0.0 + + com.xiang + xservice-basic + 1.0-SNAPSHOT + + + xservice-third-part + + + 17 + 17 + UTF-8 + + + + + com.xiang + xservice-common + 1.0-SNAPSHOT + + + + + com.aliyun + alibaba-dingtalk-service-sdk + 2.0.0 + + + + + com.aliyun + alidns20150109 + 3.4.7 + + + + \ No newline at end of file diff --git a/xservice-third-part/src/main/java/com/xiang/xservice/basic/xservice/dingTalk/enums/DingTalkUrlEnum.java b/xservice-third-part/src/main/java/com/xiang/xservice/basic/xservice/dingTalk/enums/DingTalkUrlEnum.java new file mode 100644 index 0000000..0ef6fbd --- /dev/null +++ b/xservice-third-part/src/main/java/com/xiang/xservice/basic/xservice/dingTalk/enums/DingTalkUrlEnum.java @@ -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; + } +} diff --git a/xservice-third-part/src/main/java/com/xiang/xservice/basic/xservice/dingTalk/service/DingTalkService.java b/xservice-third-part/src/main/java/com/xiang/xservice/basic/xservice/dingTalk/service/DingTalkService.java new file mode 100644 index 0000000..2cc10cb --- /dev/null +++ b/xservice-third-part/src/main/java/com/xiang/xservice/basic/xservice/dingTalk/service/DingTalkService.java @@ -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(); + } + +}