chengzq il y a 2 semaines
Parent
commit
94be11d4de
100 fichiers modifiés avec 12348 ajouts et 0 suppressions
  1. 148 0
      build.gradle
  2. 43 0
      code/base/nckd-nc2kd-base-common/build.gradle
  3. BIN
      code/base/nckd-nc2kd-base-common/build/classes/java/main/nckd/nc2kd/base/common/utils/HttpRequestUtils.class
  4. BIN
      code/base/nckd-nc2kd-base-common/build/libs/nckd-nc2kd-base-common-1.0.0-sources.jar
  5. BIN
      code/base/nckd-nc2kd-base-common/build/libs/nckd-nc2kd-base-common-1.0.0.jar
  6. 0 0
      code/base/nckd-nc2kd-base-common/build/resources/main/.gitkeep
  7. 0 0
      code/base/nckd-nc2kd-base-common/build/resources/test/.gitkeep
  8. BIN
      code/base/nckd-nc2kd-base-common/build/tmp/compileJava/previous-compilation-data.bin
  9. 16 0
      code/base/nckd-nc2kd-base-common/build/tmp/jar/MANIFEST.MF
  10. 2 0
      code/base/nckd-nc2kd-base-common/build/tmp/sourcesJar/MANIFEST.MF
  11. 0 0
      code/base/nckd-nc2kd-base-common/src/main/java/nckd/nc2kd/base/common/constant/.gitkeep
  12. 0 0
      code/base/nckd-nc2kd-base-common/src/main/java/nckd/nc2kd/base/common/enums/.gitkeep
  13. 0 0
      code/base/nckd-nc2kd-base-common/src/main/java/nckd/nc2kd/base/common/exception/.gitkeep
  14. 644 0
      code/base/nckd-nc2kd-base-common/src/main/java/nckd/nc2kd/base/common/utils/HttpRequestUtils.java
  15. 0 0
      code/base/nckd-nc2kd-base-common/src/main/resources/.gitkeep
  16. 0 0
      code/base/nckd-nc2kd-base-common/src/test/java/nckd/base/common/test/.gitkeep
  17. 0 0
      code/base/nckd-nc2kd-base-common/src/test/resources/.gitkeep
  18. 12 0
      code/base/nckd-nc2kd-base-helper/build.gradle
  19. BIN
      code/base/nckd-nc2kd-base-helper/build/libs/nckd-nc2kd-base-helper-1.0.0-sources.jar
  20. BIN
      code/base/nckd-nc2kd-base-helper/build/libs/nckd-nc2kd-base-helper-1.0.0.jar
  21. 0 0
      code/base/nckd-nc2kd-base-helper/build/resources/main/.gitkeep
  22. 0 0
      code/base/nckd-nc2kd-base-helper/build/resources/test/.gitkeep
  23. 16 0
      code/base/nckd-nc2kd-base-helper/build/tmp/jar/MANIFEST.MF
  24. 2 0
      code/base/nckd-nc2kd-base-helper/build/tmp/sourcesJar/MANIFEST.MF
  25. 0 0
      code/base/nckd-nc2kd-base-helper/src/main/java/nckd/base/helper/.gitkeep
  26. 0 0
      code/base/nckd-nc2kd-base-helper/src/main/resources/.gitkeep
  27. 0 0
      code/base/nckd-nc2kd-base-helper/src/test/java/nckd/base/helper/test/.gitkeep
  28. 0 0
      code/base/nckd-nc2kd-base-helper/src/test/resources/.gitkeep
  29. 0 0
      code/lib/.gitkeep
  30. 18 0
      code/nckd-cosmic-debug/build.gradle
  31. BIN
      code/nckd-cosmic-debug/build/classes/java/main/kd/cosmic/debug/tools/CosmicLauncher.class
  32. BIN
      code/nckd-cosmic-debug/build/classes/java/main/nckd/cosmic/debug/DebugApplication.class
  33. BIN
      code/nckd-cosmic-debug/build/libs/nckd-cosmic-debug-1.0.0-sources.jar
  34. BIN
      code/nckd-cosmic-debug/build/libs/nckd-cosmic-debug-1.0.0.jar
  35. 63 0
      code/nckd-cosmic-debug/build/resources/main/logback-kafka.xml
  36. 63 0
      code/nckd-cosmic-debug/build/resources/main/logback.xml
  37. 0 0
      code/nckd-cosmic-debug/build/resources/test/.gitkeep
  38. BIN
      code/nckd-cosmic-debug/build/tmp/compileJava/previous-compilation-data.bin
  39. 16 0
      code/nckd-cosmic-debug/build/tmp/jar/MANIFEST.MF
  40. 2 0
      code/nckd-cosmic-debug/build/tmp/sourcesJar/MANIFEST.MF
  41. 494 0
      code/nckd-cosmic-debug/src/main/java/kd/cosmic/debug/tools/CosmicLauncher.java
  42. 45 0
      code/nckd-cosmic-debug/src/main/java/nckd/cosmic/debug/DebugApplication.java
  43. 63 0
      code/nckd-cosmic-debug/src/main/resources/logback-kafka.xml
  44. 63 0
      code/nckd-cosmic-debug/src/main/resources/logback.xml
  45. 0 0
      code/nckd-cosmic-debug/src/test/java/nckd/cosmic/debug/test/.gitkeep
  46. 0 0
      code/nckd-cosmic-debug/src/test/resources/.gitkeep
  47. 14 0
      code/sys/nckd-nc2kd-sys/build.gradle
  48. BIN
      code/sys/nckd-nc2kd-sys/build/classes/java/main/nckd/nc2kd/sys/webapi/common/HttpJwt.class
  49. BIN
      code/sys/nckd-nc2kd-sys/build/classes/java/main/nckd/nc2kd/sys/webapi/common/JwtTokenValidator.class
  50. BIN
      code/sys/nckd-nc2kd-sys/build/classes/java/main/nckd/nc2kd/sys/webapi/common/JwtUtil.class
  51. BIN
      code/sys/nckd-nc2kd-sys/build/classes/java/main/nckd/nc2kd/sys/webapi/common/TokenHelper.class
  52. BIN
      code/sys/nckd-nc2kd-sys/build/classes/java/main/nckd/nc2kd/sys/webapi/common/ValidJwt.class
  53. BIN
      code/sys/nckd-nc2kd-sys/build/classes/java/main/nckd/nc2kd/sys/webapi/sso/ThirdSSOAuthHandlerOA.class
  54. BIN
      code/sys/nckd-nc2kd-sys/build/classes/java/main/nckd/nc2kd/sys/webapi/webapi/PlatPersistenceFilter.class
  55. BIN
      code/sys/nckd-nc2kd-sys/build/libs/nckd-nc2kd-sys-1.0.0-sources.jar
  56. BIN
      code/sys/nckd-nc2kd-sys/build/libs/nckd-nc2kd-sys-1.0.0.jar
  57. 11 0
      code/sys/nckd-nc2kd-sys/build/resources/main/filterXml/PlatFilter.xml
  58. 0 0
      code/sys/nckd-nc2kd-sys/build/resources/test/.gitkeep
  59. BIN
      code/sys/nckd-nc2kd-sys/build/tmp/compileJava/previous-compilation-data.bin
  60. 16 0
      code/sys/nckd-nc2kd-sys/build/tmp/jar/MANIFEST.MF
  61. 2 0
      code/sys/nckd-nc2kd-sys/build/tmp/sourcesJar/MANIFEST.MF
  62. 0 0
      code/sys/nckd-nc2kd-sys/src/main/java/nckd/nc2kd/sys/webapi/business/.gitkeep
  63. 77 0
      code/sys/nckd-nc2kd-sys/src/main/java/nckd/nc2kd/sys/webapi/common/HttpJwt.java
  64. 72 0
      code/sys/nckd-nc2kd-sys/src/main/java/nckd/nc2kd/sys/webapi/common/JwtTokenValidator.java
  65. 43 0
      code/sys/nckd-nc2kd-sys/src/main/java/nckd/nc2kd/sys/webapi/common/JwtUtil.java
  66. 101 0
      code/sys/nckd-nc2kd-sys/src/main/java/nckd/nc2kd/sys/webapi/common/TokenHelper.java
  67. 29 0
      code/sys/nckd-nc2kd-sys/src/main/java/nckd/nc2kd/sys/webapi/common/ValidJwt.java
  68. 113 0
      code/sys/nckd-nc2kd-sys/src/main/java/nckd/nc2kd/sys/webapi/sso/ThirdSSOAuthHandlerOA.java
  69. 89 0
      code/sys/nckd-nc2kd-sys/src/main/java/nckd/nc2kd/sys/webapi/webapi/PlatPersistenceFilter.java
  70. 11 0
      code/sys/nckd-nc2kd-sys/src/main/resources/filterXml/PlatFilter.xml
  71. 0 0
      code/sys/nckd-nc2kd-sys/src/test/java/nckd/sys/webapi/business/test/.gitkeep
  72. 0 0
      code/sys/nckd-nc2kd-sys/src/test/java/nckd/sys/webapi/common/test/.gitkeep
  73. 0 0
      code/sys/nckd-nc2kd-sys/src/test/java/nckd/sys/webapi/mservice/test/.gitkeep
  74. 0 0
      code/sys/nckd-nc2kd-sys/src/test/java/nckd/sys/webapi/plugin/test/.gitkeep
  75. 0 0
      code/sys/nckd-nc2kd-sys/src/test/java/nckd/sys/webapi/report/test/.gitkeep
  76. 0 0
      code/sys/nckd-nc2kd-sys/src/test/java/nckd/sys/webapi/webapi/test/.gitkeep
  77. 0 0
      code/sys/nckd-nc2kd-sys/src/test/resources/.gitkeep
  78. 45 0
      config.gradle
  79. 5 0
      cosmic.json
  80. 1 0
      cosmic.properties
  81. 0 0
      datamodel/.gitkeep
  82. BIN
      docs/images/code1.png
  83. BIN
      docs/images/cosmic-studio-qrcode.png
  84. BIN
      docs/images/eclipse-gradle.png
  85. BIN
      docs/images/idea-gradle.png
  86. 28 0
      gradle.properties
  87. BIN
      gradle/wrapper/gradle-wrapper.jar
  88. 5 0
      gradle/wrapper/gradle-wrapper.properties
  89. 240 0
      gradlew
  90. 91 0
      gradlew.bat
  91. 350 0
      logs/cosmic_out.log
  92. 282 0
      logs/cosmic_out_20250409_0.log
  93. 217 0
      logs/cosmic_out_20250410_0.log
  94. 136 0
      logs/cosmic_out_20250410_1.log
  95. 3807 0
      logs/cosmic_out_20250410_2.log
  96. 698 0
      logs/cosmic_out_20250410_3.log
  97. 242 0
      logs/cosmic_out_20250411_0.log
  98. 1378 0
      logs/cosmic_out_20250411_1.log
  99. 915 0
      logs/cosmic_out_20250411_2.log
  100. 1620 0
      logs/cosmic_out_20250411_3.log

+ 148 - 0
build.gradle

@@ -0,0 +1,148 @@
+/**
+ * This is a kingdee cosmic template project that is automatically generated by the Kingdee cosmic development assistant plugin. 
+ * If there are any issues during the use process, you can provide feedback to the kingdee developer community website.
+ * Website: https://developer.kingdee.com/developer?productLineId=29
+ * Author: liebin.zheng
+ * Generate Date: 2025-04-09 17:34:20
+ */
+
+plugins {
+	id 'java'
+	//https://docs.gradle.org/current/userguide/java_library_plugin.html#java_library_plugin
+    id 'java-library'
+    //id 'maven-publish'
+    //https://docs.gradle.org/current/userguide/idea_plugin.html
+    //id 'idea'
+    //https://docs.gradle.org/current/userguide/eclipse_plugin.html
+    //id 'eclipse'
+    //id "org.sonarqube" version "3.5.0.2730"
+}
+
+apply from: 'config.gradle'
+
+def bos = ext.path.bos	
+def trd = ext.path.trd
+def cus = ext.path.cus
+def biz = ext.path.biz
+def outputdir = ext.path.outputdir
+
+//所有工程共用的配置
+allprojects {
+	
+	apply plugin: 'java'
+	apply plugin: 'maven-publish'
+	apply plugin: 'java-library'
+	apply plugin: 'eclipse'
+	apply plugin: 'idea'
+
+	repositories{
+		mavenLocal()
+		maven{ url'https://maven.aliyun.com/repository/public/'}
+		maven{ url'https://maven.aliyun.com/repository/gradle-plugin'}
+		mavenCentral()
+		//maven { url 'https://repo.gradle.org/gradle/libs-releases' }
+		//gradlePluginPortal()
+	}
+	
+	group = System.getProperty('groupId')
+	version = System.getProperty('version')
+	
+	def jdk_version = System.getProperty('jdk.version')
+	sourceCompatibility = jdk_version
+	targetCompatibility = jdk_version
+	
+	tasks.withType(JavaCompile) {  
+		options.encoding = "UTF-8" 
+	}
+
+	dependencies {
+		
+		//implementation 'cn.hutool:hutool-all:5.8.20'
+		//implementation 'ch.qos.logback:logback-classic:1.2.12'
+		//implementation 'org.slf4j:log4j-over-slf4j:1.7.36'
+		//implementation 'org.apache.logging.log4j:log4j-to-slf4j:2.20.0' 
+		//testImplementation platform('org.junit:junit-bom:5.9.1')
+    	//testImplementation 'org.junit.jupiter:junit-jupiter'
+    	
+	}
+	
+	test {
+	    useJUnitPlatform()
+	}
+	
+	java {
+	    withSourcesJar()
+	    //withJavadocJar()
+	}
+	
+	Date now = new Date()
+	String date = now.format('yyyy-MM-dd HH:mm:ss')
+	String buildNum = now.format('yyyyMMddHHmmssSSS')
+	
+	String gitCommitShortHash = ''
+	String gitBranch = ''
+	try{
+		gitCommitShortHash = 'git log -1 --pretty=%H'.execute([], rootDir).text.trim()
+		gitBranch = 'git branch --show-current'.execute([], rootDir).text.trim()
+	} catch(Exception e){
+		println "warning: the commandline tools of git was not installed!"
+	}
+	
+	jar {
+	    manifest {
+	    	attributes 'Group-Name': project.group
+	    	attributes 'Project-Name': project.name
+	    	attributes 'Bundle-Version': project.version
+	    	attributes 'Build-Num': buildNum
+	        attributes 'Build-Date': date
+	    	attributes 'Build-Jdk': System.getProperty('java.version')
+	    	attributes 'Built-By': 'Kingdee Cosmic Developer Tools'
+	    	attributes 'Build-Tool': 'Gradle ' + project.gradle.gradleVersion
+	        attributes 'Git-Commit-Hash': gitCommitShortHash
+	    	attributes 'Git-Branch': gitBranch
+	        attributes 'Cloud-Name': ''
+	        attributes 'App-Name': ''
+	        attributes 'Jar-Id': ''
+	        attributes 'Build-Image': ''
+	    }
+	}
+	
+}
+
+//所有子工程共用的配置
+subprojects {
+	
+	dependencies {
+		
+	}
+	
+	//生成本工程jar包并拷贝到outputdir目录
+	task buildJar(type: Copy, dependsOn: build){
+		group 'build'
+		description '生成本工程jar包并拷贝到outputdir目录'
+		from 'build/libs'
+		into outputdir
+		exclude '*sources.jar','*javadoc.jar','*cosmic-debug*.jar'
+		// 多语言配置文件放在src/main/java/resources目录下
+		// 其他配置文件放在src/main/resources目录下
+		processResources{
+			from('src/main/java'){
+				include '**/*.properties'
+			}
+		}
+	}
+	
+	//生成本工程jar包并拷贝到拷贝到cus目录
+	task deployJar(type: Copy, dependsOn: buildJar){
+	 	group 'build'
+		description '生成本工程jar包并拷贝到拷贝到cus目录'
+		from outputdir
+		into cus
+		exclude '*sources.jar','*javadoc.jar','*cosmic-debug*.jar'
+	 }
+	 
+	test.ignoreFailures true
+	
+	
+}
+

+ 43 - 0
code/base/nckd-nc2kd-base-common/build.gradle

@@ -0,0 +1,43 @@
+/*
+ * This is a kingdee cosmic template project that is automatically generated by the Kingdee cosmic development assistant plugin. 
+ * If there are any issues during the use process, you can provide feedback to the kingdee developer community website.
+ * Website: https://developer.kingdee.com/developer?productLineId=29
+ * Author: liebin.zheng
+ * Generate Date: 2025-04-09 17:34:20
+ */
+
+apply from: '../../../config.gradle'
+
+def bos = ext.path.bos	
+def trd = ext.path.trd
+def cus = ext.path.cus
+def biz = ext.path.biz
+def lib = ext.path.lib
+
+dependencies {
+	api fileTree(dir: bos, include: '*.jar')
+	
+	api fileTree(trd) { include '*.jar' exclude 'qing-arthas-*.jar' }
+	
+	//如果出现本地启动出现log4j相关依赖包版本冲突的问题,则可以参考以下方式手工解决
+	//api fileTree(trd) {
+	//	include '*.jar'
+	//	exclude 'log4j-api-*.jar','logback-*.jar','slf4j-*.jar','qing-arthas-*.jar'
+	//}
+	//api 'cn.hutool:hutool-all:5.8.20'
+	//api 'ch.qos.logback:logback-classic:1.2.12'
+	//api 'org.slf4j:log4j-over-slf4j:1.7.36'
+	//api 'org.apache.logging.log4j:log4j-to-slf4j:2.20.0' 
+	
+	//默认情况下,biz目录下的依赖均为运行时依赖
+	runtimeOnly fileTree(dir: biz, include: '*.jar')
+	
+	//如存在编译阶段需要依赖的jar包,则可参考一下配置,按需引入对应的jar包
+	//api fileTree(dir: biz, include: '*sdk*.jar')
+	//编译阶段不需要依赖的jar包,则统一配置为运行时依赖
+	//runtimeOnly fileTree(biz) { include '*.jar' exclude '*sdk*.jar' }
+
+	runtimeOnly fileTree(dir: cus, include: '*.jar')
+	
+	api fileTree(dir: lib, include: '*.jar')
+}

BIN
code/base/nckd-nc2kd-base-common/build/classes/java/main/nckd/nc2kd/base/common/utils/HttpRequestUtils.class


BIN
code/base/nckd-nc2kd-base-common/build/libs/nckd-nc2kd-base-common-1.0.0-sources.jar


BIN
code/base/nckd-nc2kd-base-common/build/libs/nckd-nc2kd-base-common-1.0.0.jar


+ 0 - 0
code/base/nckd-nc2kd-base-common/build/resources/main/.gitkeep


+ 0 - 0
code/base/nckd-nc2kd-base-common/build/resources/test/.gitkeep


BIN
code/base/nckd-nc2kd-base-common/build/tmp/compileJava/previous-compilation-data.bin


+ 16 - 0
code/base/nckd-nc2kd-base-common/build/tmp/jar/MANIFEST.MF

@@ -0,0 +1,16 @@
+Manifest-Version: 1.0
+Jar-Id: 
+Project-Name: nckd-nc2kd-base-common
+Build-Tool: Gradle 7.6.3
+Build-Date: 2025-04-15 19:38:26
+Built-By: Kingdee Cosmic Developer Tools
+Build-Num: 20250415193826367
+App-Name: 
+Git-Branch: master
+Cloud-Name: 
+Group-Name: nckd.cosmic
+Bundle-Version: 1.0.0
+Git-Commit-Hash: ab430c1867721472f0f3f2f2919969c5c158f154
+Build-Image: 
+Build-Jdk: 1.8.0_331
+

+ 2 - 0
code/base/nckd-nc2kd-base-common/build/tmp/sourcesJar/MANIFEST.MF

@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+

+ 0 - 0
code/base/nckd-nc2kd-base-common/src/main/java/nckd/nc2kd/base/common/constant/.gitkeep


+ 0 - 0
code/base/nckd-nc2kd-base-common/src/main/java/nckd/nc2kd/base/common/enums/.gitkeep


+ 0 - 0
code/base/nckd-nc2kd-base-common/src/main/java/nckd/nc2kd/base/common/exception/.gitkeep


+ 644 - 0
code/base/nckd-nc2kd-base-common/src/main/java/nckd/nc2kd/base/common/utils/HttpRequestUtils.java

@@ -0,0 +1,644 @@
+package nckd.nc2kd.base.common.utils;
+
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.logging.Log;
+import kd.bos.logging.LogFactory;
+import kd.bos.logorm.LogORM;
+import kd.bos.servicehelper.BusinessDataServiceHelper;
+import org.apache.http.Header;
+import org.apache.http.HttpEntity;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.util.EntityUtils;
+import org.json.JSONObject;
+import org.json.XML;
+import org.springframework.http.MediaType;
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
+import javax.xml.XMLConstants;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.InetAddress;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.*;
+
+/**
+ * http请求工具类
+ */
+public class HttpRequestUtils {
+    public static final String DISALLOW_DOCTYPE_DECL = "http://apache.org/xml/features/disallow-doctype-decl";
+    public static final String LOAD_EXTERNAL_DTD = "http://apache.org/xml/features/nonvalidating/load-external-dtd";
+    public static final String EXTERNAL_GENERAL_ENTITIES = "http://xml.org/sax/features/external-general-entities";
+    public static final String EXTERNAL_PARAMETER_ENTITIES = "http://xml.org/sax/features/external-parameter-entities";
+    private static CloseableHttpClient httpClient = HttpClientBuilder.create().build();
+
+    public static final Log log = LogFactory.getLog(HttpRequestUtils.class);
+
+    /**
+     * Get请求
+     *
+     * @param url 请求地址
+     * @param headers 请求头
+     * @return 请求结果
+     */
+    public static String get(String url, Header[] headers) {
+        HttpGet httpGet = new HttpGet(url);
+        // 请求头中设置授权TOKEN
+        httpGet.setHeaders(headers);
+        String result = "";
+
+        try (CloseableHttpResponse httpResponse = httpClient.execute(httpGet)) {
+            // 返回状态码
+            int statusCode = httpResponse.getStatusLine().getStatusCode();
+            if (statusCode == 200) {
+                HttpEntity httpEntity = httpResponse.getEntity();
+                // 获取结果
+                result = EntityUtils.toString(httpEntity);
+                EntityUtils.consumeQuietly(httpEntity);
+
+            } else if (statusCode == 401) {
+                HttpEntity httpEntity = httpResponse.getEntity();
+                // 获取结果
+                result = EntityUtils.toString(httpEntity);
+                EntityUtils.consumeQuietly(httpEntity);
+            }
+        } catch (IOException ignored) {
+
+        }
+        return result;
+
+    }
+
+    /**
+     * POST请求
+     *
+     * @param url 请求地址
+     * @param headers 请求头
+     * @param data 请求参数
+     * @return 请求结果
+     */
+    public static String post(String url, Header[] headers, String data) {
+
+        HttpPost httpPost = new HttpPost(url);
+        httpPost.setHeaders(headers);
+        // 设置参数
+        StringEntity stringEntity = new StringEntity(data, StandardCharsets.UTF_8);
+        stringEntity.setContentType(MediaType.APPLICATION_JSON_VALUE);
+        httpPost.setEntity(stringEntity);
+        String result = "";
+        try (CloseableHttpResponse httpResponse = httpClient.execute(httpPost)) {
+            // 返回状态码
+            int statusCode = httpResponse.getStatusLine().getStatusCode();
+            if (statusCode == 200) {
+                HttpEntity httpEntity = httpResponse.getEntity();
+                // 获取结果
+                result = EntityUtils.toString(httpEntity);
+                EntityUtils.consumeQuietly(httpEntity);
+            } else {
+                InetAddress localHost = InetAddress.getLocalHost();
+                //writeLog("http请求", "http请求异常" + statusCode, "url:" + url + "IP:" + localHost, data, EntityUtils.toString(httpResponse.getEntity()));
+            }
+        } catch (IOException ignored) {
+
+        }
+        return result;
+    }
+
+
+    /**
+     * POST请求(可设置请求时长)
+     *
+     * @param url 请求地址
+     * @param headers 请求头
+     * @param data 请求参数
+     * @param timeout 单位:毫秒
+     * @return 请求结果
+     */
+    public static String post2(String url, Header[] headers, String data, int timeout) {
+
+        HttpPost httpPost = new HttpPost(url);
+        httpPost.setHeaders(headers);
+        // 设置请求时长
+        RequestConfig.Builder configBuilder = RequestConfig.custom();
+        configBuilder.setConnectTimeout(timeout);
+        configBuilder.setSocketTimeout(timeout);
+        RequestConfig requestConfig = configBuilder.build();
+        httpPost.setConfig(requestConfig);
+
+        // 设置参数
+        StringEntity stringEntity = new StringEntity(data, StandardCharsets.UTF_8);
+        stringEntity.setContentType(MediaType.APPLICATION_JSON_VALUE);
+        httpPost.setEntity(stringEntity);
+        String result = "";
+        try (CloseableHttpResponse httpResponse = httpClient.execute(httpPost)) {
+            // 返回状态码
+            int statusCode = httpResponse.getStatusLine().getStatusCode();
+            if (statusCode == 200) {
+                HttpEntity httpEntity = httpResponse.getEntity();
+                // 获取结果
+                result = EntityUtils.toString(httpEntity);
+                EntityUtils.consumeQuietly(httpEntity);
+            }
+        } catch (IOException ignored) {
+
+        }
+        return result;
+    }
+
+    /**
+     * post请求发送xml(application/soap+xml)
+     *
+     * @param serviceUrl 服务地址
+     * @param data       数据
+     * @param timeout    超时时间
+     * @return 请求结果
+     */
+    public static String postXml(String serviceUrl, String data, int timeout) {
+        try {
+            // HttpURLConnection 发送SOAP请求
+            URL url = new URL(serviceUrl);
+            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+
+            conn.setRequestProperty("Content-Type", "application/soap+xml; charset=utf-8");
+            conn.setRequestMethod("POST");
+            conn.setUseCaches(false);
+            conn.setDoInput(true);
+            conn.setDoOutput(true);
+            conn.setConnectTimeout(timeout);
+            conn.setReadTimeout(timeout);
+
+            DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
+            dos.write(data.getBytes(StandardCharsets.UTF_8));
+            dos.flush();
+
+            BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
+            String line;
+            StringBuilder strBuf = new StringBuilder();
+            while ((line = reader.readLine()) != null) {
+                strBuf.append(line);
+            }
+            dos.close();
+            reader.close();
+
+
+            // 创建一个DocumentBuilder对象
+            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+            factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
+
+            //factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); //禁用DTDs (doctypes),几乎可以防御所有xml实体攻击
+
+            // 禁用DTDs
+            factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
+            factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
+
+            // 禁用DTDs的另一种方式(如果上述特性不受支持)
+            factory.setExpandEntityReferences(false);
+            DocumentBuilder builder = factory.newDocumentBuilder();
+
+            // 使用DocumentBuilder解析XML字符串
+            Document document = builder.parse(new InputSource(new StringReader(strBuf.toString())));
+            // 将XML转换为JSONObject
+            JSONObject jsonObject = XML.toJSONObject(getStringFromDocument(document));
+
+            // 输出JSON
+            return jsonObject.toString(2); // 可以指定缩进空格数,这里是2
+        } catch (Exception e) {
+            log.error(e.getMessage());
+            return null;
+        }
+    }
+
+    /**
+     * post请求发送xml(text/xml)
+     *
+     * @param serviceUrl 服务地址
+     * @param data       数据
+     * @param timeout    超时时间
+     * @return 请求结果
+     */
+    public static String postXml2(String serviceUrl, String data, int timeout) {
+        try {
+            // HttpURLConnection 发送SOAP请求
+            URL url = new URL(serviceUrl);
+            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+
+            conn.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
+            conn.setRequestMethod("POST");
+            conn.setUseCaches(false);
+            conn.setDoInput(true);
+            conn.setDoOutput(true);
+            conn.setConnectTimeout(timeout);
+            conn.setReadTimeout(timeout);
+
+            DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
+            dos.write(data.getBytes(StandardCharsets.UTF_8));
+            dos.flush();
+
+            BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
+            String line = null;
+            StringBuilder strBuf = new StringBuilder();
+            while ((line = reader.readLine()) != null) {
+                strBuf.append(line);
+            }
+            dos.close();
+            reader.close();
+
+
+            // 创建一个DocumentBuilder对象
+            //创建DocumentBuilderFactory实例
+            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+            factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
+            // 禁用DTDs
+//            factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
+//            factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
+
+            // 禁用DTDs的另一种方式(如果上述特性不受支持)
+            factory.setExpandEntityReferences(false);
+            DocumentBuilder builder = factory.newDocumentBuilder();
+
+            // 使用DocumentBuilder解析XML字符串
+            Document document = builder.parse(new InputSource(new StringReader(strBuf.toString())));
+            // 将XML转换为JSONObject
+            JSONObject jsonObject = XML.toJSONObject(getStringFromDocument(document));
+
+            // 输出JSON
+            return jsonObject.toString(2); // 可以指定缩进空格数,这里是2
+        } catch (Exception e) {
+            log.error(e.getMessage());
+            return null;
+        }
+    }
+
+
+    /**
+     * post请求发送xml,可以指定SOAPAction(text/xml)
+     *
+     * @param serviceUrl 服务地址
+     * @param data       数据
+     * @param timeout    超时时间
+     * @param soapAction SOAPAction
+     * @return 请求结果
+     */
+    public static String postXml3(String serviceUrl, String data, int timeout, String soapAction) {
+        try {
+            // HttpURLConnection 发送SOAP请求
+            URL url = new URL(serviceUrl);
+            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+
+            conn.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
+            conn.setRequestProperty("SOAPAction", soapAction);
+            conn.setRequestMethod("POST");
+            conn.setUseCaches(false);
+            conn.setDoInput(true);
+            conn.setDoOutput(true);
+            conn.setConnectTimeout(timeout);
+            conn.setReadTimeout(timeout);
+
+            DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
+            dos.write(data.getBytes(StandardCharsets.UTF_8));
+            dos.flush();
+
+            BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
+            String line ;
+            StringBuilder strBuf = new StringBuilder();
+            while ((line = reader.readLine()) != null) {
+                strBuf.append(line);
+            }
+            dos.close();
+            reader.close();
+
+
+            // 创建一个DocumentBuilder对象
+            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+            factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
+            //如果不能禁用DTDs,可以使用下两项,必须两项同时存在
+
+            factory.setFeature("http://xml.org/sax/features/external-general-entities", false);      //防止外部普通实体POC 攻击
+            factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);   //防止外部参数实体POC攻击
+
+
+            // 禁用DTDs的另一种方式(如果上述特性不受支持)
+            factory.setExpandEntityReferences(false);
+            DocumentBuilder builder = factory.newDocumentBuilder();
+
+            // 使用DocumentBuilder解析XML字符串
+            Document document = builder.parse(new InputSource(new StringReader(strBuf.toString())));
+            // 将XML转换为JSONObject
+            JSONObject jsonObject = XML.toJSONObject(getStringFromDocument(document));
+
+            // 输出JSON
+            return jsonObject.toString(2); // 可以指定缩进空格数,这里是2
+        } catch (Exception e) {
+            log.error(e.getMessage());
+            return null;
+        }
+    }
+
+
+    /**
+     * 将Document对象转换为字符串
+     * @param document Document对象
+     * @return 字符串
+     */
+    private static String getStringFromDocument(Document document) {
+        try {
+            // 使用Transformer将Document转换为String
+            TransformerFactory tf = TransformerFactory.newInstance();
+            tf.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
+            tf.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
+            Transformer transformer = tf.newTransformer();
+            StringWriter writer = new StringWriter();
+            transformer.transform(new DOMSource(document), new StreamResult(writer));
+            return writer.toString();
+        } catch (TransformerConfigurationException e) {
+            log.error("处理配置错误", e);
+            // 处理配置错误
+            return null;
+        } catch (TransformerException e) {
+            log.error("处理转换错误", e);
+            // 处理转换错误
+            return null;
+        } catch (Exception e) {
+            log.error("处理其他类型的异常", e);
+            // 处理其他类型的异常
+            return null;
+        }
+    }
+
+
+    /**
+     * 构建动态SOAP请求
+     *
+     * @param soapParams   参数
+     * @param elementName  方法名称
+     * @param namespaceURI 命名空间
+     * @param soapAction SOAP动作
+     * @return
+     */
+    public static String buildDynamicSoapRequest(com.alibaba.fastjson.JSONObject soapParams, String elementName, String namespaceURI, String soapAction) {
+        if (soapAction == null) {
+            soapAction = "http://www.w3.org/2003/05/soap-envelope";
+        }
+        StringBuilder xmlBuilder = new StringBuilder();
+        xmlBuilder.append("<soapenv:Envelope xmlns:soapenv=\"").append(soapAction).append("\" ")
+                .append("xmlns:emp=\"").append(namespaceURI).append("\">")
+                .append("<soapenv:Header/><soapenv:Body>")
+                .append("<").append(elementName).append(">");
+
+        // 将动态参数添加到SOAP请求
+        for (String key : soapParams.keySet()) {
+            xmlBuilder.append("<emp:").append(key).append(">")
+                    .append(soapParams.get(key))
+                    .append("</emp:").append(key).append(">");
+        }
+
+        xmlBuilder.append("</").append(elementName).append("></soapenv:Body></soapenv:Envelope>");
+
+        return xmlBuilder.toString();
+    }
+
+    // 获取access_token请求参数处理
+    public static String buildOASoapRequest(com.alibaba.fastjson.JSONObject soapParams, String elementName, String namespaceURI, String soapAction) {
+        if (soapAction == null) {
+            soapAction = "http://www.w3.org/2003/05/soap-envelope";
+        }
+        StringBuilder xmlBuilder = new StringBuilder();
+        xmlBuilder.append("<soapenv:Envelope xmlns:soapenv=\"").append(soapAction).append("\" ")
+                .append("xmlns:out=\"").append(namespaceURI).append("\">")
+                .append("<soapenv:Header/><soapenv:Body>")
+                .append("<").append(elementName).append(">");
+
+        for (String key : soapParams.keySet()) {
+            xmlBuilder.append("<out:").append(key).append(">")
+                    .append(soapParams.get(key))
+                    .append("</out:").append(key).append(">");
+        }
+        xmlBuilder.append("</").append(elementName).append("></soapenv:Body></soapenv:Envelope>");
+        return xmlBuilder.toString();
+    }
+
+
+    /**
+     * oa系统校验人员soap拼接
+     *
+     * @param soapParams
+     * @param elementName
+     * @param namespaceURI
+     * @param soapAction
+     * @return
+     */
+    public static String buildDynamicSoapRequest2(com.alibaba.fastjson.JSONObject soapParams, String elementName, String namespaceURI, String soapAction) {
+        if (soapAction == null) {
+            soapAction = "http://www.w3.org/2003/05/soap-envelope";
+        }
+        StringBuilder xmlBuilder = new StringBuilder();
+        xmlBuilder.append("<soapenv:Envelope xmlns:soapenv=\"").append(soapAction).append("\" ")
+                .append("xmlns:aut=\"").append(namespaceURI).append("\">")
+                .append("<soapenv:Header/><soapenv:Body>")
+                .append("<").append(elementName).append(">");
+
+        // 将动态参数添加到SOAP请求
+        for (String key : soapParams.keySet()) {
+            xmlBuilder.append("<aut:").append(key).append(">")
+                    .append(soapParams.get(key))
+                    .append("</aut:").append(key).append(">");
+        }
+
+        xmlBuilder.append("</").append(elementName).append("></soapenv:Body></soapenv:Envelope>");
+
+        return xmlBuilder.toString();
+    }
+
+    /**
+     * ERP交叉校验soap拼接
+     *
+     * @param headerParams header参数
+     * @param soapParams   body参数
+     * @param functionName 函数名
+     * @param elementName  方法名
+     * @param username     erp认证用户名
+     * @param password     erp认证用户密码
+     * @return
+     */
+    public static String buildDynamicSoapRequest3(com.alibaba.fastjson.JSONObject headerParams, com.alibaba.fastjson.JSONObject soapParams, String functionName, String elementName, String username, String password) {
+        StringBuilder xmlBuilder = new StringBuilder();
+        xmlBuilder.append("<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" ")
+                .append("xmlns:sfy=\"http://xmlns.oracle.com/apps/cux/soaprovider/plsql/sfy_ap_statement_payment/\" ")
+                .append("xmlns:val=\"http://xmlns.oracle.com/apps/cux/soaprovider/plsql/sfy_ap_statement_payment/").append(functionName).append("/\">")
+                .append("<soapenv:Header><sfy:SOAHeader>");
+
+
+        // 将动态参数添加到SOAP请求(请求头)
+        for (String key : headerParams.keySet()) {
+            xmlBuilder.append("<sfy:").append(key).append(">")
+                    .append(headerParams.get(key))
+                    .append("</sfy:").append(key).append(">");
+        }
+
+        // 添加安全参数
+        xmlBuilder.append("</sfy:SOAHeader>")
+                .append("<wsse:Security xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\" mustUnderstand=\"1\">")
+                .append("<wsse:UsernameToken>")
+                .append("<wsse:Username>").append(username).append("</wsse:Username>")
+                .append("<wsse:Password Type=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText\">").append(password).append("</wsse:Password>")
+                .append("</wsse:UsernameToken></wsse:Security>");
+
+        xmlBuilder.append("</soapenv:Header><soapenv:Body>")
+                .append("<").append(elementName).append(">");
+        String[] split = elementName.split(":");
+        // 将动态参数添加到SOAP请求(参数)
+        for (String key : soapParams.keySet()) {
+            xmlBuilder.append("<").append(split[0]).append(":").append(key).append(">")
+                    .append(soapParams.get(key))
+                    .append("</").append(split[0]).append(":").append(key).append(">");
+        }
+
+
+        xmlBuilder.append("</").append(elementName).append("></soapenv:Body></soapenv:Envelope>");
+
+        return xmlBuilder.toString();
+    }
+
+
+    /**
+     * 获取企微打卡记录
+     *
+     * @param empid        工号
+     * @param startTime    开始时间
+     * @param endTime      结束时间
+     * @param checkindtype 打卡类型,固定2
+     * @return
+     */
+    public static String buildDynamicSoapRequest4(String empid, String startTime, String endTime, String checkindtype) {
+        StringBuilder xmlBuilder = new StringBuilder();
+        xmlBuilder.append("<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:wor=\"http://www.primeton.com/workWechatQueryUtilService\" >")
+                .append("<soapenv:Header />");
+
+        xmlBuilder.append("<soapenv:Body>")
+                .append("<wor:queryWXattendanceData>")
+                .append("<wor:userList>").append(empid).append("</wor:userList>")
+                .append("<wor:startTime>").append(startTime).append("</wor:startTime>")
+                .append("<wor:endTime>").append(endTime).append("</wor:endTime>")
+                .append("<wor:checkindtype>").append(checkindtype).append("</wor:checkindtype>")
+                .append("</wor:queryWXattendanceData>");
+
+
+        xmlBuilder.append("</soapenv:Body></soapenv:Envelope>");
+
+        return xmlBuilder.toString();
+    }
+
+    public static String buildOAPurchaseXml(HashMap<String, String> mapHeader, LinkedHashMap<String, String> mapParam, List<LinkedHashMap<String, String>> listEntryParam) {
+        StringBuffer xmlBuilder = new StringBuffer();
+        String sp = "\n";
+        xmlBuilder.append("<soapenv:Envelope\n" +
+                        "    xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"\n" +
+                        "    xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\"\n" +
+                        "    xmlns:imp=\"http://xmlns.oracle.com/apps/cux/soaprovider/plsql/sfy_po_oa_interface_pkg/import_pr_interface/\"\n" +
+                        "    xmlns:sfy=\"http://xmlns.oracle.com/apps/cux/soaprovider/plsql/sfy_po_oa_interface_pkg/\">\n")
+                //添加hearder信息
+                .append(" <soapenv:Header>\n" +
+                        "        <sfy:SOAHeader>\n");
+        for (String key : mapHeader.keySet()) {
+            xmlBuilder.append("<").append(key).append(">").append(mapHeader.get(key)).append("</").append(key).append(">").append(sp);
+        }
+        xmlBuilder.append(
+                        "        </sfy:SOAHeader>\n" +
+                                "        <wsse:Security mustUnderstand=\"1\">\n" +
+                                "            <wsse:UsernameToken>\n" +
+                                "                <wsse:Username>oa2erp</wsse:Username>\n" +
+                                "                <wsse:Password Type=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText\">1q2w#E$R</wsse:Password>\n" +
+                                "            </wsse:UsernameToken>\n" +
+                                "        </wsse:Security>\n" +
+                                "    </soapenv:Header>\n")
+                .append(" <soapenv:Body>\n" +
+                        "        <imp:InputParameters>\n");
+        for (String key : mapParam.keySet()) {
+            xmlBuilder.append("<imp:").append(key + ">").append(mapParam.get(key)).append("</imp:").append(key).append(">").append(sp);
+        }
+        xmlBuilder.append("<imp:P_PR_TBL_TYPE>");
+        for (int i = 0; i < listEntryParam.size(); i++) {
+            xmlBuilder.append(sp).append("<imp:P_PR_TBL_TYPE_ITEM>").append(sp);
+            LinkedHashMap<String, String> mapEntryParam = listEntryParam.get(i);
+            for (String key : mapEntryParam.keySet()) {
+                xmlBuilder.append("<imp:").append(key).append(">").append(mapEntryParam.get(key)).append("</imp:").append(key).append(">").append(sp);
+            }
+            xmlBuilder.append("</imp:P_PR_TBL_TYPE_ITEM>").append(sp);
+        }
+        xmlBuilder.append("</imp:P_PR_TBL_TYPE>");
+
+        xmlBuilder.append(
+                "\n</imp:InputParameters>\n" +
+                        "    </soapenv:Body>\n" +
+                        "</soapenv:Envelope>\n");
+        return xmlBuilder.toString();
+
+    }
+
+    public static String postHtml(String url, Header[] headers, String data, int timeout) {
+        HttpPost httpPost = new HttpPost(url);
+        httpPost.setHeaders(headers);
+        // 设置请求时长
+        RequestConfig.Builder configBuilder = RequestConfig.custom();
+        configBuilder.setConnectTimeout(timeout);
+        configBuilder.setSocketTimeout(timeout);
+        RequestConfig requestConfig = configBuilder.build();
+        httpPost.setConfig(requestConfig);
+
+        // 设置参数
+        StringEntity stringEntity = new StringEntity(data, StandardCharsets.UTF_8);
+        stringEntity.setContentType("application/x-www-form-urlencoded");
+        httpPost.setEntity(stringEntity);
+        String result = "";
+        try (CloseableHttpResponse httpResponse = httpClient.execute(httpPost)) {
+            // 返回状态码
+            int statusCode = httpResponse.getStatusLine().getStatusCode();
+            if (statusCode == 200) {
+                HttpEntity httpEntity = httpResponse.getEntity();
+                // 获取结果
+                result = EntityUtils.toString(httpEntity);
+                EntityUtils.consumeQuietly(httpEntity);
+            }
+        } catch (IOException ignored) {
+
+        }
+        return result;
+    }
+
+   /* *//**
+     * 写入日志
+     *
+     * @param name      操作人
+     * @param opName    操作名称
+     * @param opDesc    操作描述
+     * @param parameter 操作参数
+     * @param message   错误信息
+     *//*
+    public static void writeLog(String name, String opName, String opDesc, String parameter, String message) {
+        DynamicObject dynamicObject = BusinessDataServiceHelper.newDynamicObject(SendOaErrorLogEnum.DATA_OBJECT_TYPE_NAME);
+        dynamicObject.set(SendOaErrorLogEnum.USERNAME.getKey(), name);
+        dynamicObject.set(SendOaErrorLogEnum.OPNAME.getKey(), opName);
+        dynamicObject.set(SendOaErrorLogEnum.OPDESC.getKey(), opDesc);
+        dynamicObject.set(SendOaErrorLogEnum.OPDATE.getKey(), new Date());
+        dynamicObject.set(SendOaErrorLogEnum.PARAMETER2_TAG.getKey(), parameter);
+        dynamicObject.set(SendOaErrorLogEnum.ERRORMSG2_TAG.getKey(), message);
+
+        List<DynamicObject> list = new ArrayList<>();
+        list.add(dynamicObject);
+        LogORM.create().insert(list);
+    }*/
+}

+ 0 - 0
code/base/nckd-nc2kd-base-common/src/main/resources/.gitkeep


+ 0 - 0
code/base/nckd-nc2kd-base-common/src/test/java/nckd/base/common/test/.gitkeep


+ 0 - 0
code/base/nckd-nc2kd-base-common/src/test/resources/.gitkeep


+ 12 - 0
code/base/nckd-nc2kd-base-helper/build.gradle

@@ -0,0 +1,12 @@
+/*
+ * This is a kingdee cosmic template project that is automatically generated by the Kingdee cosmic development assistant plugin. 
+ * If there are any issues during the use process, you can provide feedback to the kingdee developer community website.
+ * Website: https://developer.kingdee.com/developer?productLineId=29
+ * Author: liebin.zheng
+ * Generate Date: 2025-04-09 17:34:20
+ */
+
+dependencies {
+	api project(':nckd-nc2kd-base-common')
+} 
+

BIN
code/base/nckd-nc2kd-base-helper/build/libs/nckd-nc2kd-base-helper-1.0.0-sources.jar


BIN
code/base/nckd-nc2kd-base-helper/build/libs/nckd-nc2kd-base-helper-1.0.0.jar


+ 0 - 0
code/base/nckd-nc2kd-base-helper/build/resources/main/.gitkeep


+ 0 - 0
code/base/nckd-nc2kd-base-helper/build/resources/test/.gitkeep


+ 16 - 0
code/base/nckd-nc2kd-base-helper/build/tmp/jar/MANIFEST.MF

@@ -0,0 +1,16 @@
+Manifest-Version: 1.0
+Jar-Id: 
+Project-Name: nckd-nc2kd-base-helper
+Build-Tool: Gradle 7.6.3
+Build-Date: 2025-04-15 19:38:26
+Built-By: Kingdee Cosmic Developer Tools
+Build-Num: 20250415193826435
+App-Name: 
+Git-Branch: master
+Cloud-Name: 
+Group-Name: nckd.cosmic
+Bundle-Version: 1.0.0
+Git-Commit-Hash: ab430c1867721472f0f3f2f2919969c5c158f154
+Build-Image: 
+Build-Jdk: 1.8.0_331
+

+ 2 - 0
code/base/nckd-nc2kd-base-helper/build/tmp/sourcesJar/MANIFEST.MF

@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+

+ 0 - 0
code/base/nckd-nc2kd-base-helper/src/main/java/nckd/base/helper/.gitkeep


+ 0 - 0
code/base/nckd-nc2kd-base-helper/src/main/resources/.gitkeep


+ 0 - 0
code/base/nckd-nc2kd-base-helper/src/test/java/nckd/base/helper/test/.gitkeep


+ 0 - 0
code/base/nckd-nc2kd-base-helper/src/test/resources/.gitkeep


+ 0 - 0
code/lib/.gitkeep


+ 18 - 0
code/nckd-cosmic-debug/build.gradle

@@ -0,0 +1,18 @@
+/*
+ * This is a kingdee cosmic template project that is automatically generated by the Kingdee cosmic development assistant plugin. 
+ * If there are any issues during the use process, you can provide feedback to the kingdee developer community website.
+ * Website: https://developer.kingdee.com/developer?productLineId=29
+ * Author: liebin.zheng
+ * Generate Date: 2025-04-09 17:34:20
+ */
+
+dependencies {
+
+	// 公共基础包
+	implementation project(':nckd-nc2kd-base-common')
+	implementation project(':nckd-nc2kd-base-helper')
+
+	// 引入sys云模块
+	implementation project(':nckd-nc2kd-sys')
+	
+} 

BIN
code/nckd-cosmic-debug/build/classes/java/main/kd/cosmic/debug/tools/CosmicLauncher.class


BIN
code/nckd-cosmic-debug/build/classes/java/main/nckd/cosmic/debug/DebugApplication.class


BIN
code/nckd-cosmic-debug/build/libs/nckd-cosmic-debug-1.0.0-sources.jar


BIN
code/nckd-cosmic-debug/build/libs/nckd-cosmic-debug-1.0.0.jar


+ 63 - 0
code/nckd-cosmic-debug/build/resources/main/logback-kafka.xml

@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+This is a kingdee cosmic template project that is automatically generated by the Kingdee cosmic development assistant plugin. 
+If there are any issues during the use process, you can provide feedback to the kingdee developer community website.
+Website: https://developer.kingdee.com/developer?productLineId=29
+Author: liebin.zheng
+Generate Date: generate_date
+ -->
+<configuration>
+	
+	<property name="LOG_DIR" value="logs"/>
+	<property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %5p ${PID:- } --- [%t] %-40.40logger{39} : %m%n"/>
+
+	<logger name="org.apache.catalina.startup.DigesterFactory" level="ERROR"/>
+	<logger name="org.apache.catalina.util.LifecycleBase" level="ERROR"/>
+	<logger name="org.apache.coyote.http11.Http11NioProtocol" level="WARN"/>
+	<logger name="org.apache.sshd.common.util.SecurityUtils" level="WARN"/>
+	<logger name="org.apache.tomcat.util.net.NioSelectorPool" level="WARN"/>
+	<logger name="org.eclipse.jetty.util.component.AbstractLifeCycle" level="ERROR"/>
+	<logger name="org.hibernate.validator.internal.util.Version" level="WARN"/>
+	<logger name="org.springframework.boot.actuate.endpoint.jmx" level="WARN"/>
+	
+    <logger name="kd.bos.dc.utils.AccountUtils" level="WARN"/>
+    <logger name="kd.bos.license" level="WARN"/>
+    <logger name="org.apache.zookeeper" level="WARN"/>
+    <logger name="kd.bos.portal.pluginnew" level="WARN" />
+    
+	<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+		<encoder>
+			<pattern>${LOG_PATTERN}</pattern>
+		</encoder>
+	</appender>
+	<!-- 
+	<appender name="FILE"
+		class="ch.qos.logback.core.rolling.RollingFileAppender">
+		<encoder>
+			<pattern>${LOG_PATTERN}</pattern>
+		</encoder>
+		<file>${LOG_DIR}/cosmic_out.log</file>
+		<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+			<cleanHistoryOnStart>false</cleanHistoryOnStart>
+			<fileNamePattern>${LOG_DIR}/cosmic_out_%d{yyyyMMdd}_%i.log</fileNamePattern>
+			<maxFileSize>10MB</maxFileSize>
+			<maxHistory>7</maxHistory>
+			<totalSizeCap>0</totalSizeCap>
+		</rollingPolicy>
+	</appender>
+	 -->
+	<appender name="kafka" class="kd.bos.logging.console.slf4j.logback.KafkaAppender">
+        <topic>{{clusterName}}-log</topic>
+        <brokerList>{{log.kafka.ip_port}}</brokerList>
+        <compressionType>none</compressionType>
+        <syncSend>false</syncSend>
+        <keySerializerClass>org.apache.kafka.common.serialization.StringSerializer</keySerializerClass>
+        <valueSerializerClass>org.apache.kafka.common.serialization.StringSerializer</valueSerializerClass>
+    </appender>
+	
+	<root level="INFO">
+		<appender-ref ref="CONSOLE" />
+		<appender-ref ref="kafka" />
+	</root>
+
+</configuration>

+ 63 - 0
code/nckd-cosmic-debug/build/resources/main/logback.xml

@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+This is a kingdee cosmic template project that is automatically generated by the Kingdee cosmic development assistant plugin. 
+If there are any issues during the use process, you can provide feedback to the kingdee developer community website.
+Website: https://developer.kingdee.com/developer?productLineId=29
+Author: liebin.zheng
+Generate Date: generate_date
+ -->
+<configuration>
+	
+	<property name="LOG_DIR" value="logs"/>
+	<property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %5p ${PID:- } --- [%t] %-40.40logger{39} : %m%n"/>
+
+	<logger name="org.apache.catalina.startup.DigesterFactory" level="ERROR"/>
+	<logger name="org.apache.catalina.util.LifecycleBase" level="ERROR"/>
+	<logger name="org.apache.coyote.http11.Http11NioProtocol" level="WARN"/>
+	<logger name="org.apache.sshd.common.util.SecurityUtils" level="WARN"/>
+	<logger name="org.apache.tomcat.util.net.NioSelectorPool" level="WARN"/>
+	<logger name="org.eclipse.jetty.util.component.AbstractLifeCycle" level="ERROR"/>
+	<logger name="org.hibernate.validator.internal.util.Version" level="WARN"/>
+	<logger name="org.springframework.boot.actuate.endpoint.jmx" level="WARN"/>
+	
+    <logger name="kd.bos.dc.utils.AccountUtils" level="WARN"/>
+    <logger name="kd.bos.license" level="WARN"/>
+    <logger name="org.apache.zookeeper" level="INFO"/>
+    <logger name="kd.bos.portal.pluginnew" level="WARN" />
+
+	<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+		<encoder>
+			<pattern>${LOG_PATTERN}</pattern>
+		</encoder>
+	</appender>
+
+	<appender name="FILE"
+		class="ch.qos.logback.core.rolling.RollingFileAppender">
+		<encoder>
+			<pattern>${LOG_PATTERN}</pattern>
+		</encoder>
+		<file>${LOG_DIR}/cosmic_out.log</file>
+		<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+			<cleanHistoryOnStart>false</cleanHistoryOnStart>
+			<fileNamePattern>${LOG_DIR}/cosmic_out_%d{yyyyMMdd}_%i.log</fileNamePattern>
+			<maxFileSize>10MB</maxFileSize>
+			<maxHistory>7</maxHistory>
+			<totalSizeCap>0</totalSizeCap>
+		</rollingPolicy>
+	</appender>
+	<!-- 
+	<appender name="kafka" class="kd.bos.logging.console.slf4j.logback.KafkaAppender">
+        <topic>{{clusterName}}-log</topic>
+        <brokerList>{{log.kafka.ip_port}}</brokerList>
+        <compressionType>none</compressionType>
+        <syncSend>false</syncSend>
+        <keySerializerClass>org.apache.kafka.common.serialization.StringSerializer</keySerializerClass>
+        <valueSerializerClass>org.apache.kafka.common.serialization.StringSerializer</valueSerializerClass>
+    </appender>
+	 -->
+	<root level="INFO">
+		<appender-ref ref="CONSOLE" />
+		<appender-ref ref="FILE" />
+	</root>
+
+</configuration>

+ 0 - 0
code/nckd-cosmic-debug/build/resources/test/.gitkeep


BIN
code/nckd-cosmic-debug/build/tmp/compileJava/previous-compilation-data.bin


+ 16 - 0
code/nckd-cosmic-debug/build/tmp/jar/MANIFEST.MF

@@ -0,0 +1,16 @@
+Manifest-Version: 1.0
+Jar-Id: 
+Project-Name: nckd-cosmic-debug
+Build-Tool: Gradle 7.6.3
+Build-Date: 2025-04-15 19:38:26
+Built-By: Kingdee Cosmic Developer Tools
+Build-Num: 20250415193826291
+App-Name: 
+Git-Branch: master
+Cloud-Name: 
+Group-Name: nckd.cosmic
+Bundle-Version: 1.0.0
+Git-Commit-Hash: ab430c1867721472f0f3f2f2919969c5c158f154
+Build-Image: 
+Build-Jdk: 1.8.0_331
+

+ 2 - 0
code/nckd-cosmic-debug/build/tmp/sourcesJar/MANIFEST.MF

@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+

+ 494 - 0
code/nckd-cosmic-debug/src/main/java/kd/cosmic/debug/tools/CosmicLauncher.java

@@ -0,0 +1,494 @@
+/**
+ * This is a kingdee cosmic template project that is automatically generated by the Kingdee cosmic development assistant plugin. 
+ * If there are any issues during the use process, you can provide feedback to the kingdee developer community website.
+ * Website: https://developer.kingdee.com/developer?productLineId=29
+ * Author: liebin.zheng
+ * Generate Date: 2025-04-09 17:34:20
+ */
+package kd.cosmic.debug.tools;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.ServerSocket;
+import java.util.Properties;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+
+import com.alibaba.dubbo.common.utils.NetUtils;
+
+import kd.bos.config.client.util.ConfigUtils;
+import kd.bos.service.bootstrap.Booter;
+
+/**
+ * cosmic服务启动器,含默认配置,如需更改请在DebugApplication中设置。
+ * 注:本工具类由开发助手自动生成,请不用直接修改本工具类。
+ */
+public final class CosmicLauncher {
+	
+	/**
+	 * 苍穹安装目录的环境变量名称(即苍穹依赖包和静态资源目录的上级目录)
+	 */
+	private static final String COSMIC_HOME = "COSMIC_HOME";
+	
+	/**
+	 * Gradle变量-Cosmic Home
+	 */
+	private static final String GRADLE_PROPERTIES_COSMIC_HOME = "systemProp.cosmic_home";
+	
+	/**
+     * 苍穹Gradle模板默认变量 - 默认的苍穹资源目录
+     */
+    private static final String DEFAULT_COSMIT_HOME_PATH = System.getProperty("user.home").replaceAll("\\\\", "/") + "/cosmic/home";
+	
+	private static final String PROJECT_HOME = "D:/work/ncgd/nckdSpace";
+	
+	private static final String LOCAL_IP = "127.0.0.1";
+	
+	public static String localHostName;
+	
+    private boolean setConfigUrl = false;
+
+    private int cosmicPort = 8881;
+    
+    private String cosmicUrl = "http://127.0.0.1:" + cosmicPort + "/ierp";
+    
+    /**
+     * 是否优先使用MC服务端的配置替代本地调试模板工程的部分默认配置
+     */
+    private boolean useMcServiceConfigFirst = false;
+    
+    public CosmicLauncher() {
+        setDefault();
+    }
+    
+    /**
+     * @param useMcServiceConfigFirst 是否优先使用MC服务端的配置替代本地调试模板工程的部分默认配置
+     */
+    public CosmicLauncher(boolean useMcServiceConfigFirst) {
+    	this.useMcServiceConfigFirst = useMcServiceConfigFirst;
+        setDefault();
+    }
+
+    public void setDefault() {
+    	
+        set("configAppName", "mservice,web");
+        set("webmserviceinone", "true");
+        set("file.encoding", "utf-8");
+        set("MONITOR_HTTP_PORT", "9998");
+        set("JMX_HTTP_PORT", "9091");
+        set("appSplit", "false");
+        set("tenant.code.type", "config");
+        
+        localHostName = getLocalHostName();
+        setClusterNumber("cosmic");
+        setTenantNumber("ierp");
+        setAppName("kdcosmic-" + localHostName + "-" + cosmicPort);
+        
+        setXdbEnable(false);
+        setSqlOut(true, true);
+        
+        setCosmicWebPort(cosmicPort);
+        setWebResPath(getCosmicHome() + "/static-file-service");
+        
+        //是否优先使用MC服务端的配置替代本地调试模板工程的部分默认配置
+		if (!useMcServiceConfigFirst) {
+			//当本地开发且连接轻量级环境时,可使用以下默认配置
+	        setConfigUrl("127.0.0.1:2181");
+	        setMcServerUrl("http://127.0.0.1:8090");
+	        setFsServerUrl("127.0.0.1", 8100);
+	        setImageServerUrl("127.0.0.1", 8100);
+	        
+//	        setEnableLightWeightDeploy(true);
+	        setDubboHostConfig(LOCAL_IP, 28888, 30880);
+//	        set("login.type", "STANDALONE");
+	        setMqConsumerRegister(false, null);
+		} else {
+			//当需要连接项目开发环境(即非轻量级环境)时,应以MC服务器上面的配置优先
+//			setEnableLightWeightDeploy(false);
+			setMqConsumerRegister(true, localHostName);
+		}
+		
+		setStartWithQing(false);
+        
+		//是否以轻量级环境启动苍穹服务
+        setEnableLightWeightDeploy(true);
+        
+        //本地日志配置
+        setLogConfig(false);
+        
+        //Dubbo服务注册配置
+        setDubboConfig(false, true, true);
+        
+    }
+
+    public void start() {
+//    	LOG.info("Cosmic Service starting! Please check url: {}", getCosmicUrl());
+    	Booter.main(null);
+    }
+
+    public void set(String key, String value) {
+        System.setProperty(key, value);
+    }
+
+    public String get(String key) {
+        return System.getProperty(key);
+    }
+
+    /**
+     * 设置苍穹服务器IP地址(包括MC、ZK、文件及图片服务)
+     * 不推荐使用该方法,项目开发时应该分别配置这几个服务地址,或者优先使用MC服务器上的配置。
+     */
+    @Deprecated
+    public void setServerIp(String ip) {
+        setMcServerUrl("http://" + ip + ":8090");
+        if (!setConfigUrl) {
+            setConfigUrl(ip + ":2181");
+        }
+        setFsServerUrl(ip, 8100);
+        setImageServerUrl(ip, 8100);
+    }
+
+    /**
+     * 设置MC服务地址
+     *
+     * @param mcServerUrl
+     */
+    public void setMcServerUrl(String mcServerUrl) {
+        set("mc.server.url", mcServerUrl);
+    }
+
+    /**
+     * @param configUrl 配置服务地址
+     */
+    public void setConfigUrl(String configUrl) {
+        set(ConfigUtils.CONFIG_URL_KEY, configUrl);
+        setConfigUrl = true;
+    }
+
+    /**
+     * 配置服务地址
+     *
+     * @param connectString zookeeper链接URL,如 127.0.0.1:2181
+     * @param user          用户
+     * @param password      密码
+     */
+    public void setConfigUrl(String connectString, String user, String password) {
+        if (user != null && password != null) {
+            setConfigUrl(connectString + "?user=" + user + "&password=" + password);
+        } else {
+            setConfigUrl(connectString);
+        }
+    }
+
+    /**
+     * @param clusterNumber 集群编码
+     */
+    public void setClusterNumber(String clusterNumber) {
+        set(ConfigUtils.CLUSTER_NAME_KEY, clusterNumber);
+    }
+
+
+    /**
+     * @param appName 本节点服务名称
+     */
+    public void setAppName(String appName) {
+        setAppName(appName, true);
+    }
+
+    public void setAppName(String appName, boolean alsoSetQueueTag) {
+        set(ConfigUtils.APP_NAME_KEY, appName);
+        if (alsoSetQueueTag) {
+            setQueueTag(appName);
+        }
+    }
+
+    public void setStartWithQing(boolean b) {
+        set("bos.app.special.deployalone.ids", b ? " " : "qing");
+    }
+
+    /**
+     * @param tenantNumber 租户编码
+     */
+    public void setTenantNumber(String tenantNumber) {
+        set("domain.tenantCode", tenantNumber);
+    }
+
+    /**
+     * @param enable 是否开启水平分表服务
+     */
+    public void setXdbEnable(boolean enable) {
+        set("xdb.enable", String.valueOf(enable));
+    }
+
+    /**
+     * @param tag 队列标记
+     */
+    public void setQueueTag(String tag) {
+        set("mq.debug.queue.tag", tag);
+    }
+
+    /**
+     * @param path web静态资源路径
+     */
+    public void setWebResPath(String path) {
+        set("JETTY_WEBRES_PATH", path);
+    }
+    
+    /**
+     * 控制台输出SQL开关
+     *
+     * @param outSql        是否输出SQL
+     * @param withParameter 是否输出参数
+     */
+    public void setSqlOut(boolean outSql, boolean withParameter) {
+        set("db.sql.out", String.valueOf(outSql));
+        set("db.sql.out.withParameter", String.valueOf(withParameter));
+    }
+
+    /**
+     * 设置苍穹服务端口
+     * @param port
+     */
+    public void setCosmicWebPort(int port) {
+    	this.cosmicPort = port;
+    	this.cosmicUrl = "http://127.0.0.1:" + cosmicPort + "/ierp";
+        set("JETTY_WEB_PORT", String.valueOf(cosmicPort));
+        set("domain.contextUrl", cosmicUrl);
+    }
+    
+    /**
+     * 设置是否注册为MQ消费者
+     * @param registerOnMq
+     * @param debbugTopic
+     */
+    public void setMqConsumerRegister(boolean registerOnMq, String debbugTopic) {
+    	set("mq.consumer.register", String.valueOf(registerOnMq));
+    	if(StringUtils.isNotBlank(debbugTopic)) {
+    		set("mq.debug.queue.tag", debbugTopic);
+    	}
+    }
+    
+    /**
+     * 设置文件服务地址
+     * @param ip
+     * @param port
+     */
+    public void setFsServerUrl(String ip, int port) {
+    	set("fileserver", "http://" + ip + ":" + port + "/fileserver/");
+    	set("attachmentServer.url", "http://" + ip + ":" + port + "/fileserver/");
+    	set("attachmentServer.inner.url", "http://" + ip + ":" + port + "/fileserver/");
+    }
+    
+    /**
+     * 设置图片服务地址
+     * @param ip
+     * @param port
+     */
+    public void setImageServerUrl(String ip, int port) {
+        set("imageServer.url", "http://" + ip + ":" + port + "/fileserver/");
+        set("imageServer.inner.url", "http://" + ip + ":" + port + "/fileserver/");
+    }
+
+    /**
+     * 获取苍穹服务URL
+     */
+	public String getCosmicUrl() {
+		return cosmicUrl;
+	}
+	
+	/**
+     * 设置webapp配置所在的目录
+     */
+	public void setWebAppPath(String path) {
+		set("JETTY_WEBAPP_PATH", path);
+	}
+	
+	/**
+	 * 是否以轻量级环境启动苍穹服务
+	 */
+	public void setEnableLightWeightDeploy(boolean enable) {
+		set("lightweightdeploy", String.valueOf(enable));
+		set("lightweightdeploy.services", "");
+		if(enable) {
+			set("tempfile.cachetype", "disk");
+			set("diskcache.path", System.getProperty("java.io.tmpdir") + File.separator + "cosmic_temp");
+			set("redismodelcache.enablelua", "false");
+		}
+	}
+
+	/**
+	 * Redis配置
+	 */
+	public void setRedisConfig(String redisUrl) {
+		set("redis.serversForCache", redisUrl);
+		set("redis.serversForSession", redisUrl);
+		set("algo.storage.redis.url", redisUrl);
+		set("redismodelcache.enablelua", String.valueOf(true));
+	}
+	
+	/**
+	 * MQ配置
+	 */
+	public void setMqHostConfig(String mqHost, String mqPort, String mqUser, String mqPassword, String mqVhost) {
+		String line = System.lineSeparator();
+		StringBuffer builder = new StringBuffer();
+		builder.append("type=rabbitmq").append(line).append("host=").append(mqHost).append(line).append("port=")
+				.append(mqPort).append(line).append("user=").append(mqUser).append(line).append("password=")
+				.append(mqPassword).append(line).append("vhost=").append(mqVhost);
+		set("mq.server", builder.toString());
+	}
+	
+	/**
+	 * 是否启用监控中心日志配置(是否将日志通过kafka上传到日志中心)</br>
+	 * 注:如需要启用,请先确保elk、kafka等服务已可用
+	 */
+	public void setLogConfig(boolean useMonitorLog) {
+//		String logConfigXmlContent = null;
+		String path = null;
+		if(useMonitorLog) {
+			//日志通过kafka上传到日志中心
+			path = "logback-kafka.xml";
+//			logConfigXmlContent = FileUtil.readUtf8String("classpath:logback-kafka.xml");
+		} else {
+			//本地日志配置
+			path = "logback.xml";
+//			logConfigXmlContent = FileUtil.readUtf8String("classpath:logback.xml");
+		}
+		String logConfigXmlContent = null;
+		InputStream is = null;
+		try {
+			is = getClass().getClassLoader().getResourceAsStream(path);
+			logConfigXmlContent = IOUtils.toString(is, "utf-8");
+//			logConfigXmlContent = new String(Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource(path).toURI())), "UTF-8");
+			set("log.config", logConfigXmlContent);
+			set("dubbo.application.logger", "slf4j");
+		} catch (Exception e) {
+			e.printStackTrace();
+		} finally {
+			try {
+				if(is != null) {
+					is.close();
+					is = null;
+				}
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+		}
+	}
+	
+	/**
+	 * Dubbo服务配置
+	 * 
+	 * @param registerProvider   是否向此注册中心注册服务,如果设为false,将只订阅,不注册
+	 * @param registerComsumer   是否向此注册中心订阅服务,如果设为false,将只注册,不订阅
+	 * @param lookupLocal   是否使用本地服务查找
+	 */
+	public void setDubboConfig(boolean registerProvider, boolean registerComsumer, boolean lookupLocal) {
+//		set("dubbo.registry.group", group);
+		set("dubbo.registry.register", String.valueOf(registerProvider));
+		set("dubbo.registry.subscribe", String.valueOf(registerComsumer));
+		//dubbo官方资料上没有支持lookupLocal配置,可能是平台扩展的功能,也可能是无效的配置
+        set("dubbo.service.lookup.local", String.valueOf(lookupLocal));
+//        set("dubbo.registry.protocol", "zookeeper");
+//        set("dubbo.registry.address", "");
+	}
+	
+	/**
+	 * Dubbo网络配置 
+	 * @param ip 默认127.0.0.1
+	 * @param port 默认28888
+	 * @param qingPort 默认30880
+	 */
+	public void setDubboHostConfig(String ip, int port, int qingPort) {
+		port = getAvailablePort(port);
+		qingPort = getAvailablePort(qingPort);
+		set("dubbo.protocol.port", String.valueOf(port));
+        set("dubbo.consumer.url", "dubbo://" + ip + ":" + port);
+        set("dubbo.consumer.url.qing", "dubbo://" + ip + ":" + qingPort);
+	}
+	
+    public int getAvailablePort(int port) {
+        try (ServerSocket serverSocket = new ServerSocket(port)) {
+            return port;
+        } catch (IOException e) {
+            return getAvailablePort(port+1);
+        }
+    }
+	
+//	/**
+//	 * 设置苍穹服务的中间件类型
+//	 * @param serverType
+//	 */
+//    public void setCosmicServerType(CosmicServerType serverType) {
+//    	if(serverType == CosmicServerType.springboot) {
+//    		set("mservice.booter.type", serverType.name());
+//    	} else {
+//    		set("webserver.type", serverType.name());
+//    	}
+//    }
+//    
+//    enum CosmicServerType{
+//    	jetty,tomcat,aas,springboot;
+//    }
+    
+//	private static String getLocalHostName() {
+//		InetAddress localhost = null;
+//		try {
+//			localhost = InetAddress.getLocalHost();
+//		} catch (UnknownHostException e) {
+//			e.printStackTrace();
+//		}
+//		return localhost == null ? "UnknownHost" : localhost.getHostAddress();
+//	}
+    
+    private static String getLocalHostName() {
+		return NetUtils.getLocalHost();
+	}
+	
+	public static String getCosmicHome(){
+        return getCosmicHome(PROJECT_HOME);
+    }
+	
+    public static String getCosmicHome(String projectPath){
+    	String cosmicHome = getCosmicGradleProp(projectPath, GRADLE_PROPERTIES_COSMIC_HOME);
+    	if(StringUtils.isBlank(cosmicHome)) {
+    		cosmicHome = System.getenv(COSMIC_HOME);
+    	}
+    	if(StringUtils.isBlank(cosmicHome)) {
+    		cosmicHome = DEFAULT_COSMIT_HOME_PATH;
+    	}
+        return cosmicHome;
+    }
+	
+    private static String getCosmicGradleProp(String projectPath, String key) {
+    	String gradleConfigPath = projectPath + "/gradle.properties";
+    	Properties prop = new Properties();
+    	FileReader fr = null;
+    	String value = null;
+    	try {
+    		File configFile = new File(gradleConfigPath);
+    		if(configFile.exists()) {
+    			fr = new FileReader(configFile);
+    			prop.load(fr);
+    			
+    			value = prop.getProperty(key);
+    		}
+		} catch (IOException e) {
+			e.printStackTrace();
+		} finally {
+			try {
+				if(fr != null) {
+					fr.close();
+					fr = null;
+				}
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+		}
+    	
+    	return value;
+    }
+}

+ 45 - 0
code/nckd-cosmic-debug/src/main/java/nckd/cosmic/debug/DebugApplication.java

@@ -0,0 +1,45 @@
+/**
+ * This is a kingdee cosmic template project that is automatically generated by the Kingdee cosmic development assistant plugin. 
+ * If there are any issues during the use process, you can provide feedback to the kingdee developer community website.
+ * Website: https://developer.kingdee.com/developer?productLineId=29
+ * Author: liebin.zheng
+ * Generate Date: 2025-04-09 17:34:20
+ */
+package nckd.cosmic.debug;
+
+import kd.cosmic.debug.tools.CosmicLauncher;
+
+/**
+ * 启动本地应用程序(微服务节点)
+ */
+public class DebugApplication {
+	
+	
+
+    public static void main(String[] args) {
+    	
+//    	Thread.currentThread().setContextClassLoader(new KDSecurityClassLoader(Thread.currentThread().getContextClassLoader()));
+    	
+        CosmicLauncher cosmic = new CosmicLauncher(false);
+
+        cosmic.setClusterNumber("gdjt-sit");
+        cosmic.setTenantNumber("gdjt-sit");
+        
+//        cosmic.setConfigUrl("127.0.0.1:2181?user=zk&password=xxx");
+        cosmic.setConfigUrl("10.1.128.150:2181?user=zookeeper&password=d@f*g:SGVsbG8==kDH33hzGBbCCFAiKSv3MbDxOYA/UqBPkz1ViZtFEy5OAa2RwYXNzd29yZA==");
+        
+//        cosmic.setMcServerUrl("http://127.0.0.1:8090");
+        cosmic.setMcServerUrl("http://10.1.128.150:8090/"); 
+        //cosmic.set("KFilterConfigFiles.config","code/sys/nckd-nc2kd-sys/src/main/resources/filterXml/PlatFilter.xml");
+//        cosmic.setFsServerUrl("127.0.0.1", 8100);
+//        cosmic.setImageServerUrl("127.0.0.1", 8100);
+        System.setProperty("PLATURL","http://223.84.144.55:11800/ncplat");
+
+        //自定义本地苍穹调试服务的端口
+        cosmic.setCosmicWebPort(8080);
+//        cosmic.setDubboConfig(false, true, true);
+        cosmic.start();
+        
+        
+    }
+}

+ 63 - 0
code/nckd-cosmic-debug/src/main/resources/logback-kafka.xml

@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+This is a kingdee cosmic template project that is automatically generated by the Kingdee cosmic development assistant plugin. 
+If there are any issues during the use process, you can provide feedback to the kingdee developer community website.
+Website: https://developer.kingdee.com/developer?productLineId=29
+Author: liebin.zheng
+Generate Date: generate_date
+ -->
+<configuration>
+	
+	<property name="LOG_DIR" value="logs"/>
+	<property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %5p ${PID:- } --- [%t] %-40.40logger{39} : %m%n"/>
+
+	<logger name="org.apache.catalina.startup.DigesterFactory" level="ERROR"/>
+	<logger name="org.apache.catalina.util.LifecycleBase" level="ERROR"/>
+	<logger name="org.apache.coyote.http11.Http11NioProtocol" level="WARN"/>
+	<logger name="org.apache.sshd.common.util.SecurityUtils" level="WARN"/>
+	<logger name="org.apache.tomcat.util.net.NioSelectorPool" level="WARN"/>
+	<logger name="org.eclipse.jetty.util.component.AbstractLifeCycle" level="ERROR"/>
+	<logger name="org.hibernate.validator.internal.util.Version" level="WARN"/>
+	<logger name="org.springframework.boot.actuate.endpoint.jmx" level="WARN"/>
+	
+    <logger name="kd.bos.dc.utils.AccountUtils" level="WARN"/>
+    <logger name="kd.bos.license" level="WARN"/>
+    <logger name="org.apache.zookeeper" level="WARN"/>
+    <logger name="kd.bos.portal.pluginnew" level="WARN" />
+    
+	<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+		<encoder>
+			<pattern>${LOG_PATTERN}</pattern>
+		</encoder>
+	</appender>
+	<!-- 
+	<appender name="FILE"
+		class="ch.qos.logback.core.rolling.RollingFileAppender">
+		<encoder>
+			<pattern>${LOG_PATTERN}</pattern>
+		</encoder>
+		<file>${LOG_DIR}/cosmic_out.log</file>
+		<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+			<cleanHistoryOnStart>false</cleanHistoryOnStart>
+			<fileNamePattern>${LOG_DIR}/cosmic_out_%d{yyyyMMdd}_%i.log</fileNamePattern>
+			<maxFileSize>10MB</maxFileSize>
+			<maxHistory>7</maxHistory>
+			<totalSizeCap>0</totalSizeCap>
+		</rollingPolicy>
+	</appender>
+	 -->
+	<appender name="kafka" class="kd.bos.logging.console.slf4j.logback.KafkaAppender">
+        <topic>{{clusterName}}-log</topic>
+        <brokerList>{{log.kafka.ip_port}}</brokerList>
+        <compressionType>none</compressionType>
+        <syncSend>false</syncSend>
+        <keySerializerClass>org.apache.kafka.common.serialization.StringSerializer</keySerializerClass>
+        <valueSerializerClass>org.apache.kafka.common.serialization.StringSerializer</valueSerializerClass>
+    </appender>
+	
+	<root level="INFO">
+		<appender-ref ref="CONSOLE" />
+		<appender-ref ref="kafka" />
+	</root>
+
+</configuration>

+ 63 - 0
code/nckd-cosmic-debug/src/main/resources/logback.xml

@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+This is a kingdee cosmic template project that is automatically generated by the Kingdee cosmic development assistant plugin. 
+If there are any issues during the use process, you can provide feedback to the kingdee developer community website.
+Website: https://developer.kingdee.com/developer?productLineId=29
+Author: liebin.zheng
+Generate Date: generate_date
+ -->
+<configuration>
+	
+	<property name="LOG_DIR" value="logs"/>
+	<property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %5p ${PID:- } --- [%t] %-40.40logger{39} : %m%n"/>
+
+	<logger name="org.apache.catalina.startup.DigesterFactory" level="ERROR"/>
+	<logger name="org.apache.catalina.util.LifecycleBase" level="ERROR"/>
+	<logger name="org.apache.coyote.http11.Http11NioProtocol" level="WARN"/>
+	<logger name="org.apache.sshd.common.util.SecurityUtils" level="WARN"/>
+	<logger name="org.apache.tomcat.util.net.NioSelectorPool" level="WARN"/>
+	<logger name="org.eclipse.jetty.util.component.AbstractLifeCycle" level="ERROR"/>
+	<logger name="org.hibernate.validator.internal.util.Version" level="WARN"/>
+	<logger name="org.springframework.boot.actuate.endpoint.jmx" level="WARN"/>
+	
+    <logger name="kd.bos.dc.utils.AccountUtils" level="WARN"/>
+    <logger name="kd.bos.license" level="WARN"/>
+    <logger name="org.apache.zookeeper" level="INFO"/>
+    <logger name="kd.bos.portal.pluginnew" level="WARN" />
+
+	<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+		<encoder>
+			<pattern>${LOG_PATTERN}</pattern>
+		</encoder>
+	</appender>
+
+	<appender name="FILE"
+		class="ch.qos.logback.core.rolling.RollingFileAppender">
+		<encoder>
+			<pattern>${LOG_PATTERN}</pattern>
+		</encoder>
+		<file>${LOG_DIR}/cosmic_out.log</file>
+		<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+			<cleanHistoryOnStart>false</cleanHistoryOnStart>
+			<fileNamePattern>${LOG_DIR}/cosmic_out_%d{yyyyMMdd}_%i.log</fileNamePattern>
+			<maxFileSize>10MB</maxFileSize>
+			<maxHistory>7</maxHistory>
+			<totalSizeCap>0</totalSizeCap>
+		</rollingPolicy>
+	</appender>
+	<!-- 
+	<appender name="kafka" class="kd.bos.logging.console.slf4j.logback.KafkaAppender">
+        <topic>{{clusterName}}-log</topic>
+        <brokerList>{{log.kafka.ip_port}}</brokerList>
+        <compressionType>none</compressionType>
+        <syncSend>false</syncSend>
+        <keySerializerClass>org.apache.kafka.common.serialization.StringSerializer</keySerializerClass>
+        <valueSerializerClass>org.apache.kafka.common.serialization.StringSerializer</valueSerializerClass>
+    </appender>
+	 -->
+	<root level="INFO">
+		<appender-ref ref="CONSOLE" />
+		<appender-ref ref="FILE" />
+	</root>
+
+</configuration>

+ 0 - 0
code/nckd-cosmic-debug/src/test/java/nckd/cosmic/debug/test/.gitkeep


+ 0 - 0
code/nckd-cosmic-debug/src/test/resources/.gitkeep


+ 14 - 0
code/sys/nckd-nc2kd-sys/build.gradle

@@ -0,0 +1,14 @@
+/*
+ * This is a kingdee cosmic template project that is automatically generated by the Kingdee cosmic development assistant plugin. 
+ * If there are any issues during the use process, you can provide feedback to the kingdee developer community website.
+ * Website: https://developer.kingdee.com/developer?productLineId=29
+ * Author: liebin.zheng
+ * Generate Date: 2025-04-09 17:34:20
+ */
+
+dependencies {
+	api project(':nckd-nc2kd-base-common')
+	api project(':nckd-nc2kd-base-helper')
+} 
+
+

BIN
code/sys/nckd-nc2kd-sys/build/classes/java/main/nckd/nc2kd/sys/webapi/common/HttpJwt.class


BIN
code/sys/nckd-nc2kd-sys/build/classes/java/main/nckd/nc2kd/sys/webapi/common/JwtTokenValidator.class


BIN
code/sys/nckd-nc2kd-sys/build/classes/java/main/nckd/nc2kd/sys/webapi/common/JwtUtil.class


BIN
code/sys/nckd-nc2kd-sys/build/classes/java/main/nckd/nc2kd/sys/webapi/common/TokenHelper.class


BIN
code/sys/nckd-nc2kd-sys/build/classes/java/main/nckd/nc2kd/sys/webapi/common/ValidJwt.class


BIN
code/sys/nckd-nc2kd-sys/build/classes/java/main/nckd/nc2kd/sys/webapi/sso/ThirdSSOAuthHandlerOA.class


BIN
code/sys/nckd-nc2kd-sys/build/classes/java/main/nckd/nc2kd/sys/webapi/webapi/PlatPersistenceFilter.class


BIN
code/sys/nckd-nc2kd-sys/build/libs/nckd-nc2kd-sys-1.0.0-sources.jar


BIN
code/sys/nckd-nc2kd-sys/build/libs/nckd-nc2kd-sys-1.0.0.jar


+ 11 - 0
code/sys/nckd-nc2kd-sys/build/resources/main/filterXml/PlatFilter.xml

@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app >
+    <filter>
+        <filter-name>platFilter</filter-name>
+        <filter-class>nckd.nc2kd.sys.webapi.webapi.PlatPersistenceFilter</filter-class>
+        <filter-order>49999</filter-order>
+        <filter-mapping>
+            <url-pattern>/oaLogin.html</url-pattern>
+        </filter-mapping>
+    </filter>
+</web-app>

+ 0 - 0
code/sys/nckd-nc2kd-sys/build/resources/test/.gitkeep


BIN
code/sys/nckd-nc2kd-sys/build/tmp/compileJava/previous-compilation-data.bin


+ 16 - 0
code/sys/nckd-nc2kd-sys/build/tmp/jar/MANIFEST.MF

@@ -0,0 +1,16 @@
+Manifest-Version: 1.0
+Jar-Id: 
+Project-Name: nckd-nc2kd-sys
+Build-Tool: Gradle 7.6.3
+Build-Date: 2025-04-15 19:38:26
+Built-By: Kingdee Cosmic Developer Tools
+Build-Num: 20250415193826505
+App-Name: 
+Git-Branch: master
+Cloud-Name: 
+Group-Name: nckd.cosmic
+Bundle-Version: 1.0.0
+Git-Commit-Hash: ab430c1867721472f0f3f2f2919969c5c158f154
+Build-Image: 
+Build-Jdk: 1.8.0_331
+

+ 2 - 0
code/sys/nckd-nc2kd-sys/build/tmp/sourcesJar/MANIFEST.MF

@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+

+ 0 - 0
code/sys/nckd-nc2kd-sys/src/main/java/nckd/nc2kd/sys/webapi/business/.gitkeep


+ 77 - 0
code/sys/nckd-nc2kd-sys/src/main/java/nckd/nc2kd/sys/webapi/common/HttpJwt.java

@@ -0,0 +1,77 @@
+package nckd.nc2kd.sys.webapi.common;
+
+
+import net.sf.json.JSONObject;
+import org.apache.http.HttpEntity;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.util.EntityUtils;
+
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+public class HttpJwt {
+    /**
+     * post 请求
+     *
+     * @param jsonStr
+     * @param url
+     * @return
+     */
+    @SuppressWarnings("finally")
+    public static Map sendPost(String jsonStr, String url) {
+        Map<String, String> resultMap = new HashMap<String, String>();
+        HttpPost httpPost = new HttpPost(url);
+        CloseableHttpResponse httpResponse = null;
+        JSONObject responseBody = null;
+        String result = "";
+        CloseableHttpClient httpClient = HttpClients.createDefault();
+        try {
+            RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(5000)
+                    .setConnectionRequestTimeout(10000).setSocketTimeout(10000).build();// TODO
+            httpPost.setConfig(requestConfig);
+            httpPost.setHeader("Content-type", "application/json");
+            httpPost.setHeader("DataEncoding", "UTF-8");
+            httpPost.setEntity(new StringEntity(jsonStr));
+            httpResponse = httpClient.execute(httpPost);
+            result = String.valueOf(httpResponse.getStatusLine());
+            HttpEntity entity = httpResponse.getEntity();
+            String resultd = EntityUtils.toString(httpResponse.getEntity());// 返回json格式:
+            responseBody = JSONObject.fromObject(resultd);
+            result = responseBody.getString("status");
+            resultMap.put("code", String.valueOf(httpResponse.getStatusLine().getStatusCode()));
+            resultMap.put("result", result);
+        } catch (ClientProtocolException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            if (e.getMessage().endsWith("connect timed out")) {
+                result = "连接超时";
+            }
+            e.printStackTrace();
+        } finally {
+            if (httpResponse != null) {
+                try {
+                    httpResponse.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+            if (httpClient != null) {
+                try {
+                    httpClient.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+
+        }
+        return resultMap;
+    }
+}

+ 72 - 0
code/sys/nckd-nc2kd-sys/src/main/java/nckd/nc2kd/sys/webapi/common/JwtTokenValidator.java

@@ -0,0 +1,72 @@
+package nckd.nc2kd.sys.webapi.common;
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.io.Decoder;
+import io.jsonwebtoken.io.Decoders;
+import net.sf.json.JSONObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import java.nio.charset.StandardCharsets;
+import java.security.PublicKey;
+import java.util.Base64;
+import java.util.List;
+import java.util.Map;
+public class JwtTokenValidator {
+    private static Logger logger = LoggerFactory.getLogger(JwtTokenValidator.class);
+
+    public Map validateToken(String sessionToken) {
+        String issuer;
+        String  audience="JDCW";//这是对接系统的appCode 与4.1.2的appCode 是同一个
+        boolean isSuperAdmin;
+        try {
+            if(sessionToken==null){
+                return JwtUtil.returnMsg("-1", "jwt 为空");//不用抛到页面提示
+            }
+            Decoder<String, byte[]> base64UrlDecoder = Decoders.BASE64URL;
+            byte[] bytes = base64UrlDecoder.decode(sessionToken.split("\\.")[1]);
+            String payload = new String(bytes, StandardCharsets.UTF_8);
+            JSONObject jsonObj = JSONObject.fromObject(payload);
+            isSuperAdmin=Boolean.parseBoolean((String) jsonObj.get("isSuperAdmin"));
+             List<String>  listAppCode=(List<String>) jsonObj.get("appCodeList");
+
+
+
+// audience 是对接系统自己的appCode即系统简称 需要注册到服务平台,确认了就不用变动 //audience 自己维护好。
+            if(!isSuperAdmin) {//如果是超级管理员允许登录,否则以下就要验证权限
+                if(!listAppCode.contains(audience.toUpperCase())) {//没权限时 ,需要系统提示
+                    return JwtUtil.returnMsg("9", "无权访问该系统"); //系统给出页面提示
+                }
+            }
+            logger.info("目标系统 appCode :[" + audience + "]");
+        }catch (Throwable th){
+            return JwtUtil.returnMsg("-1", "签发者获取异常");
+        }
+        //获取公钥;
+         // 注意;以下逻辑 如果是非平台的框架请使用4.1.10 示例
+        //PublicKey publicKey = keyPairLocator.getPublic(audience);//这段代码是获取公钥,
+        PublicKey publicKey=ValidJwt.getPublic();
+        //非平台架构参考4.1.10  getpublic() 方法 获取, 以下逻辑不变
+        if(publicKey == null){
+            if (logger.isDebugEnabled()) {
+                logger.debug("无法获取系统[" + audience + "]的公钥");
+            }
+            return JwtUtil.returnMsg("-1", "公钥获取失败");
+        }
+        Claims claims=null;
+        try {
+
+            claims = Jwts.parser().setSigningKey(publicKey)
+                    .parseClaimsJws(sessionToken).getBody();
+            claims.put("status","0");
+            claims.put("msg","success");
+        } catch (Exception e) {
+            if(e.getLocalizedMessage().endsWith("milliseconds.")) {
+                return JwtUtil.returnMsg("-1", "Token time out");
+            }else {
+                return JwtUtil.returnMsg("-1", "Token 验证失败");
+            }
+        }
+        return claims;
+    }
+
+}

+ 43 - 0
code/sys/nckd-nc2kd-sys/src/main/java/nckd/nc2kd/sys/webapi/common/JwtUtil.java

@@ -0,0 +1,43 @@
+package nckd.nc2kd.sys.webapi.common;
+
+
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashMap;
+import java.util.Map;
+
+
+public class JwtUtil {
+    private static Logger logger = LoggerFactory.getLogger(JwtUtil.class);
+    private static JwtTokenValidator jwtTokenValidator;
+
+    public final static String ATTR_JWT_MAP = "jwt_map";
+    public final static String JWT_HEADER = "iplat-jwt";
+    public final static String USERNAME_KEY = "sub";
+    public final static String JWT_SOURCE = "jwt-source";
+    public final static String JWT_SOURCE_HEADER = "header";
+
+    public static JwtTokenValidator getJwtTokenValidator() {
+        if(jwtTokenValidator == null) {
+            setJwtTokenValidator();
+        }
+        return jwtTokenValidator;
+    }
+    private static void setJwtTokenValidator() {
+        //jwtTokenValidator=PlatApplicationContext.getBean("jwtTokenValidator", JwtTokenValidator.class);
+        jwtTokenValidator=new JwtTokenValidator();
+    }
+
+/*
+ //    * 验证返回值处理*/
+
+
+    public static Map returnMsg(String status, String msg) {
+        Map<String,String> result=new HashMap<>();
+        result.put("status", status);
+        result.put("msg", msg);
+        return result;
+    }
+}

+ 101 - 0
code/sys/nckd-nc2kd-sys/src/main/java/nckd/nc2kd/sys/webapi/common/TokenHelper.java

@@ -0,0 +1,101 @@
+package nckd.nc2kd.sys.webapi.common;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import nckd.nc2kd.base.common.utils.HttpRequestUtils;
+import org.springframework.util.StringUtils;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class TokenHelper {
+    private static final String KEY_GETAPPTOKEN = "/api/getAppToken.do";
+
+    private static final String KEY_LOGIN = "/api/login.do";
+
+    private static final String PLATURLKEY="PLATURL";
+    private  static final String DOMAIN_CONTEXT_URL = "domain.contextUrl";
+    /**
+     * 获取苍穹AccessToken
+     *
+     * @param userNum 账号
+     * @param usertype 账号类型
+     * @return
+     */
+    public static String getCQToken(String userNum, String usertype) {
+        String accessToken = "";
+        String appTokenUrl = System.getProperty(DOMAIN_CONTEXT_URL) + KEY_GETAPPTOKEN;
+        String accessTokenUrl = System.getProperty(DOMAIN_CONTEXT_URL)+ KEY_LOGIN;
+        String appId ="oa";
+        String appSecret = "QWERTYUIOp1234567890/*-";
+        String tenantId = "gdjt-sit";
+        String accountId = "2159456356011082752";
+        String appToken = getAppToken(appTokenUrl, appId, appSecret, tenantId, accountId);
+        if (StringUtils.hasText(appToken)) {
+            accessToken = getAccessToken(accessTokenUrl, appToken, userNum, tenantId, accountId, usertype);
+        }
+        return accessToken;
+    }
+
+    /**
+     * 获取AppToken -- 内部使用
+     *
+     * @param appTokenURL AppToken接口
+     * @param appId 第三方应用编码
+     * @param appSecret AccessToken加密认证秘钥
+     * @param tenantId 租户ID
+     * @param accountId 数据中心(默认数据中心)
+     * @return
+     */
+    public static String getAppToken(String appTokenURL, String appId, String appSecret, String tenantId, String accountId) {
+        String appToken = "";
+        Map<String, Object> body = new HashMap<>();//body集合
+        body.put("appId", appId);//第三方应用编码
+        body.put("appSecret", appSecret);//AccessToken加密认证秘钥
+        body.put("tenantId", tenantId);//租户ID
+        body.put("accountId", accountId);//数据中心(默认数据中心)
+        String res = null;
+        res = HttpRequestUtils.post(appTokenURL, null, JSON.toJSONString(body));
+        JSONObject response = JSON.parseObject(res);
+        if ("success".equalsIgnoreCase(response.getString("state"))) {
+            JSONObject responseData = response.getJSONObject("data");
+            if (responseData != null && StringUtils.hasText(responseData.getString("app_token"))) {
+                appToken = responseData.getString("app_token");
+            }
+        }
+
+        return appToken;
+    }
+    /**
+     * 获取AccessToken -- 内部使用
+     *
+     * @param accessTokenURL AccessToken接口
+     * @param appToken AppToken
+     * @param userNum 苍穹用户账号
+     * @param tenantId 租户ID
+     * @param accountId 数据中心(默认数据中心)
+     * @param usertype 用户类型
+     * @return
+     */
+    public static String getAccessToken(String accessTokenURL, String appToken, String userNum, String tenantId, String accountId, String usertype) {
+        String accessToken = "";
+        Map<String, Object> body = new HashMap<>();//body集合
+        body.put("user", userNum);//苍穹用户账号
+        body.put("apptoken", appToken);//appToken
+        body.put("tenantId", tenantId);//租户ID
+        body.put("accountId", accountId);//数据中心(默认数据中心)
+        body.put("usertype", usertype);
+        String res = null;
+        res = HttpRequestUtils.post(accessTokenURL, null, JSON.toJSONString(body));
+        if (StringUtils.hasText(res)) {
+            JSONObject response = JSON.parseObject(res);
+            if ("success".equalsIgnoreCase(response.getString("state"))) {
+                JSONObject responseData = response.getJSONObject("data");
+                if (responseData != null && StringUtils.hasText(responseData.getString("access_token"))) {
+                    accessToken = responseData.getString("access_token");
+                }
+            }
+        }
+        return accessToken;
+    }
+}

+ 29 - 0
code/sys/nckd-nc2kd-sys/src/main/java/nckd/nc2kd/sys/webapi/common/ValidJwt.java

@@ -0,0 +1,29 @@
+package nckd.nc2kd.sys.webapi.common;
+
+import javax.xml.bind.DatatypeConverter;
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.PublicKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.X509EncodedKeySpec;
+public class  ValidJwt {
+    public static PublicKey getPublic(){
+        PublicKey publicKey=null;
+        String publicKeyStr="MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsHALqvw9cFBKb6KG0WC/swMyOQY+c39lPvYbt/mTIb6a31rYux29M3klYidXEnC3YN22qaasJYZzh0frV/YPD0wbY8rAtognVKXr0wSBGW875HoGGntGCTkonp5D5L6se1kyEz6rQ+ZxWE8MgFH5Enq6T6rR0oE59M+7LH4BeVFazB7Wtf2pNceAEvEJcV1NeY77DUnTO1ibkqo+J7QwfYp0AvIviHuQudvlynp2mQSYaZ4k87CxqT9W68g48qswTlhbBtaWWqkJBysUjD9JVF/CQJB87327ygIGrCijNXaqR2yYY42EPl0mqVq0neZukF3n/cSHf5ZIAi9YMKPkvQIDAQAB";
+        byte [] decoded = DatatypeConverter.parseBase64Binary(publicKeyStr);
+        X509EncodedKeySpec spec =
+                new X509EncodedKeySpec(decoded);
+        KeyFactory kf = null;
+        try {
+            kf = KeyFactory.getInstance("RSA");
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+        }
+        try {
+            publicKey=  kf.generatePublic(spec);
+        } catch (InvalidKeySpecException e) {
+            e.printStackTrace();
+        }
+        return  publicKey;
+    }
+}

+ 113 - 0
code/sys/nckd-nc2kd-sys/src/main/java/nckd/nc2kd/sys/webapi/sso/ThirdSSOAuthHandlerOA.java

@@ -0,0 +1,113 @@
+package nckd.nc2kd.sys.webapi.sso;
+
+import com.alibaba.fastjson.JSONObject;
+import kd.bos.exception.KDBizException;
+import kd.bos.logging.Log;
+import kd.bos.logging.LogFactory;
+import kd.bos.login.thirdauth.UserAuthResult;
+import kd.bos.login.thirdauth.UserProperType;
+import nckd.nc2kd.sys.webapi.common.HttpJwt;
+import nckd.nc2kd.sys.webapi.common.JwtUtil;
+import org.apache.commons.lang3.StringUtils;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import java.io.IOException;
+
+import java.util.Map;
+public class ThirdSSOAuthHandlerOA implements kd.bos.login.thirdauth.ThirdSSOAuthHandler {
+    private  final String DOMAIN_CONTEXT_URL = "domain.contextUrl";
+    private final String appCode="JDCW";
+    private final String GETCOOKIE="getTokenFromCookie";
+    private final String PLATURLKEY="PLATURL";
+    public static final Log log= LogFactory.getLog(ThirdSSOAuthHandlerOA.class);
+    @Override
+    public void callTrdSSOLogin(HttpServletRequest req, HttpServletResponse res, String s) {
+
+    }
+
+    @Override
+    public UserAuthResult getTrdSSOAuth(HttpServletRequest req, HttpServletResponse res) {
+        if( req.getRequestURI().endsWith("login.html")){
+            return null;
+        };
+        UserAuthResult authResultresult=new UserAuthResult();
+        authResultresult.setSucess(false);
+        try {
+            HttpSession session = ((HttpServletRequest) req).getSession();
+            /*
+             *第1步:从请求连接获取token并存放到session 中*/
+            String token = req.getParameter("token");
+            if (StringUtils.isNotEmpty(token)) {
+                session.setAttribute("token", token);
+            }
+            /*
+             * 2.本地地址和平台地址的拼装获取*/
+
+            String URLPath = System.getProperty(PLATURLKEY)+"/"+GETCOOKIE+"?appCode=" + appCode + "&returnUrl="+ System.getProperty(DOMAIN_CONTEXT_URL)+"/index.html";
+               if (session.getAttribute("userName") == null && StringUtils.isEmpty(token)) {
+                   ((HttpServletResponse) res).sendRedirect(URLPath);
+                   return null;
+               }
+
+            /**
+             * 3.从session 中获取token*/
+
+
+            String sessionToken = (String) session.getAttribute("token");
+            JSONObject jsonObject = new JSONObject();
+            jsonObject.put("token", sessionToken);
+            String jsonToken = sessionToken == null ? "" : jsonObject.toString();
+//*
+//         * 4.将session 获取的token 去调用基础平台api判断是否注销状态 如果为“F”为注销状态,则注销sessiion
+//         * 重定向到本地请求地址
+
+
+            String checkOutUrl = System.getProperty(PLATURLKEY)+"/checkTokenIsOut";// 平台判断token是否已经被注销地址
+            if (StringUtils.isNotEmpty(jsonToken)) {
+                Map<String, String> resultMap = HttpJwt.sendPost(jsonToken, checkOutUrl);
+                if ("200".equals(resultMap.get("code")) && "F".equals(resultMap.get("result"))) {
+                    session.invalidate();//注销系统
+                    ((HttpServletResponse) res).sendRedirect(System.getProperty(DOMAIN_CONTEXT_URL));//进入对接系统首页地址
+                    return null;
+                }
+            }
+            Map result = validJwtFromRequest((HttpServletRequest) req, (HttpServletResponse) res, sessionToken);
+            if (StringUtils.isNotEmpty(token) && !"0".equals(result.get("status"))) {
+                String sendUrl = System.getProperty(PLATURLKEY)+ "/clearCookie"+"?appCode=" + appCode + "&returnUrl="+ System.getProperty(DOMAIN_CONTEXT_URL)+"/index.html";
+                if ("9".equals(result.get("status"))) {//无权限时提示到页面
+                    authResultresult.setSucess(false);
+                    authResultresult.setErrDesc("对不起,您无权限访问{金蝶系统}!请联系管理员!");
+                }
+                session.invalidate();//注销系统
+                ((HttpServletResponse) res).sendRedirect(sendUrl);
+                return  authResultresult;
+            }
+            else{
+
+                Object userObj= result.get("sub");
+                session.setAttribute("userName",userObj);
+                if(userObj!=null) {
+                    authResultresult.setUserType(UserProperType.UserName);
+                    authResultresult.setUser(userObj.toString());
+                    authResultresult.setSucess(true);
+
+                }
+                return authResultresult;
+            }
+        }
+        catch (IOException e) {
+            throw new KDBizException(e.getMessage());
+        }
+
+    }
+    // 验证jwt
+    private Map validJwtFromRequest(HttpServletRequest req, HttpServletResponse res, String sessionToken) {
+        Map result = null;
+        try {
+            result = JwtUtil.getJwtTokenValidator().validateToken(sessionToken);
+        } catch (Exception e) {
+        }
+        return result;
+    }
+}

+ 89 - 0
code/sys/nckd-nc2kd-sys/src/main/java/nckd/nc2kd/sys/webapi/webapi/PlatPersistenceFilter.java

@@ -0,0 +1,89 @@
+package nckd.nc2kd.sys.webapi.webapi;
+
+import com.alibaba.fastjson.JSONObject;
+
+import nckd.nc2kd.sys.webapi.common.HttpJwt;
+import nckd.nc2kd.sys.webapi.common.JwtUtil;
+import nckd.nc2kd.sys.webapi.common.TokenHelper;
+import org.apache.commons.lang3.StringUtils;
+
+import javax.servlet.*;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Map;
+
+public class PlatPersistenceFilter implements  Filter{
+    private final String appCode="JDCW";
+    private final String GETCOOKIE="getTokenFromCookie";
+    private final String PLATURLKEY="PLATURL";
+    private  final String DOMAIN_CONTEXT_URL = "domain.contextUrl";
+    @Override
+    public void init(FilterConfig filterConfig) throws ServletException {
+
+        Filter.super.init(filterConfig);
+    }
+
+    @Override
+    public void doFilter(ServletRequest req, ServletResponse res, FilterChain filterChain) throws IOException, ServletException {
+        HttpSession session = ((HttpServletRequest) req).getSession();
+/*
+         *第1步:从请求连接获取token并存放到session 中*/
+
+        String token = req.getParameter("token");
+        if (StringUtils.isNotEmpty(token)) {
+            session.setAttribute("token", token);
+        }
+        /*
+         * 2.本地地址和平台地址的拼装获取*/
+
+
+        String url = ((HttpServletRequest) req).getRequestURI();
+        //String localUrl="http://localhost:8080/ierp/oalogin.html";//进入对接系统主页的地址
+       // appCode 是对接系统代码简称,与对接人定义好后必须注册到基础平台系统,和门户系统(系统主页地址也要注册到门户)。
+      // 验证服务平台的访问地址+本系统的请求地址
+        String URLPath = System.getProperty(PLATURLKEY)+"/"+GETCOOKIE+"?appCode=" + appCode + "&returnUrl="+ System.getProperty(DOMAIN_CONTEXT_URL)+"/oaLogin.html";
+        if(session.getAttribute("userName")==null&&StringUtils.isEmpty(token)) {
+            ((HttpServletResponse) res).sendRedirect(URLPath);
+            return;
+        }
+
+
+        String sessionToken = (String) session.getAttribute("token");
+        JSONObject jsonObject = new JSONObject();
+        jsonObject.put("token", sessionToken);
+        String jsonToken = sessionToken == null ? "" : jsonObject.toString();
+//*
+//         * 4.将session 获取的token 去调用基础平台api判断是否注销状态 如果为“F”为注销状态,则注销sessiion
+//         * 重定向到本地请求地址
+
+
+        String checkOutUrl = System.getProperty(PLATURLKEY)+"/checkTokenIsOut";// 平台判断token是否已经被注销地址
+        if (StringUtils.isNotEmpty(jsonToken)) {
+            Map<String, String> resultMap = HttpJwt.sendPost(jsonToken, checkOutUrl);
+            if ("200".equals(resultMap.get("code")) && "F".equals(resultMap.get("result"))) {
+                session.invalidate();//注销系统
+                ((HttpServletResponse) res).sendRedirect(System.getProperty(DOMAIN_CONTEXT_URL));//进入对接系统首页地址
+                return;
+            }
+        }
+
+       filterChain.doFilter(req,res);
+    }
+
+    // 验证jwt
+    private Map validJwtFromRequest(HttpServletRequest req, HttpServletResponse res, String sessionToken) {
+        Map result = null;
+        try {
+            result = JwtUtil.getJwtTokenValidator().validateToken(sessionToken);
+        } catch (Exception e) {
+        }
+        return result;
+    }
+    @Override
+    public void destroy() {
+        Filter.super.destroy();
+    }
+}

+ 11 - 0
code/sys/nckd-nc2kd-sys/src/main/resources/filterXml/PlatFilter.xml

@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app >
+    <filter>
+        <filter-name>platFilter</filter-name>
+        <filter-class>nckd.nc2kd.sys.webapi.webapi.PlatPersistenceFilter</filter-class>
+        <filter-order>49999</filter-order>
+        <filter-mapping>
+            <url-pattern>/oaLogin.html</url-pattern>
+        </filter-mapping>
+    </filter>
+</web-app>

+ 0 - 0
code/sys/nckd-nc2kd-sys/src/test/java/nckd/sys/webapi/business/test/.gitkeep


+ 0 - 0
code/sys/nckd-nc2kd-sys/src/test/java/nckd/sys/webapi/common/test/.gitkeep


+ 0 - 0
code/sys/nckd-nc2kd-sys/src/test/java/nckd/sys/webapi/mservice/test/.gitkeep


+ 0 - 0
code/sys/nckd-nc2kd-sys/src/test/java/nckd/sys/webapi/plugin/test/.gitkeep


+ 0 - 0
code/sys/nckd-nc2kd-sys/src/test/java/nckd/sys/webapi/report/test/.gitkeep


+ 0 - 0
code/sys/nckd-nc2kd-sys/src/test/java/nckd/sys/webapi/webapi/test/.gitkeep


+ 0 - 0
code/sys/nckd-nc2kd-sys/src/test/resources/.gitkeep


+ 45 - 0
config.gradle

@@ -0,0 +1,45 @@
+/**
+ * This is a kingdee cosmic template project that is automatically generated by the Kingdee cosmic development assistant plugin. 
+ * If there are any issues during the use process, you can provide feedback to the kingdee developer community website.
+ * Website: https://developer.kingdee.com/developer?productLineId=29
+ * Author: liebin.zheng
+ * Generate Date: 2025-04-09 17:34:20
+ */
+def cosmic_libs_path = System.getProperty('cosmic_libs_path')
+def cosmic_home = null
+
+if(cosmic_libs_path == null){
+	//println "NO 'cosmic_libs_path' property was setted in gradle.properties. "
+	//println "Try to find the 'cosmic_home' property in gradle.properties."
+	cosmic_home = System.getProperty('cosmic_home')
+}
+
+if(cosmic_home == null){
+	//println "NO 'cosmic_home' property was setted in gradle.properties. "
+	//println "Try to find the 'COSMIC_HOME' property in System environment."
+	cosmic_home = System.getenv('COSMIC_HOME')
+}
+
+if(cosmic_home != null){
+	cosmic_libs_path = "${cosmic_home}/mservice-cosmic/lib"
+}
+
+if(cosmic_libs_path == null){
+	throw new RuntimeException("Neither 'COSMIC_LIBS_PATH' was setted in System environment, nor 'cosmic_libs_path' property was setted in gradle.properties.")
+}
+
+
+println "The 'cosmic_libs_path' is: '${cosmic_libs_path}'."
+
+ext	{
+
+	path = [
+		trd : "${cosmic_libs_path}/trd",
+		bos : "${cosmic_libs_path}/bos",
+		biz : "${cosmic_libs_path}/biz",
+		cus : "${cosmic_libs_path}/cus",
+		outputdir : "${cosmic_libs_path}/outputdir",
+		lib : rootDir.path + "/code/lib"
+	]
+
+}

+ 5 - 0
cosmic.json

@@ -0,0 +1,5 @@
+{
+  "COSMIC_DEVELOPER_FLAG": "nckd",
+  "COSMIC_PROJECT_FLAG": "nc2kd",
+  "COSMIC_RES_URL": "http://10.1.128.150:8090/appstore/dev_env"
+}

+ 1 - 0
cosmic.properties

@@ -0,0 +1 @@
+MCServerURL=http://10.1.128.150:8090/appstore/dev_env

+ 0 - 0
datamodel/.gitkeep


BIN
docs/images/code1.png


BIN
docs/images/cosmic-studio-qrcode.png


BIN
docs/images/eclipse-gradle.png


BIN
docs/images/idea-gradle.png


+ 28 - 0
gradle.properties

@@ -0,0 +1,28 @@
+### ----------------------------
+### This is a kingdee cosmic template project that is automatically generated by the Kingdee cosmic development assistant plugin. 
+### If there are any issues during the use process, you can provide feedback to the kingdee developer community website.
+### Website: https://developer.kingdee.com/developer?productLineId=29
+### Author: liebin.zheng
+### Generate Date: 2025-04-09 17:34:20
+### ----------------------------
+systemProp.kddt_version=2.2.0-Beta
+systemProp.template_type=cloud
+systemProp.groupId=nckd.cosmic
+systemProp.artifactId=nckd-cosmic
+systemProp.version=1.0.0
+systemProp.ci_version=2.0
+systemProp.jdk.version=1.8
+systemProp.new_cosmic_project=true
+#--This is the developer flag
+systemProp.developer_flag=nckd
+#--This is the project flag
+systemProp.project_flag=nc2kd
+#--This is the project dir
+systemProp.project_dir=D:/work/ncgd/nckdSpace
+#--This is the dir for cosmic project libs and static resouces
+systemProp.cosmic_home=D:/work/ncgd/ncgdJar
+#--Performance configuration for gradle build
+org.gradle.parallel=true
+org.gradle.daemon=true
+org.gradle.caching=true
+org.gradle.jvmargs=-Xms256m -Xmx1024m -XX:MaxMetaspaceSize=128m

BIN
gradle/wrapper/gradle-wrapper.jar


+ 5 - 0
gradle/wrapper/gradle-wrapper.properties

@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-7.6.3-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists

+ 240 - 0
gradlew

@@ -0,0 +1,240 @@
+#!/bin/sh
+
+#
+# Copyright © 2015-2021 the original authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+#
+#   Gradle start up script for POSIX generated by Gradle.
+#
+#   Important for running:
+#
+#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+#       noncompliant, but you have some other compliant shell such as ksh or
+#       bash, then to run this script, type that shell name before the whole
+#       command line, like:
+#
+#           ksh Gradle
+#
+#       Busybox and similar reduced shells will NOT work, because this script
+#       requires all of these POSIX shell features:
+#         * functions;
+#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+#         * compound commands having a testable exit status, especially «case»;
+#         * various built-in commands including «command», «set», and «ulimit».
+#
+#   Important for patching:
+#
+#   (2) This script targets any POSIX shell, so it avoids extensions provided
+#       by Bash, Ksh, etc; in particular arrays are avoided.
+#
+#       The "traditional" practice of packing multiple parameters into a
+#       space-separated string is a well documented source of bugs and security
+#       problems, so this is (mostly) avoided, by progressively accumulating
+#       options in "$@", and eventually passing that to Java.
+#
+#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+#       see the in-line comments for details.
+#
+#       There are tweaks for specific operating systems such as AIX, CygWin,
+#       Darwin, MinGW, and NonStop.
+#
+#   (3) This script is generated from the Groovy template
+#       https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+#       within the Gradle project.
+#
+#       You can find Gradle at https://github.com/gradle/gradle/.
+#
+##############################################################################
+
+# Attempt to set APP_HOME
+
+# Resolve links: $0 may be a link
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+    APP_HOME=${app_path%"${app_path##*/}"}  # leaves a trailing /; empty if no leading path
+    [ -h "$app_path" ]
+do
+    ls=$( ls -ld "$app_path" )
+    link=${ls#*' -> '}
+    case $link in             #(
+      /*)   app_path=$link ;; #(
+      *)    app_path=$APP_HOME$link ;;
+    esac
+done
+
+APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
+
+APP_NAME="Gradle"
+APP_BASE_NAME=${0##*/}
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx1024m" "-Xms256m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD=maximum
+
+warn () {
+    echo "$*"
+} >&2
+
+die () {
+    echo
+    echo "$*"
+    echo
+    exit 1
+} >&2
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "$( uname )" in                #(
+  CYGWIN* )         cygwin=true  ;; #(
+  Darwin* )         darwin=true  ;; #(
+  MSYS* | MINGW* )  msys=true    ;; #(
+  NONSTOP* )        nonstop=true ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD=$JAVA_HOME/jre/sh/java
+    else
+        JAVACMD=$JAVA_HOME/bin/java
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD=java
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+    case $MAX_FD in #(
+      max*)
+        MAX_FD=$( ulimit -H -n ) ||
+            warn "Could not query maximum file descriptor limit"
+    esac
+    case $MAX_FD in  #(
+      '' | soft) :;; #(
+      *)
+        ulimit -n "$MAX_FD" ||
+            warn "Could not set maximum file descriptor limit to $MAX_FD"
+    esac
+fi
+
+# Collect all arguments for the java command, stacking in reverse order:
+#   * args from the command line
+#   * the main class name
+#   * -classpath
+#   * -D...appname settings
+#   * --module-path (only if needed)
+#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if "$cygwin" || "$msys" ; then
+    APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+    CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+    JAVACMD=$( cygpath --unix "$JAVACMD" )
+
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    for arg do
+        if
+            case $arg in                                #(
+              -*)   false ;;                            # don't mess with options #(
+              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath
+                    [ -e "$t" ] ;;                      #(
+              *)    false ;;
+            esac
+        then
+            arg=$( cygpath --path --ignore --mixed "$arg" )
+        fi
+        # Roll the args list around exactly as many times as the number of
+        # args, so each arg winds up back in the position where it started, but
+        # possibly modified.
+        #
+        # NB: a `for` loop captures its iteration list before it begins, so
+        # changing the positional parameters here affects neither the number of
+        # iterations, nor the values presented in `arg`.
+        shift                   # remove old arg
+        set -- "$@" "$arg"      # push replacement arg
+    done
+fi
+
+# Collect all arguments for the java command;
+#   * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
+#     shell script including quotes and variable substitutions, so put them in
+#     double quotes to make sure that they get re-expanded; and
+#   * put everything else in single quotes, so that it's not re-expanded.
+
+set -- \
+        "-Dorg.gradle.appname=$APP_BASE_NAME" \
+        -classpath "$CLASSPATH" \
+        org.gradle.wrapper.GradleWrapperMain \
+        "$@"
+
+# Stop when "xargs" is not available.
+if ! command -v xargs >/dev/null 2>&1
+then
+    die "xargs is not available"
+fi
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+#   readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+#   set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+        printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+        xargs -n1 |
+        sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+        tr '\n' ' '
+    )" '"$@"'
+
+exec "$JAVACMD" "$@"

+ 91 - 0
gradlew.bat

@@ -0,0 +1,91 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem      https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%"=="" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%"=="" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx1024m" "-Xms256m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if %ERRORLEVEL% equ 0 goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if %ERRORLEVEL% equ 0 goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+set EXIT_CODE=%ERRORLEVEL%
+if %EXIT_CODE% equ 0 set EXIT_CODE=1
+if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
+exit /b %EXIT_CODE%
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega

Fichier diff supprimé car celui-ci est trop grand
+ 350 - 0
logs/cosmic_out.log


Fichier diff supprimé car celui-ci est trop grand
+ 282 - 0
logs/cosmic_out_20250409_0.log


Fichier diff supprimé car celui-ci est trop grand
+ 217 - 0
logs/cosmic_out_20250410_0.log


Fichier diff supprimé car celui-ci est trop grand
+ 136 - 0
logs/cosmic_out_20250410_1.log


Fichier diff supprimé car celui-ci est trop grand
+ 3807 - 0
logs/cosmic_out_20250410_2.log


Fichier diff supprimé car celui-ci est trop grand
+ 698 - 0
logs/cosmic_out_20250410_3.log


Fichier diff supprimé car celui-ci est trop grand
+ 242 - 0
logs/cosmic_out_20250411_0.log


Fichier diff supprimé car celui-ci est trop grand
+ 1378 - 0
logs/cosmic_out_20250411_1.log


Fichier diff supprimé car celui-ci est trop grand
+ 915 - 0
logs/cosmic_out_20250411_2.log


Fichier diff supprimé car celui-ci est trop grand
+ 1620 - 0
logs/cosmic_out_20250411_3.log


Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff