新增钉钉 Stream SDK 依赖,支持无 HTTP 上下文的后台线程显式传入 token 进行审批回调。同时,完善了 MES 审批台账功能,新增审批记录同步、批量发起审批时的门禁与台账写入逻辑,增强了系统的审批流管理能力。

This commit is contained in:
geht
2026-06-05 10:44:30 +08:00
parent 4785c55e52
commit fc4e3211ad
73 changed files with 5225 additions and 240 deletions

View File

@@ -66,6 +66,12 @@ public class SysThirdAppConfig {
@Schema(description = "是否启用(0-否,1-是)")
private Integer status;
//update-begin---author:GHT ---date:20260604 for【钉钉Stream回调】Stream事件推送主配置标识-----
/**Stream事件推送主配置(0-否,1-是)*/
@Schema(description = "Stream事件推送主配置(0-否,1-是),同一 thirdType 中只有一条记录为1")
private Integer streamEnabled;
//update-end---author:GHT ---date:20260604 for【钉钉Stream回调】Stream事件推送主配置标识-----
/**创建日期*/
@Excel(name = "创建日期", width = 20, format = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")

View File

@@ -1196,6 +1196,70 @@ public class ThirdAppDingtalkServiceImpl implements IThirdAppService {
return configMapper.getThirdConfigByThirdType(tenantId,MessageTypeEnum.DD.getType());
}
//update-begin---author:GHT ---date:20260604 for【钉钉Stream回调】获取钉钉应用凭证Stream模式专用-----
/**
* 获取钉钉应用凭证 [clientId, clientSecret],供 Stream 长连接使用。
* <p>
* 优先级:
* ① stream_enabled=1 的记录(管理员在「钉钉集成」页面显式指定的 Stream 主配置)
* ② 兜底AppKey 长度 > 10 的第一条有效记录(迁移期或未配置时保持可用)
*
* @return [appKey, appSecret];未配置时返回 null
*/
public String[] getDingAppCredentials() {
java.util.List<SysThirdAppConfig> all = configMapper.selectList(
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<SysThirdAppConfig>()
.eq(SysThirdAppConfig::getThirdType, THIRD_TYPE)
.isNotNull(SysThirdAppConfig::getClientId)
.isNotNull(SysThirdAppConfig::getClientSecret)
// stream_enabled=1 的排最前面
.orderByDesc(SysThirdAppConfig::getStreamEnabled)
.orderByDesc(SysThirdAppConfig::getTenantId));
for (SysThirdAppConfig c : all) {
String appKey = c.getClientId();
String appSecret = c.getClientSecret();
if (oConvertUtils.isNotEmpty(appKey) && appKey.length() > 10
&& oConvertUtils.isNotEmpty(appSecret) && appSecret.length() > 10) {
return new String[]{appKey, appSecret};
}
}
return null;
}
//update-end---author:GHT ---date:20260604 for【钉钉Stream回调】获取钉钉应用凭证Stream模式专用-----
//update-begin---author:GHT ---date:20260604 for【钉钉Stream回调】后台线程专用AccessToken绕过租户检查-----
/**
* 后台线程专用:获取钉钉 AccessToken不依赖 TenantContext。
* <p>
* 原 {@link #getAccessToken()} 内部调 {@code tenantIzExist(0)}
* 后台线程无租户上下文时 tenantId 默认 0若 tenant=0 不存在直接抛异常。
* 本方法复用 {@link #getDingAppCredentials()} 的安全查询,绕过租户校验。
*
* @return AccessToken 字符串;未配置或失败时返回 null
*/
public String getAccessTokenForBackground() {
String[] creds = getDingAppCredentials();
if (creds == null || oConvertUtils.isEmpty(creds[0]) || oConvertUtils.isEmpty(creds[1])) {
log.warn("[DingBg] 未找到有效钉钉配置,无法获取 AccessToken");
return null;
}
try {
// JdtBaseAPI 已在文件顶部 import com.jeecg.dingtalk.api.base.JdtBaseAPI
// AccessToken 已在文件顶部 import com.jeecg.dingtalk.api.core.vo.AccessToken
AccessToken token = JdtBaseAPI.getAccessToken(creds[0], creds[1]);
if (token != null && oConvertUtils.isNotEmpty(token.getAccessToken())) {
return token.getAccessToken();
}
log.warn("[DingBg] getAccessToken 返回空");
return null;
} catch (Exception e) {
log.warn("[DingBg] 获取 AccessToken 失败: {}", e.getMessage());
return null;
}
}
//update-end---author:GHT ---date:20260604 for【钉钉Stream回调】后台线程专用AccessToken绕过租户检查-----
/**
* 获取钉钉accessToken
* @param config