diff --git a/jeecg-boot-module/jeecg-module-im/pom.xml b/jeecg-boot-module/jeecg-module-im/pom.xml
new file mode 100644
index 0000000..e7e8a36
--- /dev/null
+++ b/jeecg-boot-module/jeecg-module-im/pom.xml
@@ -0,0 +1,21 @@
+
+
+
+ jeecg-boot-module
+ org.jeecgframework.boot
+ ${jeecgProjectVersion}
+
+ 4.0.0
+
+ jeecg-module-im
+
+
+
+ org.jeecgframework.boot
+ jeecg-boot-base-core
+
+
+
+
diff --git a/jeecg-boot-module/jeecg-module-im/src/main/java/org/jeecg/modules/ksim/client/KsimApiClient.java b/jeecg-boot-module/jeecg-module-im/src/main/java/org/jeecg/modules/ksim/client/KsimApiClient.java
new file mode 100644
index 0000000..dd1c08c
--- /dev/null
+++ b/jeecg-boot-module/jeecg-module-im/src/main/java/org/jeecg/modules/ksim/client/KsimApiClient.java
@@ -0,0 +1,74 @@
+package org.jeecg.modules.ksim.client;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.util.RestUtil;
+import org.jeecg.modules.ksim.config.KsimProperties;
+import org.jeecg.modules.ksim.dto.KsimApiResult;
+import org.jeecg.modules.ksim.dto.KsimMsgSendDTO;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+
+@Slf4j
+@Component
+public class KsimApiClient {
+
+ @Resource
+ private KsimProperties ksimProperties;
+
+ private HttpHeaders jsonHeaders() {
+ return RestUtil.getHeaderApplicationJson();
+ }
+
+ public JSONObject createToken(String appId, String appSecret, int timeoutSeconds) {
+ JSONObject body = new JSONObject();
+ body.put("appId", appId);
+ body.put("appSecret", appSecret);
+ body.put("tokenTimeoutSeconds", timeoutSeconds);
+
+ String url = ksimProperties.getHost() + "/api-open/v1/token/create";
+ ResponseEntity resp = RestUtil.request(url, HttpMethod.POST, jsonHeaders(), null, body, JSONObject.class);
+
+ log.info("【即时通推送-Token创建】请求完成, appId: {}, 获取Token: {}",
+ appId, resp.getBody() != null && resp.getBody().getJSONObject("dataBody") != null ? "成功" : "失败");
+ return resp.getBody();
+ }
+
+ public JSONObject refreshToken(String oldToken, int timeoutSeconds) {
+ JSONObject body = new JSONObject();
+ body.put("tokenTimeoutSeconds", timeoutSeconds);
+
+ HttpHeaders headers = jsonHeaders();
+ headers.add("imOpenApiToken", oldToken);
+
+ String url = ksimProperties.getHost() + "/api-open/v1/token/refresh";
+ ResponseEntity resp = RestUtil.request(url, HttpMethod.POST, headers, null, body, JSONObject.class);
+
+ log.info("【即时通推送-Token刷新】请求完成, 获取Token: {}",
+ resp.getBody() != null && resp.getBody().getJSONObject("dataBody") != null ? "成功" : "失败");
+ return resp.getBody();
+ }
+
+ public KsimApiResult sendMsg(String token, KsimMsgSendDTO dto) {
+ HttpHeaders headers = jsonHeaders();
+ headers.add("imOpenApiToken", token);
+
+ String bodyJson = JSON.toJSONString(dto);
+ String url = ksimProperties.getHost() + "/api-open/v1/msg/send";
+
+ ResponseEntity resp = RestUtil.request(url, HttpMethod.POST, headers, null,
+ JSON.parseObject(bodyJson), JSONObject.class);
+
+ JSONObject respBody = resp.getBody();
+ int code = respBody != null ? respBody.getIntValue("code") : -1;
+ log.info("【即时通推送-消息发送】请求完成, toUser: {}, title: {}, code: {}",
+ dto.getToUserValue(), dto.getTitle(), code);
+
+ return respBody != null ? respBody.toJavaObject(KsimApiResult.class) : null;
+ }
+}
diff --git a/jeecg-boot-module/jeecg-module-im/src/main/java/org/jeecg/modules/ksim/config/KsimProperties.java b/jeecg-boot-module/jeecg-module-im/src/main/java/org/jeecg/modules/ksim/config/KsimProperties.java
new file mode 100644
index 0000000..a133410
--- /dev/null
+++ b/jeecg-boot-module/jeecg-module-im/src/main/java/org/jeecg/modules/ksim/config/KsimProperties.java
@@ -0,0 +1,30 @@
+package org.jeecg.modules.ksim.config;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+@Component
+@ConfigurationProperties(prefix = "ksim")
+public class KsimProperties {
+
+ /** 即时通服务地址,如 http://10.2.0.54:19010 */
+ private String host = "http://10.2.0.54:19010";
+
+ /** 应用ID,在 application-{env}.yml 中配置 */
+ private String appId;
+
+ /** 应用密钥,在 application-{env}.yml 中配置 */
+ private String appSecret;
+
+ /** Token 有效期(秒),默认 7200(2小时) */
+ private int tokenTimeoutSeconds = 7200;
+
+ public String getHost() { return host; }
+ public void setHost(String host) { this.host = host; }
+ public String getAppId() { return appId; }
+ public void setAppId(String appId) { this.appId = appId; }
+ public String getAppSecret() { return appSecret; }
+ public void setAppSecret(String appSecret) { this.appSecret = appSecret; }
+ public int getTokenTimeoutSeconds() { return tokenTimeoutSeconds; }
+ public void setTokenTimeoutSeconds(int tokenTimeoutSeconds) { this.tokenTimeoutSeconds = tokenTimeoutSeconds; }
+}
diff --git a/jeecg-boot-module/jeecg-module-im/src/main/java/org/jeecg/modules/ksim/config/KsimScheduleConfig.java b/jeecg-boot-module/jeecg-module-im/src/main/java/org/jeecg/modules/ksim/config/KsimScheduleConfig.java
new file mode 100644
index 0000000..9cb70e4
--- /dev/null
+++ b/jeecg-boot-module/jeecg-module-im/src/main/java/org/jeecg/modules/ksim/config/KsimScheduleConfig.java
@@ -0,0 +1,9 @@
+package org.jeecg.modules.ksim.config;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+@Configuration
+@EnableScheduling
+public class KsimScheduleConfig {
+}
diff --git a/jeecg-boot-module/jeecg-module-im/src/main/java/org/jeecg/modules/ksim/controller/KsimTestController.java b/jeecg-boot-module/jeecg-module-im/src/main/java/org/jeecg/modules/ksim/controller/KsimTestController.java
new file mode 100644
index 0000000..4964f79
--- /dev/null
+++ b/jeecg-boot-module/jeecg-module-im/src/main/java/org/jeecg/modules/ksim/controller/KsimTestController.java
@@ -0,0 +1,127 @@
+package org.jeecg.modules.ksim.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.util.RestUtil;
+import org.jeecg.modules.ksim.dto.KsimMsgSendDTO;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.ResponseEntity;
+import org.springframework.context.annotation.Profile;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+@Slf4j
+@RestController
+@Profile("dev")
+@RequestMapping("/ksim/test")
+public class KsimTestController {
+
+ @PostMapping("/send")
+ public Result