diff --git a/JSD-9274-需求确认书V1.docx b/JSD-9274-需求确认书V1.docx
new file mode 100644
index 0000000..64cc300
Binary files /dev/null and b/JSD-9274-需求确认书V1.docx differ
diff --git a/README.md b/README.md
index 2e7e2f4..362ad62 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,6 @@
# open-JSD-9274
-JSD-9274 数据集扩展
\ No newline at end of file
+JSD-9274 数据集扩展\
+免责说明:该源码为第三方爱好者提供,不保证源码和方案的可靠性,也不提供任何形式的源码教学指导和协助!\
+仅作为开发者学习参考使用!禁止用于任何商业用途!\
+为保护开发者隐私,开发者信息已隐去!若原开发者希望公开自己的信息,可联系hugh处理。
\ No newline at end of file
diff --git a/lib/finekit-10.0.jar b/lib/finekit-10.0.jar
new file mode 100644
index 0000000..611c8f5
Binary files /dev/null and b/lib/finekit-10.0.jar differ
diff --git a/plugin.xml b/plugin.xml
new file mode 100644
index 0000000..1bb3833
--- /dev/null
+++ b/plugin.xml
@@ -0,0 +1,21 @@
+
+
+ com.fr.plugin.third.party.jsdjche
+
+ yes
+ 0.2
+ 10.0
+ 2019-01-01
+ fr.open
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/com/fr/plugin/third/party/jsdjche/Utils.java b/src/main/java/com/fr/plugin/third/party/jsdjche/Utils.java
new file mode 100644
index 0000000..82a95bf
--- /dev/null
+++ b/src/main/java/com/fr/plugin/third/party/jsdjche/Utils.java
@@ -0,0 +1,188 @@
+package com.fr.plugin.third.party.jsdjche;
+
+import com.fanruan.api.log.LogKit;
+import com.fanruan.api.util.StringKit;
+import com.fr.third.org.apache.http.HttpEntity;
+import com.fr.third.org.apache.http.HttpStatus;
+import com.fr.third.org.apache.http.client.config.RequestConfig;
+import com.fr.third.org.apache.http.client.methods.CloseableHttpResponse;
+import com.fr.third.org.apache.http.client.methods.HttpGet;
+import com.fr.third.org.apache.http.client.methods.HttpPost;
+import com.fr.third.org.apache.http.conn.ssl.NoopHostnameVerifier;
+import com.fr.third.org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import com.fr.third.org.apache.http.entity.StringEntity;
+import com.fr.third.org.apache.http.impl.client.CloseableHttpClient;
+import com.fr.third.org.apache.http.impl.client.HttpClients;
+import com.fr.third.org.apache.http.ssl.SSLContextBuilder;
+import com.fr.third.org.apache.http.ssl.TrustStrategy;
+import com.fr.third.org.apache.http.util.EntityUtils;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.UUID;
+
+public class Utils {
+ public static String DEFAULT_USER_AGENT = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36";
+ public static RequestConfig REQUEST_CONFIG = RequestConfig.custom()
+ .setConnectionRequestTimeout(30000)
+ .setSocketTimeout(30000) // 服务端相应超时
+ .setConnectTimeout(30000) // 建立socket链接超时时间
+ .build();
+
+ public static CloseableHttpClient createSSLClientDefault() {
+ try {
+ SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
+
+ @Override
+ public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+ return true;
+ }
+ }).build();
+ HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE;
+ SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
+ return HttpClients.custom().setSSLSocketFactory(sslsf).build();
+ } catch (Exception e) {
+ LogKit.error(e.getMessage(), e);
+ }
+ return HttpClients.createDefault();
+ }
+
+ public static synchronized CloseableHttpClient createHttpClient(String url) {
+ CloseableHttpClient httpClient = null;
+ if (StringKit.isEmpty(url)) {
+ httpClient = HttpClients.createDefault();
+ return httpClient;
+ }
+
+ if (url.startsWith("https://")) {
+ httpClient = createSSLClientDefault();
+ return httpClient;
+ }
+ httpClient = HttpClients.createDefault();
+ return httpClient;
+ }
+
+ public static synchronized String createHttpGetContent(CloseableHttpClient httpClient, String url, String basicAuth) throws IOException {
+ if ((httpClient == null) || (StringKit.isEmpty(url))) {
+ return "";
+ }
+
+ HttpGet httpGet = new HttpGet(url);
+ httpGet.addHeader("User-Agent", Utils.DEFAULT_USER_AGENT);
+ if (StringKit.isNotEmpty(basicAuth)) {
+ httpGet.addHeader("Authorization", basicAuth);
+ }
+
+ httpGet.setConfig(Utils.REQUEST_CONFIG);
+ CloseableHttpResponse response = httpClient.execute(httpGet);
+ int statusCode = response.getStatusLine().getStatusCode();
+ if (statusCode != HttpStatus.SC_OK) {
+ response.close();
+ LogKit.info("http请求出错,http status:" + statusCode);
+ return "";
+ }
+
+ HttpEntity httpEntity = response.getEntity();
+ if (httpEntity == null) {
+ response.close();
+ LogKit.info("http请求出错,http响应内容为空");
+ return "";
+ }
+ String responseContent = EntityUtils.toString(httpEntity, "UTF-8");
+ response.close();
+ if (StringKit.isEmpty(responseContent)) {
+ LogKit.info("http请求出错,http响应内容为空1");
+ return "";
+ }
+ return responseContent;
+ }
+
+ public static synchronized String createHttpPostContent(CloseableHttpClient httpClient, String url, String bodyContent, String basicAuth,String contentType) throws IOException {
+ if ((httpClient == null) || (StringKit.isEmpty(url))) {
+ return "";
+ }
+
+ HttpPost httpPost = new HttpPost(url);
+ httpPost.addHeader("User-Agent", Utils.DEFAULT_USER_AGENT);
+ httpPost.setConfig(Utils.REQUEST_CONFIG);
+ if (StringKit.isNotEmpty(basicAuth)) {
+ httpPost.addHeader("Authorization", basicAuth);
+ }
+ if (StringKit.isNotEmpty(contentType)) {
+ httpPost.addHeader("Content-Type", contentType);
+ }
+ StringEntity bodyEntity = new StringEntity(bodyContent, "UTF-8");
+ httpPost.setEntity(bodyEntity);
+ CloseableHttpResponse response = httpClient.execute(httpPost);
+ int statusCode = response.getStatusLine().getStatusCode();
+ if (statusCode != HttpStatus.SC_OK) {
+ response.close();
+ LogKit.info("http请求出错,http status:" + statusCode);
+ return "";
+ }
+
+ HttpEntity httpEntity = response.getEntity();
+ if (httpEntity == null) {
+ response.close();
+ LogKit.info("http请求出错,http响应内容为空");
+ return "";
+ }
+ String responseContent = EntityUtils.toString(httpEntity, "UTF-8");
+ response.close();
+ if (StringKit.isEmpty(responseContent)) {
+ LogKit.info("http请求出错,http响应内容为空1");
+ return "";
+ }
+ return responseContent;
+ }
+
+
+ /**
+ * 获取完整请求链接
+ *
+ * @param req 请求
+ * @return
+ */
+ public static String getFullRequestUrl(HttpServletRequest req) {
+ if (req == null) {
+ return "";
+ }
+ String url = req.getRequestURL().toString();
+ String queryUrl = req.getQueryString();
+ if ((queryUrl == null) || "null".equalsIgnoreCase(queryUrl)) {
+ queryUrl = "";
+ } else {
+ queryUrl = "?" + queryUrl;
+ }
+ String fullUrl = url + queryUrl;
+ return fullUrl;
+ }
+
+
+ /**
+ * 重定向
+ *
+ * @param res
+ * @param url
+ */
+ public static void sendRedirect(HttpServletResponse res, String url) {
+ if ((res == null) || (StringKit.isEmpty(url))) {
+ return;
+ }
+ res.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
+ res.setHeader("Location", url);
+ }
+
+
+ public static synchronized String getUuid() {
+ String uuid = UUID.randomUUID().toString().replace("-", "");
+ return uuid;
+ }
+
+
+}
diff --git a/src/main/java/com/fr/plugin/third/party/jsdjche/config/CustomDataConfig.java b/src/main/java/com/fr/plugin/third/party/jsdjche/config/CustomDataConfig.java
new file mode 100644
index 0000000..377a5ca
--- /dev/null
+++ b/src/main/java/com/fr/plugin/third/party/jsdjche/config/CustomDataConfig.java
@@ -0,0 +1,68 @@
+package com.fr.plugin.third.party.jsdjche.config;
+
+import com.fr.config.*;
+import com.fr.config.holder.Conf;
+import com.fr.config.holder.factory.Holders;
+
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * 配置数据保存
+ */
+@Visualization(category = "自定义数据集配置")
+public class CustomDataConfig extends DefaultConfiguration {
+ public String getNameSpace() {
+ return this.getClass().getName();
+ }
+
+ private static volatile CustomDataConfig config = null;
+
+ public static CustomDataConfig getInstance() {
+ if (config == null) {
+ config = ConfigContext.getConfigInstance(CustomDataConfig.class);
+ }
+ return config;
+ }
+
+ @Identifier(value = "dataSyncUrl", name = "数据地址", description = "", status = Status.SHOW)
+ private Conf dataSyncUrl = Holders.simple("http://10.12.8.130/ssss/rest/windFarmBi/provideData");
+
+ @Identifier(value = "dataUsername", name = "数据用户名", description = "", status = Status.SHOW)
+ private Conf dataUsername = Holders.simple("xxxx");
+
+ @Identifier(value = "dataPassword", name = "数据密码", description = "", status = Status.SHOW)
+ private Conf dataPassword = Holders.simple("zzzz");
+
+ public String getDataSyncUrl() {
+ return dataSyncUrl.get();
+ }
+
+ public void setDataSyncUrl(String dataSyncUrl) {
+ this.dataSyncUrl.set(dataSyncUrl);
+ }
+
+ public String getDataUsername() {
+ return dataUsername.get();
+ }
+
+ public void setDataUsername(String dataUsername) {
+ this.dataUsername.set(dataUsername);
+ }
+
+ public String getDataPassword() {
+ return dataPassword.get();
+ }
+
+ public void setDataPassword(String dataPassword) {
+ this.dataPassword.set(dataPassword);
+ }
+
+ @Override
+ public Object clone() throws CloneNotSupportedException {
+ CustomDataConfig cloned = (CustomDataConfig) super.clone();
+ cloned.dataSyncUrl = (Conf) dataSyncUrl.clone();
+ cloned.dataUsername = (Conf) dataUsername.clone();
+ cloned.dataPassword = (Conf) dataPassword.clone();
+ return cloned;
+ }
+}
diff --git a/src/main/java/com/fr/plugin/third/party/jsdjche/config/DataConfigInitializeMonitor.java b/src/main/java/com/fr/plugin/third/party/jsdjche/config/DataConfigInitializeMonitor.java
new file mode 100644
index 0000000..861db1d
--- /dev/null
+++ b/src/main/java/com/fr/plugin/third/party/jsdjche/config/DataConfigInitializeMonitor.java
@@ -0,0 +1,26 @@
+package com.fr.plugin.third.party.jsdjche.config;
+
+import com.fr.intelli.record.Focus;
+import com.fr.intelli.record.Original;
+import com.fr.plugin.context.PluginContext;
+import com.fr.plugin.observer.inner.AbstractPluginLifecycleMonitor;
+import com.fr.record.analyzer.EnableMetrics;
+import com.fr.stable.fun.Authorize;
+
+/**
+ * 配置信息初始化
+ */
+@EnableMetrics
+@Authorize(callSignKey = "com.fr.plugin.third.party.jsdjche")
+public class DataConfigInitializeMonitor extends AbstractPluginLifecycleMonitor {
+ @Override
+ @Focus(id = "com.fr.plugin.third.party.jsdjche", text = "plugin-jsdjche", source = Original.PLUGIN)
+ public void afterRun(PluginContext pluginContext) {
+ CustomDataConfig.getInstance();
+ }
+
+ @Override
+ public void beforeStop(PluginContext pluginContext) {
+
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/fr/plugin/third/party/jsdjche/data/CustomHttpDataModel.java b/src/main/java/com/fr/plugin/third/party/jsdjche/data/CustomHttpDataModel.java
new file mode 100644
index 0000000..56c1c0f
--- /dev/null
+++ b/src/main/java/com/fr/plugin/third/party/jsdjche/data/CustomHttpDataModel.java
@@ -0,0 +1,161 @@
+package com.fr.plugin.third.party.jsdjche.data;
+
+import com.fanruan.api.log.LogKit;
+import com.fanruan.api.util.StringKit;
+import com.fr.base.TableData;
+import com.fr.data.AbstractDataModel;
+import com.fr.general.data.TableDataException;
+import com.fr.json.JSONArray;
+import com.fr.json.JSONObject;
+import com.fr.plugin.context.PluginContexts;
+import com.fr.plugin.third.party.jsdjche.Utils;
+import com.fr.plugin.third.party.jsdjche.config.CustomDataConfig;
+import com.fr.third.org.apache.http.impl.client.CloseableHttpClient;
+import com.fr.utils.Base64;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class CustomHttpDataModel extends AbstractDataModel {
+ private static String[] COLUMN_NAMES = {"projectscadacode", "projectname", "servicestarttime", "serviceendtime"};
+ private int rowCount = TableData.RESULT_ALL;
+ private DatasetData datas = new DatasetData();
+
+ public CustomHttpDataModel(int count) {
+ this.rowCount = count;
+ if (this.rowCount == 0) {
+ return;
+ }
+ queryData();
+ }
+
+ @Override
+ public int getColumnCount() throws TableDataException {
+ return COLUMN_NAMES.length;
+ }
+
+ @Override
+ public String getColumnName(int i) throws TableDataException {
+ return COLUMN_NAMES[i];
+ }
+
+ @Override
+ public boolean hasRow(int rowIndex) throws TableDataException {
+ int count = getRowCount();
+ return rowIndex < count;
+ }
+
+ @Override
+ public int getRowCount() throws TableDataException {
+ if (this.datas == null) {
+ return 0;
+ }
+ List> values = this.datas.getValues();
+ if (values == null) {
+ return 0;
+ }
+ int count = values.size();
+ return count;
+ }
+
+ @Override
+ public Object getValueAt(int rowIndex, int columnIndex) throws TableDataException {
+ if (this.datas == null) {
+ return "";
+ }
+ List> values = this.datas.getValues();
+ if ((values == null) || (values.size() <= rowIndex)) {
+ return "";
+ }
+ List