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