浙政钉
This commit is contained in:
1 parent
1666184356
commit
a0be0ebc0c
8 files changed
+255
-74
No files matched your search
@@ -155,6 +155,19 @@
|
||||
<version>5.7.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<!-- 政务钉钉开放平台 SDK(本地 jar:src/lib/zwdd-sdk-java-1.2.0.jar) -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.xxpt</groupId>
|
||||
<artifactId>zwdd-sdk-java</artifactId>
|
||||
<version>1.2.0</version>
|
||||
<scope>system</scope>
|
||||
<systemPath>${project.basedir}/src/lib/zwdd-sdk-java-1.2.0.jar</systemPath>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>joda-time</groupId>
|
||||
<artifactId>joda-time</artifactId>
|
||||
<version>2.10</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<profiles>
|
||||
<profile>
|
||||
@@ -190,6 +203,7 @@
|
||||
</goals>
|
||||
<configuration>
|
||||
<loaderImplementation>CLASSIC</loaderImplementation>
|
||||
<includeSystemScope>true</includeSystemScope>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
|
||||
Binary file not shown.
+41
@@ -0,0 +1,41 @@
|
||||
package com.bsd.pjcloud.thirdparty.config;
|
||||
|
||||
import com.alibaba.xxpt.gateway.shared.client.http.ExecutableClient;
|
||||
import com.bsd.pjcloud.thirdparty.exception.ThirdPartyException;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 政务钉钉开放平台 {@link ExecutableClient} 单例初始化(与官方 SDK 文档一致,全局只 init 一次)。
|
||||
*/
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class ZzdOpenPlatformExecutableClientHolder {
|
||||
|
||||
private final ZzdOpenPlatformProperties zzdOpenPlatform;
|
||||
|
||||
private final Object initLock = new Object();
|
||||
|
||||
private volatile boolean initialized;
|
||||
|
||||
public ExecutableClient client() {
|
||||
if (!zzdOpenPlatform.isEnabled() || !zzdOpenPlatform.isAppCredentialConfigured()) {
|
||||
throw new ThirdPartyException("浙政钉开放平台未启用或未配置 appKey/appSecret", "ZZD_OPEN_SDK_CFG");
|
||||
}
|
||||
if (!initialized) {
|
||||
synchronized (initLock) {
|
||||
if (!initialized) {
|
||||
ExecutableClient c = ExecutableClient.getInstance();
|
||||
c.setDomainName(zzdOpenPlatform.getDomain());
|
||||
c.setProtocal(zzdOpenPlatform.getProtocol());
|
||||
c.setAccessKey(zzdOpenPlatform.getAppKey());
|
||||
c.setSecretKey(zzdOpenPlatform.getAppSecret());
|
||||
c.setValidateAfterInactivity(60_000);
|
||||
c.init();
|
||||
initialized = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ExecutableClient.getInstance();
|
||||
}
|
||||
}
|
||||
+5
@@ -32,6 +32,11 @@ public class ZzdOpenPlatformProperties {
|
||||
|
||||
private String appSecret = "";
|
||||
|
||||
/**
|
||||
* H5 微应用 JSAPI 鉴权用 AgentId(管理后台应用详情,非 appKey)
|
||||
*/
|
||||
private String jsapiAgentId = "";
|
||||
|
||||
public boolean isAppCredentialConfigured() {
|
||||
return StringUtils.hasText(appKey) && StringUtils.hasText(appSecret);
|
||||
}
|
||||
|
||||
+13
@@ -17,6 +17,8 @@ import com.bsd.pjcloud.common.log.annotation.SysLog;
|
||||
import com.bsd.pjcloud.common.security.annotation.Inner;
|
||||
import com.bsd.pjcloud.thirdparty.dto.*;
|
||||
import com.bsd.pjcloud.thirdparty.service.SmsService;
|
||||
import com.bsd.pjcloud.thirdparty.exception.ThirdPartyException;
|
||||
import com.bsd.pjcloud.thirdparty.vo.ZzdJsapiConfigVO;
|
||||
import com.bsd.pjcloud.thirdparty.service.ThirdPartyOAuth2Service;
|
||||
import com.bsd.pjcloud.thirdparty.service.ThirdPartyUserService;
|
||||
import com.bsd.pjcloud.thirdparty.utils.SmsCodeUtil;
|
||||
@@ -87,6 +89,17 @@ public class ThirdPartyOAth2Cotroller {
|
||||
* @param token 浙政钉前端获取的token
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/zzdJsapiConfig")
|
||||
@Operation(summary = "政务钉钉H5 JSAPI鉴权(dd.authConfig 所需 ticket)")
|
||||
@Inner(value = false)
|
||||
public R<ZzdJsapiConfigVO> zzdJsapiConfig() {
|
||||
try {
|
||||
return R.ok(thirdPartyOAuth2Service.buildZzdJsapiConfigForH5());
|
||||
} catch (ThirdPartyException e) {
|
||||
return R.failed(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping("/zzdsso")
|
||||
@Operation(summary = "浙政钉单点登录")
|
||||
@SysLog("浙政钉单点登录")
|
||||
|
||||
+163
-74
@@ -4,7 +4,19 @@ import com.alibaba.fastjson.JSON;
|
||||
import com.bsd.pjcloud.admin.api.entity.SysUser;
|
||||
import com.bsd.pjcloud.common.core.util.R;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.xxpt.gateway.shared.api.request.OapiGetJsapiTokenJsonRequest;
|
||||
import com.alibaba.xxpt.gateway.shared.api.request.OapiGettokenJsonRequest;
|
||||
import com.alibaba.xxpt.gateway.shared.api.request.OapiRpcOauth2DingtalkAppUserJsonRequest;
|
||||
import com.alibaba.xxpt.gateway.shared.api.response.OapiGetJsapiTokenJsonResponse;
|
||||
import com.alibaba.xxpt.gateway.shared.api.response.OapiGettokenJsonResponse;
|
||||
import com.alibaba.xxpt.gateway.shared.api.response.OapiRpcOauth2DingtalkAppUserJsonResponse;
|
||||
import com.alibaba.xxpt.gateway.shared.client.http.ExecutableClient;
|
||||
import com.alibaba.xxpt.gateway.shared.client.http.IntelligentGetClient;
|
||||
import com.alibaba.xxpt.gateway.shared.client.http.IntelligentPostClient;
|
||||
import com.alibaba.xxpt.gateway.shared.client.http.api.OapiResponse;
|
||||
import com.alibaba.xxpt.gateway.shared.client.http.api.OapiSpResultContent;
|
||||
import com.bsd.pjcloud.thirdparty.config.OAuth2ClientConfig;
|
||||
import com.bsd.pjcloud.thirdparty.config.ZzdOpenPlatformExecutableClientHolder;
|
||||
import com.bsd.pjcloud.thirdparty.config.ZzdOpenPlatformProperties;
|
||||
import com.bsd.pjcloud.thirdparty.constant.UserTypeEnum;
|
||||
import com.bsd.pjcloud.thirdparty.dto.*;
|
||||
@@ -12,6 +24,7 @@ import com.bsd.pjcloud.thirdparty.entity.ThirdPartyDeptEntity;
|
||||
import com.bsd.pjcloud.thirdparty.entity.ThirdPartyLogEntity;
|
||||
import com.bsd.pjcloud.thirdparty.entity.ThirdPartyUserEntity;
|
||||
import com.bsd.pjcloud.thirdparty.exception.ThirdPartyException;
|
||||
import com.bsd.pjcloud.thirdparty.vo.ZzdJsapiConfigVO;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
@@ -48,6 +61,12 @@ public class ThirdPartyOAuth2Service {
|
||||
private volatile String zzdOpenCachedAppAccessToken;
|
||||
private volatile long zzdOpenCachedAppAccessTokenExpireMs;
|
||||
|
||||
private final Object zzdJsapiTicketLock = new Object();
|
||||
|
||||
private volatile String zzdOpenCachedJsapiTicket;
|
||||
|
||||
private volatile long zzdOpenCachedJsapiTicketExpireMs;
|
||||
|
||||
@Autowired
|
||||
private OAuth2ClientConfig config;
|
||||
private final String baseUrl = "http://192.168.93.121:8880";
|
||||
@@ -65,6 +84,8 @@ public class ThirdPartyOAuth2Service {
|
||||
|
||||
private final ZzdOpenPlatformProperties zzdOpenPlatform;
|
||||
|
||||
private final ZzdOpenPlatformExecutableClientHolder zzdExecutableClientHolder;
|
||||
|
||||
|
||||
public TokenDTO getAccessToken() {
|
||||
TokenDTO cachedToken = tokenCache.get("access_token");
|
||||
@@ -390,12 +411,8 @@ public class ThirdPartyOAuth2Service {
|
||||
return getZZDUserInfo(authCode, UserTypeEnum.ZZD.getType(), true);
|
||||
}
|
||||
|
||||
private String zzdOpenBaseUrl() {
|
||||
return zzdOpenPlatform.getProtocol() + "://" + zzdOpenPlatform.getDomain();
|
||||
}
|
||||
|
||||
/**
|
||||
* 开放平台文档:POST /gettoken.json,表单 appkey、appsecret;返回 content.data.accessToken
|
||||
* 开放平台:官方 SDK {@code IntelligentGetClient /gettoken.json},解析 content.data 中 accessToken
|
||||
*/
|
||||
private String getZzdOpenAppAccessToken() {
|
||||
long now = System.currentTimeMillis();
|
||||
@@ -407,97 +424,111 @@ public class ThirdPartyOAuth2Service {
|
||||
if (zzdOpenCachedAppAccessToken != null && now < zzdOpenCachedAppAccessTokenExpireMs - 60_000L) {
|
||||
return zzdOpenCachedAppAccessToken;
|
||||
}
|
||||
String url = zzdOpenBaseUrl() + "/gettoken.json";
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
|
||||
MultiValueMap<String, String> body = new LinkedMultiValueMap<>();
|
||||
body.add("appkey", zzdOpenPlatform.getAppKey());
|
||||
body.add("appsecret", zzdOpenPlatform.getAppSecret());
|
||||
HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<>(body, headers);
|
||||
ResponseEntity<String> response;
|
||||
try {
|
||||
response = restTemplate.postForEntity(url, entity, String.class);
|
||||
} catch (HttpStatusCodeException e) {
|
||||
log.error("浙政钉 gettoken HTTP异常 状态:{} 响应:{}", e.getRawStatusCode(), e.getResponseBodyAsString());
|
||||
throw new ThirdPartyException("浙政钉获取应用 access_token 失败", "ZZD_OPEN_TOKEN_HTTP");
|
||||
} catch (ResourceAccessException e) {
|
||||
log.error("浙政钉 gettoken 网络异常", e);
|
||||
throw new ThirdPartyException("浙政钉开放平台暂不可用", "ZZD_OPEN_TOKEN_NET");
|
||||
}
|
||||
String respBody = response.getBody();
|
||||
JSONObject data = parseZzdOpenContentData(respBody, url);
|
||||
String accessToken = data.getString("accessToken");
|
||||
if (!StringUtils.hasText(accessToken)) {
|
||||
throw new ThirdPartyException("浙政钉 gettoken 未返回 accessToken", "ZZD_OPEN_TOKEN_BAD");
|
||||
}
|
||||
int expiresIn = 7100;
|
||||
try {
|
||||
Object ex = data.get("expiresIn");
|
||||
if (ex != null) {
|
||||
expiresIn = Integer.parseInt(ex.toString());
|
||||
ExecutableClient ec = zzdExecutableClientHolder.client();
|
||||
IntelligentGetClient getClient = ec.newIntelligentGetClient("/gettoken.json");
|
||||
OapiGettokenJsonRequest req = new OapiGettokenJsonRequest();
|
||||
req.setAppkey(zzdOpenPlatform.getAppKey());
|
||||
req.setAppsecret(zzdOpenPlatform.getAppSecret());
|
||||
OapiGettokenJsonResponse resp = getClient.get(req);
|
||||
zzdAssertSdkTopSuccess(resp, "gettoken");
|
||||
JSONObject data = zzdSdkSpResultData(resp.getContent(), "gettoken");
|
||||
String accessToken = data.getString("accessToken");
|
||||
if (!StringUtils.hasText(accessToken)) {
|
||||
throw new ThirdPartyException("浙政钉 gettoken 未返回 accessToken", "ZZD_OPEN_TOKEN_BAD");
|
||||
}
|
||||
} catch (NumberFormatException ignored) {
|
||||
int expiresIn = 7100;
|
||||
try {
|
||||
Object ex = data.get("expiresIn");
|
||||
if (ex != null) {
|
||||
expiresIn = Integer.parseInt(ex.toString());
|
||||
}
|
||||
} catch (NumberFormatException ignored) {
|
||||
}
|
||||
zzdOpenCachedAppAccessToken = accessToken;
|
||||
zzdOpenCachedAppAccessTokenExpireMs = System.currentTimeMillis() + expiresIn * 1000L;
|
||||
return accessToken;
|
||||
} catch (ThirdPartyException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
log.error("浙政钉 gettoken SDK 调用异常", e);
|
||||
throw new ThirdPartyException("浙政钉获取应用 access_token 失败", "ZZD_OPEN_TOKEN_SDK");
|
||||
}
|
||||
zzdOpenCachedAppAccessToken = accessToken;
|
||||
zzdOpenCachedAppAccessTokenExpireMs = System.currentTimeMillis() + expiresIn * 1000L;
|
||||
return accessToken;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* POST /rpc/oauth2/dingtalk_app_user.json,表单 access_token、auth_code
|
||||
* 官方 SDK {@code IntelligentPostClient /rpc/oauth2/dingtalk_app_user.json}
|
||||
*/
|
||||
private ZZDUserDTO getZzdUserByOpenPlatformAuthCode(String authCode) {
|
||||
String appToken = getZzdOpenAppAccessToken();
|
||||
String url = zzdOpenBaseUrl() + "/rpc/oauth2/dingtalk_app_user.json";
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
|
||||
MultiValueMap<String, String> body = new LinkedMultiValueMap<>();
|
||||
body.add("access_token", appToken);
|
||||
body.add("auth_code", authCode);
|
||||
HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<>(body, headers);
|
||||
ResponseEntity<String> response;
|
||||
try {
|
||||
response = restTemplate.postForEntity(url, entity, String.class);
|
||||
} catch (HttpStatusCodeException e) {
|
||||
log.error("浙政钉 dingtalk_app_user HTTP异常 状态:{} 响应:{}", e.getRawStatusCode(), e.getResponseBodyAsString());
|
||||
throw new ThirdPartyException("浙政钉获取用户失败", "ZZD_OPEN_USER_HTTP");
|
||||
} catch (ResourceAccessException e) {
|
||||
log.error("浙政钉 dingtalk_app_user 网络异常", e);
|
||||
throw new ThirdPartyException("浙政钉开放平台暂不可用", "ZZD_OPEN_USER_NET");
|
||||
String appToken = getZzdOpenAppAccessToken();
|
||||
ExecutableClient ec = zzdExecutableClientHolder.client();
|
||||
IntelligentPostClient postClient = ec.newIntelligentPostClient("/rpc/oauth2/dingtalk_app_user.json");
|
||||
OapiRpcOauth2DingtalkAppUserJsonRequest req = new OapiRpcOauth2DingtalkAppUserJsonRequest();
|
||||
req.setAccess_token(appToken);
|
||||
req.setAuth_code(authCode);
|
||||
OapiRpcOauth2DingtalkAppUserJsonResponse resp = postClient.post(req);
|
||||
zzdAssertSdkTopSuccess(resp, "dingtalk_app_user");
|
||||
JSONObject data = zzdSdkDingtalkAppUserContentData(resp.getContent());
|
||||
ZZDUserDTO dto = mapOpenPlatformUserToZzdDto(data);
|
||||
if (StringUtils.hasText(zzdOpenPlatform.getTenantId()) && dto.getExt() != null
|
||||
&& StringUtils.hasText(dto.getExt().getRealmId())
|
||||
&& !zzdOpenPlatform.getTenantId().equals(dto.getExt().getRealmId())) {
|
||||
log.warn("浙政钉用户 realmId={} 与配置 zzd.open.tenant-id={} 不一致", dto.getExt().getRealmId(), zzdOpenPlatform.getTenantId());
|
||||
}
|
||||
return dto;
|
||||
} catch (ThirdPartyException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
log.error("浙政钉 dingtalk_app_user SDK 调用异常", e);
|
||||
throw new ThirdPartyException("浙政钉获取用户失败", "ZZD_OPEN_USER_SDK");
|
||||
}
|
||||
JSONObject data = parseZzdOpenContentData(response.getBody(), url);
|
||||
ZZDUserDTO dto = mapOpenPlatformUserToZzdDto(data);
|
||||
if (StringUtils.hasText(zzdOpenPlatform.getTenantId()) && dto.getExt() != null
|
||||
&& StringUtils.hasText(dto.getExt().getRealmId())
|
||||
&& !zzdOpenPlatform.getTenantId().equals(dto.getExt().getRealmId())) {
|
||||
log.warn("浙政钉用户 realmId={} 与配置 zzd.open.tenant-id={} 不一致", dto.getExt().getRealmId(), zzdOpenPlatform.getTenantId());
|
||||
}
|
||||
return dto;
|
||||
}
|
||||
|
||||
private static JSONObject parseZzdOpenContentData(String body, String requestUrl) {
|
||||
if (!StringUtils.hasText(body)) {
|
||||
throw new ThirdPartyException("浙政钉接口空响应: " + requestUrl, "ZZD_OPEN_EMPTY");
|
||||
private static void zzdAssertSdkTopSuccess(OapiResponse resp, String apiLabel) {
|
||||
if (resp == null || !Boolean.TRUE.equals(resp.getSuccess())) {
|
||||
String msg = resp != null && StringUtils.hasText(resp.getMessage()) ? resp.getMessage() : "success!=true";
|
||||
throw new ThirdPartyException("浙政钉 " + apiLabel + " 网关失败: " + msg, "ZZD_OPEN_FAIL");
|
||||
}
|
||||
JSONObject root = JSON.parseObject(body);
|
||||
if (root == null || !root.getBooleanValue("success")) {
|
||||
throw new ThirdPartyException("浙政钉接口失败: " + body, "ZZD_OPEN_FAIL");
|
||||
}
|
||||
JSONObject content = root.getJSONObject("content");
|
||||
}
|
||||
|
||||
private static JSONObject zzdSdkSpResultData(OapiSpResultContent content, String apiLabel) {
|
||||
if (content == null) {
|
||||
throw new ThirdPartyException("浙政钉响应缺少 content: " + body, "ZZD_OPEN_BAD");
|
||||
throw new ThirdPartyException("浙政钉 " + apiLabel + " 响应无 content", "ZZD_OPEN_BAD");
|
||||
}
|
||||
if (!content.getBooleanValue("success")) {
|
||||
throw new ThirdPartyException("浙政钉 content 失败: " + body, "ZZD_OPEN_FAIL");
|
||||
if (content.getSuccess() != null && !content.getSuccess()) {
|
||||
throw new ThirdPartyException("浙政钉 " + apiLabel + " 业务失败: " + content.getResponseCode() + " " + content.getResponseMessage(), "ZZD_OPEN_FAIL");
|
||||
}
|
||||
JSONObject data = content.getJSONObject("data");
|
||||
String dataStr = content.getData();
|
||||
if (!StringUtils.hasText(dataStr)) {
|
||||
throw new ThirdPartyException("浙政钉 " + apiLabel + " 响应无 data", "ZZD_OPEN_BAD");
|
||||
}
|
||||
JSONObject data = JSON.parseObject(dataStr);
|
||||
if (data == null) {
|
||||
throw new ThirdPartyException("浙政钉响应缺少 data: " + body, "ZZD_OPEN_BAD");
|
||||
throw new ThirdPartyException("浙政钉 " + apiLabel + " data 非 JSON", "ZZD_OPEN_BAD");
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
private static JSONObject zzdSdkDingtalkAppUserContentData(String contentStr) {
|
||||
if (!StringUtils.hasText(contentStr)) {
|
||||
throw new ThirdPartyException("浙政钉 dingtalk_app_user 响应无 content body", "ZZD_OPEN_BAD");
|
||||
}
|
||||
JSONObject content = JSON.parseObject(contentStr);
|
||||
if (content == null) {
|
||||
throw new ThirdPartyException("浙政钉 dingtalk_app_user content 非 JSON", "ZZD_OPEN_BAD");
|
||||
}
|
||||
if (content.containsKey("success") && !content.getBooleanValue("success")) {
|
||||
throw new ThirdPartyException("浙政钉 dingtalk_app_user 业务失败: " + content.getString("responseCode") + " " + content.getString("responseMessage"), "ZZD_OPEN_FAIL");
|
||||
}
|
||||
JSONObject data = content.getJSONObject("data");
|
||||
if (data != null) {
|
||||
return data;
|
||||
}
|
||||
return content;
|
||||
}
|
||||
|
||||
private static ZZDUserDTO mapOpenPlatformUserToZzdDto(JSONObject data) {
|
||||
ZZDUserDTO dto = new ZZDUserDTO();
|
||||
String lastName = data.getString("lastName");
|
||||
@@ -728,6 +759,64 @@ public class ThirdPartyOAuth2Service {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 政务钉钉 H5 JSAPI 鉴权:前端 {@code dd.authConfig({ ticket, jsApiList })}。
|
||||
* 官方 SDK:{@code IntelligentGetClient /get_jsapi_token.json},请求体带应用 {@code accessToken},解析 {@code content.data.accessToken} 为 ticket。
|
||||
*/
|
||||
public ZzdJsapiConfigVO buildZzdJsapiConfigForH5() {
|
||||
if (!zzdOpenPlatform.isEnabled() || !zzdOpenPlatform.isAppCredentialConfigured()) {
|
||||
throw new ThirdPartyException("浙政钉开放平台未启用或未配置 appKey/appSecret", "ZZD_JSAPI_CFG");
|
||||
}
|
||||
String ticket = getZzdOpenJsapiTokenTicket();
|
||||
ZzdJsapiConfigVO vo = new ZzdJsapiConfigVO();
|
||||
vo.setTicket(ticket);
|
||||
vo.setJsApiList(Arrays.asList("getAuthCode", "runtime.permission.requestAuthCode"));
|
||||
return vo;
|
||||
}
|
||||
|
||||
private String getZzdOpenJsapiTokenTicket() {
|
||||
long now = System.currentTimeMillis();
|
||||
if (StringUtils.hasText(zzdOpenCachedJsapiTicket) && now < zzdOpenCachedJsapiTicketExpireMs - 120_000L) {
|
||||
return zzdOpenCachedJsapiTicket;
|
||||
}
|
||||
synchronized (zzdJsapiTicketLock) {
|
||||
now = System.currentTimeMillis();
|
||||
if (StringUtils.hasText(zzdOpenCachedJsapiTicket) && now < zzdOpenCachedJsapiTicketExpireMs - 120_000L) {
|
||||
return zzdOpenCachedJsapiTicket;
|
||||
}
|
||||
String appToken = getZzdOpenAppAccessToken();
|
||||
try {
|
||||
ExecutableClient ec = zzdExecutableClientHolder.client();
|
||||
IntelligentGetClient getClient = ec.newIntelligentGetClient("/get_jsapi_token.json");
|
||||
OapiGetJsapiTokenJsonRequest req = new OapiGetJsapiTokenJsonRequest();
|
||||
req.setAccessToken(appToken);
|
||||
OapiGetJsapiTokenJsonResponse resp = getClient.get(req);
|
||||
zzdAssertSdkTopSuccess(resp, "get_jsapi_token");
|
||||
JSONObject data = zzdSdkSpResultData(resp.getContent(), "get_jsapi_token");
|
||||
String ticket = data.getString("accessToken");
|
||||
if (!StringUtils.hasText(ticket)) {
|
||||
throw new ThirdPartyException("浙政钉 get_jsapi_token 响应无 data.accessToken", "ZZD_JSAPI_TK_BAD");
|
||||
}
|
||||
int ttl = 7100;
|
||||
try {
|
||||
Object ex = data.get("expiresIn");
|
||||
if (ex != null) {
|
||||
ttl = Integer.parseInt(ex.toString());
|
||||
}
|
||||
} catch (NumberFormatException ignored) {
|
||||
}
|
||||
zzdOpenCachedJsapiTicket = ticket;
|
||||
zzdOpenCachedJsapiTicketExpireMs = System.currentTimeMillis() + ttl * 1000L;
|
||||
return ticket;
|
||||
} catch (ThirdPartyException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
log.error("浙政钉 get_jsapi_token SDK 调用异常", e);
|
||||
throw new ThirdPartyException("浙政钉获取 JSAPI ticket 失败", "ZZD_JSAPI_TK_SDK");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 诗画
|
||||
* @param accountId
|
||||
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package com.bsd.pjcloud.thirdparty.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 政务钉钉 / 专有钉钉 H5:{@code dd.authConfig} 参数。
|
||||
* ticket 来自开放平台 {@code POST /get_jsapi_token.json} 返回的 {@code content.data.accessToken}(文档称鉴权 ticket)。
|
||||
*/
|
||||
@Data
|
||||
public class ZzdJsapiConfigVO {
|
||||
|
||||
private String ticket;
|
||||
|
||||
private List<String> jsApiList;
|
||||
}
|
||||
@@ -52,6 +52,8 @@ zzd:
|
||||
tenant-id: "196729"
|
||||
app-key: ${ZZD_OPEN_APP_KEY:pjx_zhhqyth-wt2VrVa0olcqEBBJJb}
|
||||
app-secret: ${ZZD_OPEN_APP_SECRET:rT5zbpHO0L7raRHJtvlIs26N8hn53JDv1K1SNa7X}
|
||||
# H5 使用 dd.authConfig 时仅需 ak/sk;jsapi-agent-id 为旧版 dd.config 方案保留,可不配
|
||||
# jsapi-agent-id:
|
||||
|
||||
# 正元智慧
|
||||
# https://gwyc.zj.gov.cn/API/%E7%9C%81%E5%B9%B3%E5%8F%B0API%E5%AF%B9%E6%8E%A5%E6%8E%A5%E5%8F%A3.html
|
||||
|
||||
Reference in new issue
Block a user