diff --git a/mes-module-infra/mes-module-infra-biz/pom.xml b/mes-module-infra/mes-module-infra-biz/pom.xml
index fd649e55..9a133070 100644
--- a/mes-module-infra/mes-module-infra-biz/pom.xml
+++ b/mes-module-infra/mes-module-infra-biz/pom.xml
@@ -114,6 +114,12 @@
mes-spring-boot-starter-file
+
+ com.chanjet
+ chanjet-openapi-java-sdk
+ 1.0.15-RELEASE
+
+
diff --git a/mes-module-majoys/mes-module-majoys-biz/src/main/java/com/chanko/yunxi/mes/module/majoys/config/ChanjetClientConfig.java b/mes-module-majoys/mes-module-majoys-biz/src/main/java/com/chanko/yunxi/mes/module/majoys/config/ChanjetClientConfig.java
new file mode 100644
index 00000000..6c017eb3
--- /dev/null
+++ b/mes-module-majoys/mes-module-majoys-biz/src/main/java/com/chanko/yunxi/mes/module/majoys/config/ChanjetClientConfig.java
@@ -0,0 +1,19 @@
+package com.chanko.yunxi.mes.module.majoys.config;
+
+import com.chanjet.openapi.sdk.java.ChanjetClient;
+import com.chanjet.openapi.sdk.java.DefaultChanjetClient;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * 初始化畅捷通SDK client
+ * @author chenxi
+ * @date 2024-04-16 02:28
+ */
+@Configuration
+public class ChanjetClientConfig {
+ @Bean
+ public ChanjetClient chanjetClient(OpenApiConfig openApiConfig) {
+ return new DefaultChanjetClient(openApiConfig.getGatewayUrl(), openApiConfig.getSecret());
+ }
+}
diff --git a/mes-module-majoys/mes-module-majoys-biz/src/main/java/com/chanko/yunxi/mes/module/majoys/config/OpenApiConfig.java b/mes-module-majoys/mes-module-majoys-biz/src/main/java/com/chanko/yunxi/mes/module/majoys/config/OpenApiConfig.java
new file mode 100644
index 00000000..2e5b5d9b
--- /dev/null
+++ b/mes-module-majoys/mes-module-majoys-biz/src/main/java/com/chanko/yunxi/mes/module/majoys/config/OpenApiConfig.java
@@ -0,0 +1,44 @@
+package com.chanko.yunxi.mes.module.majoys.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * 畅捷通开放平台的配置
+ * @author chenxi
+ * @date 2024-04-16 02:28
+ */
+@Data
+@Configuration
+@ConfigurationProperties("chanjet.openapi")
+public class OpenApiConfig {
+ /**
+ * 开放平台网关地址
+ */
+ private String gatewayUrl;
+ /**
+ * 开放平台申请的appKey
+ */
+ private String appKey;
+ /**
+ * 开放平台申请的appSecret
+ */
+ private String appSecret;
+ /**
+ * 连接超时时间,单位ms
+ */
+ private int connectTimeout;
+ /**
+ * 读取超时时间,单位ms
+ */
+ private int readTimeout;
+ /**
+ * 加签key,用于加签和解密
+ */
+ private String secret;
+ /**
+ * Oauth重定向地址
+ */
+ private String redirectUri;
+}
diff --git a/mes-module-majoys/mes-module-majoys-biz/src/main/java/com/chanko/yunxi/mes/module/majoys/controller/admin/chanjet/ChanjetController.java b/mes-module-majoys/mes-module-majoys-biz/src/main/java/com/chanko/yunxi/mes/module/majoys/controller/admin/chanjet/ChanjetController.java
new file mode 100644
index 00000000..e470cc7c
--- /dev/null
+++ b/mes-module-majoys/mes-module-majoys-biz/src/main/java/com/chanko/yunxi/mes/module/majoys/controller/admin/chanjet/ChanjetController.java
@@ -0,0 +1,52 @@
+package com.chanko.yunxi.mes.module.majoys.controller.admin.chanjet;
+
+import com.chanjet.openapi.sdk.java.exception.ChanjetApiException;
+import com.chanjet.openapi.sdk.java.response.GetTokenResponse;
+import com.chanko.yunxi.mes.framework.tenant.core.aop.TenantIgnore;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+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;
+
+import javax.annotation.security.PermitAll;
+
+/**
+ * 畅捷通控制器
+ *
+ * @author chenxi
+ * @date 2024-04-15 15:31
+ */
+@Tag(name = "管理后台 - 畅捷通")
+@RestController
+@PermitAll
+@RequestMapping("/mes/chanjet")
+@Validated
+@Slf4j
+public class ChanjetController {
+
+ @Autowired
+ private ChanjetSpi chanjetSpi;
+
+ /**
+ * OAuth回调地址接口
+ *
+ * @param code 开放平台的授权码
+ * @return
+ * @throws ChanjetApiException
+ */
+ @PermitAll
+ @TenantIgnore
+ @GetMapping("receiveCode")
+ public GetTokenResponse receiveCode(@RequestParam("code") String code) throws ChanjetApiException {
+ log.debug("接收授权码推送:{}", code);
+ GetTokenResponse response = chanjetSpi.getToken(code);
+ // 如成功 保存token
+ ChanjetTokenHolder.setToken(response);
+ return response;
+ }
+
+}
diff --git a/mes-module-majoys/mes-module-majoys-biz/src/main/java/com/chanko/yunxi/mes/module/majoys/controller/admin/chanjet/ChanjetSpi.java b/mes-module-majoys/mes-module-majoys-biz/src/main/java/com/chanko/yunxi/mes/module/majoys/controller/admin/chanjet/ChanjetSpi.java
new file mode 100644
index 00000000..bf92ad56
--- /dev/null
+++ b/mes-module-majoys/mes-module-majoys-biz/src/main/java/com/chanko/yunxi/mes/module/majoys/controller/admin/chanjet/ChanjetSpi.java
@@ -0,0 +1,133 @@
+package com.chanko.yunxi.mes.module.majoys.controller.admin.chanjet;
+
+import com.chanjet.openapi.sdk.java.ChanjetClient;
+import com.chanjet.openapi.sdk.java.domain.GetAppAccessTokenContent;
+import com.chanjet.openapi.sdk.java.domain.GetOrgAccessTokenContent;
+import com.chanjet.openapi.sdk.java.domain.GetPermanentAuthCodeContent;
+import com.chanjet.openapi.sdk.java.domain.GetTokenByPermanentCodeContent;
+import com.chanjet.openapi.sdk.java.exception.ChanjetApiException;
+import com.chanjet.openapi.sdk.java.request.*;
+import com.chanjet.openapi.sdk.java.response.*;
+import com.chanko.yunxi.mes.module.majoys.config.OpenApiConfig;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+/**
+ * 封装畅捷通SDK的spi
+ *
+ * @author: zsc
+ * @create: 2020/11/6 2:41 下午
+ **/
+@Component
+public class ChanjetSpi {
+
+ public static final String TOKEN = "";
+
+ @Autowired
+ private OpenApiConfig openApiConfig;
+ @Autowired
+ private ChanjetClient chanjetClient;
+
+ /**
+ * 获取应用凭证
+ *
+ * @param getAppAccessTokenContent
+ * @return
+ * @throws ChanjetApiException
+ */
+ public GetAppAccessTokenResponse getAppAccessToken(GetAppAccessTokenContent getAppAccessTokenContent) throws ChanjetApiException {
+ GetAppAccessTokenRequest getAppAccessTokenRequest = new GetAppAccessTokenRequest();
+ getAppAccessTokenRequest.setAppKey(openApiConfig.getAppKey());
+ getAppAccessTokenRequest.setAppSecret(openApiConfig.getAppSecret());
+ getAppAccessTokenRequest.setRequestUri("/auth/appAuth/getAppAccessToken");
+ getAppAccessTokenRequest.setBizContent(getAppAccessTokenContent);
+ return chanjetClient.execute(getAppAccessTokenRequest);
+ }
+
+ /**
+ * 获取企业永久授权码
+ *
+ * @param getPermanentAuthCodeContent
+ * @return
+ * @throws ChanjetApiException
+ */
+ public GetPermanentAuthCodeResponse getPermanentAuthCode(GetPermanentAuthCodeContent getPermanentAuthCodeContent) throws ChanjetApiException {
+ GetPermanentAuthCodeRequest getPermanentAuthCodeRequest = new GetPermanentAuthCodeRequest();
+ getPermanentAuthCodeRequest.setAppKey(openApiConfig.getAppKey());
+ getPermanentAuthCodeRequest.setAppSecret(openApiConfig.getAppSecret());
+ getPermanentAuthCodeRequest.setRequestUri("/auth/orgAuth/getPermanentAuthCode");
+ getPermanentAuthCodeRequest.setBizContent(getPermanentAuthCodeContent);
+ return chanjetClient.execute(getPermanentAuthCodeRequest);
+ }
+
+ /**
+ * 获取应用凭证
+ *
+ * @param getOrgAccessTokenContent
+ * @return
+ * @throws ChanjetApiException
+ */
+ public GetOrgAccessTokenResponse getOrgAccessToken(GetOrgAccessTokenContent getOrgAccessTokenContent) throws ChanjetApiException {
+ GetOrgAccessTokenRequest getOrgAccessTokenRequest = new GetOrgAccessTokenRequest();
+ getOrgAccessTokenRequest.setAppKey(openApiConfig.getAppKey());
+ getOrgAccessTokenRequest.setAppSecret(openApiConfig.getAppSecret());
+ getOrgAccessTokenRequest.setRequestUri("/auth/orgAuth/getOrgAccessToken");
+ getOrgAccessTokenRequest.setBizContent(getOrgAccessTokenContent);
+ return chanjetClient.execute(getOrgAccessTokenRequest);
+ }
+
+ /**
+ * 使用code换取openToken
+ *
+ * @param code
+ * @return
+ * @throws ChanjetApiException
+ */
+ public GetTokenResponse getToken(String code) throws ChanjetApiException {
+ GetTokenRequest getTokenRequest = new GetTokenRequest();
+ getTokenRequest.addQueryParam("appKey", openApiConfig.getAppKey());
+ getTokenRequest.addQueryParam("grantType", "authorization_code");
+ //填写开发者的真实OAuth回调地址
+ getTokenRequest.addQueryParam("redirectUri", openApiConfig.getRedirectUri());
+ getTokenRequest.addQueryParam("code", code);
+ getTokenRequest.setRequestUri("/auth/getToken");
+
+ return chanjetClient.execute(getTokenRequest);
+ }
+
+ /**
+ * 使用refreshToken刷新openToken
+ *
+ * @param refreshToken
+ * @return
+ * @throws ChanjetApiException
+ */
+ public RefreshTokenResponse refreshToken(String refreshToken) throws ChanjetApiException {
+ RefreshTokenRequest getTokenRequest = new RefreshTokenRequest();
+ getTokenRequest.addQueryParam("appKey", openApiConfig.getAppKey());
+ getTokenRequest.addQueryParam("appSecret", openApiConfig.getAppSecret());
+ getTokenRequest.addQueryParam("grantType", "refresh_token");
+ //填写开发者的真实OAuth回调地址
+ getTokenRequest.addQueryParam("refreshToken", refreshToken);
+ getTokenRequest.setRequestUri("/auth/v2/refreshToken");
+
+ return chanjetClient.execute(getTokenRequest);
+ }
+
+ /**
+ * 使用用户永久授权码获取openToken
+ *
+ * @param getTokenByPermanentCodeContent
+ * @return
+ * @throws ChanjetApiException
+ */
+ public GetTokenByPermanentCodeResponse getTokenByPermanentCode(GetTokenByPermanentCodeContent getTokenByPermanentCodeContent) throws ChanjetApiException {
+ GetTokenByPermanentCodeRequest getTokenByPermanentCodeRequest = new GetTokenByPermanentCodeRequest();
+ getTokenByPermanentCodeRequest.setAppKey(openApiConfig.getAppKey());
+ getTokenByPermanentCodeRequest.setAppSecret(openApiConfig.getAppSecret());
+ getTokenByPermanentCodeRequest.setRequestUri("/auth/token/getTokenByPermanentCode");
+ getTokenByPermanentCodeRequest.setBizContent(getTokenByPermanentCodeContent);
+ return chanjetClient.execute(getTokenByPermanentCodeRequest);
+ }
+
+}
diff --git a/mes-module-majoys/mes-module-majoys-biz/src/main/java/com/chanko/yunxi/mes/module/majoys/controller/admin/chanjet/ChanjetTokenHolder.java b/mes-module-majoys/mes-module-majoys-biz/src/main/java/com/chanko/yunxi/mes/module/majoys/controller/admin/chanjet/ChanjetTokenHolder.java
new file mode 100644
index 00000000..64c0bb4a
--- /dev/null
+++ b/mes-module-majoys/mes-module-majoys-biz/src/main/java/com/chanko/yunxi/mes/module/majoys/controller/admin/chanjet/ChanjetTokenHolder.java
@@ -0,0 +1,63 @@
+package com.chanko.yunxi.mes.module.majoys.controller.admin.chanjet;
+
+import com.alibaba.fastjson.JSON;
+import com.chanjet.openapi.sdk.java.exception.ChanjetApiException;
+import com.chanjet.openapi.sdk.java.response.GetTokenResponse;
+import com.chanjet.openapi.sdk.java.response.RefreshTokenResponse;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+
+/**
+ * 畅捷通 token 包装器
+ * 暂不考虑过期时间问题
+ * @author chenxi
+ * @date 2024-04-16 02:50
+ */
+@Slf4j
+@Component
+public class ChanjetTokenHolder {
+
+ public static String TOKEN = null;
+ public static String REFRESH_TOKEN = null;
+
+ @Resource
+ private ChanjetSpi chanjetSpi;
+
+ public static void setToken(GetTokenResponse response) {
+ log.debug("ChanjetTokenHolder.setToken: {}", JSON.toJSONString(response));
+ if("200".equals(response.getCode())){
+ TOKEN = response.getResult().getAccessToken();
+ REFRESH_TOKEN = response.getResult().getRefreshToken();
+ }else{
+ log.error("ChanjetTokenHolder.setToken error: {}", JSON.toJSONString(response));
+ }
+ }
+
+ /**
+ * 每天刷新一次token
+ * @author chenxi
+ * @date 2024-04-16 03:01
+ */
+ @Scheduled(cron = "0 0 0 * * ?")
+ public void refreshToken() throws ChanjetApiException {
+ if(!StringUtils.isEmpty(REFRESH_TOKEN)){
+ RefreshTokenResponse refreshTokenResponse = chanjetSpi.refreshToken(REFRESH_TOKEN);
+ setToken(refreshTokenResponse);
+ }
+ }
+
+ private void setToken(RefreshTokenResponse response) {
+ log.debug("ChanjetTokenHolder.refreshToken: {}", JSON.toJSONString(response));
+ if("200".equals(response.getCode())){
+ TOKEN = response.getResult().getAccessToken();
+ REFRESH_TOKEN = response.getResult().getRefreshToken();
+ }else{
+ log.error("ChanjetTokenHolder.refreshToken error: {}", JSON.toJSONString(response));
+ }
+ }
+
+}
diff --git a/mes-server/src/main/resources/application-local.yaml b/mes-server/src/main/resources/application-local.yaml
index 92223677..d817b677 100644
--- a/mes-server/src/main/resources/application-local.yaml
+++ b/mes-server/src/main/resources/application-local.yaml
@@ -215,3 +215,14 @@ wx:
host: 127.0.0.1
port: 6379
password:
+
+chanjet:
+ openapi:
+ gatewayUrl: https://openapi.chanjet.com #开放平台网关地址
+ connectTimeout: 3000 #连接超时时间,单位ms
+ readTimeout: 15000 #读取超时时间,单位ms
+ appKey: fZtARspH #需要填写在开放平台申请的appKey
+ appSecret: B071433DABBE48DB2241AE12280C8CBC #需要填写在开放平台申请的appSecret
+ secret: 1234567890123456 #秘钥,用于解密,需要去开放平台自主填写,然后配置在此处
+ redirectUri: http://192.168.0.158:9021/admin-api/mes/chanjet/receiveCode #Oauth重定向地址,需要去开放平台自主填写,然后配置在此处
+ code: c-6ff9b5e5e1014a788abb31f9d87bb42d
diff --git a/mes-server/src/main/resources/application.yaml b/mes-server/src/main/resources/application.yaml
index fa489ac9..0052818e 100644
--- a/mes-server/src/main/resources/application.yaml
+++ b/mes-server/src/main/resources/application.yaml
@@ -190,6 +190,7 @@ mes:
- /jmreport/* # 积木报表,无法携带租户编号
- /ureport/* # UReport 报表,无法携带租户编号
- /admin-api/mp/open/** # 微信公众号开放平台,微信回调接口,无法携带租户编号
+ - /admin-api/mes/chanjet/** # 畅捷通开放平台 无需租户
ignore-tables:
- system_tenant
- system_tenant_package