diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-biz/pom.xml b/pjcloud-thirdparty/pjcloud-thirdparty-biz/pom.xml index cb431bbcf..81f09a7fa 100644 --- a/pjcloud-thirdparty/pjcloud-thirdparty-biz/pom.xml +++ b/pjcloud-thirdparty/pjcloud-thirdparty-biz/pom.xml @@ -155,6 +155,19 @@ 5.7.0 compile + + + com.alibaba.xxpt + zwdd-sdk-java + 1.2.0 + system + ${project.basedir}/src/lib/zwdd-sdk-java-1.2.0.jar + + + joda-time + joda-time + 2.10 + @@ -190,6 +203,7 @@ CLASSIC + true diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/lib/zwdd-sdk-java-1.2.0.jar b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/lib/zwdd-sdk-java-1.2.0.jar new file mode 100644 index 000000000..497940666 Binary files /dev/null and b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/lib/zwdd-sdk-java-1.2.0.jar differ diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/config/ZzdOpenPlatformExecutableClientHolder.java b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/config/ZzdOpenPlatformExecutableClientHolder.java new file mode 100644 index 000000000..dbe3a8726 --- /dev/null +++ b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/config/ZzdOpenPlatformExecutableClientHolder.java @@ -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(); + } +} diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/config/ZzdOpenPlatformProperties.java b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/config/ZzdOpenPlatformProperties.java index 459b0901f..530eb1914 100644 --- a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/config/ZzdOpenPlatformProperties.java +++ b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/config/ZzdOpenPlatformProperties.java @@ -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); } diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/controller/ThirdPartyOAth2Cotroller.java b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/controller/ThirdPartyOAth2Cotroller.java index db7de5420..d6cc79d4b 100644 --- a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/controller/ThirdPartyOAth2Cotroller.java +++ b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/controller/ThirdPartyOAth2Cotroller.java @@ -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 zzdJsapiConfig() { + try { + return R.ok(thirdPartyOAuth2Service.buildZzdJsapiConfigForH5()); + } catch (ThirdPartyException e) { + return R.failed(e.getMessage()); + } + } + @PostMapping("/zzdsso") @Operation(summary = "浙政钉单点登录") @SysLog("浙政钉单点登录") diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/ThirdPartyOAuth2Service.java b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/ThirdPartyOAuth2Service.java index 7e40f6d55..853a4992f 100644 --- a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/ThirdPartyOAuth2Service.java +++ b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/ThirdPartyOAuth2Service.java @@ -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 body = new LinkedMultiValueMap<>(); - body.add("appkey", zzdOpenPlatform.getAppKey()); - body.add("appsecret", zzdOpenPlatform.getAppSecret()); - HttpEntity> entity = new HttpEntity<>(body, headers); - ResponseEntity 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 body = new LinkedMultiValueMap<>(); - body.add("access_token", appToken); - body.add("auth_code", authCode); - HttpEntity> entity = new HttpEntity<>(body, headers); - ResponseEntity 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 diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/vo/ZzdJsapiConfigVO.java b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/vo/ZzdJsapiConfigVO.java new file mode 100644 index 000000000..1301b4030 --- /dev/null +++ b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/vo/ZzdJsapiConfigVO.java @@ -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 jsApiList; +} diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/resources/application.yml b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/resources/application.yml index f0b36d3ac..390f36294 100644 --- a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/resources/application.yml +++ b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/resources/application.yml @@ -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