package com.smtaiserver.smtaiserver.core;
|
|
import com.alibaba.druid.pool.DruidDataSource;
|
import com.smtaiserver.smtaiserver.attach.SMTAIAttachMetricDef;
|
import com.smtaiserver.smtaiserver.attach.SMTAIAttachTableDef;
|
import com.smtaiserver.smtaiserver.database.SMTDatabase;
|
import com.smtaiserver.smtaiserver.gismap.SMTGisMapLayerDef;
|
import com.smtaiserver.smtaiserver.gismap.SMTMapOtypeDef;
|
import com.smtaiserver.smtaiserver.gismap.SMTMapVPropDef;
|
import com.smtaiserver.smtaiserver.gismap.tabledef.SMTMapTableDef;
|
import com.smtaiserver.smtaiserver.gismap.theme.SMTMapThemeDef;
|
import com.smtaiserver.smtaiserver.gismap.theme.SMTMapThemeTableDef;
|
import com.smtaiserver.smtaiserver.javaai.ast.ASTQuestionReplace;
|
import com.smtaiserver.smtaiserver.javaai.datasource.SMTDataSource;
|
import com.smtaiserver.smtaiserver.javaai.jsonflow.core.SMTJsonFlowManager;
|
import com.smtaiserver.smtaiserver.javaai.jsonflow.core.SMTJsonFlowScriptJet;
|
import com.smtaiserver.smtaiserver.javaai.llm.core.SMTLLMConnect;
|
import com.smtaiserver.smtaiserver.javaai.llm.core.SMTLLMFactory;
|
import com.smtaiserver.smtaiserver.javaai.metrics.base.SMTDimensionDef;
|
import com.smtaiserver.smtaiserver.javaai.metrics.base.SMTMetricsDef;
|
import com.smtaiserver.smtaiserver.javaai.querydetail.SMTAIQueryDetail;
|
import com.smtaiserver.smtaiserver.javaai.qwen.SMTQwenAgentManager;
|
import com.smtaiserver.smtaiserver.javaai.qwen.SMTQwenApp;
|
import com.smtaiserver.smtaiserver.javaai.sse.SMTSSEBroadcastChat;
|
import com.smtservlet.core.SMTApp;
|
import com.smtservlet.core.SMTApp.SMTEhCacheManagerInitialize;
|
import com.smtservlet.util.Json;
|
import com.smtservlet.util.SMTHttpClient;
|
import com.smtservlet.util.SMTJsonWriter;
|
import com.smtservlet.util.SMTStatic;
|
import java.io.*;
|
import java.net.URLEncoder;
|
import java.sql.Connection;
|
import java.sql.DriverManager;
|
import java.util.ArrayList;
|
import java.util.Date;
|
import java.util.HashMap;
|
import java.util.HashSet;
|
import java.util.List;
|
import java.util.Map;
|
import java.util.Map.Entry;
|
import java.util.Set;
|
import java.util.regex.Matcher;
|
import java.util.regex.Pattern;
|
import javax.servlet.http.HttpSessionEvent;
|
import net.sf.ehcache.Cache;
|
import net.sf.ehcache.CacheManager;
|
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.Logger;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.text.PDFTextStripper;
|
import org.apache.poi.hwpf.HWPFDocument;
|
import org.apache.poi.hwpf.extractor.WordExtractor;
|
import org.apache.poi.xwpf.extractor.XWPFWordExtractor;
|
import org.apache.poi.xwpf.usermodel.XWPFDocument;
|
import org.dom4j.Document;
|
import org.dom4j.io.OutputFormat;
|
import org.dom4j.io.XMLWriter;
|
import org.locationtech.proj4j.CoordinateTransform;
|
import org.locationtech.proj4j.ProjCoordinate;
|
import org.mozilla.javascript.ConsString;
|
import org.mozilla.javascript.Context;
|
import org.mozilla.javascript.Function;
|
import org.mozilla.javascript.NativeArray;
|
import org.mozilla.javascript.NativeObject;
|
import org.mozilla.javascript.Undefined;
|
import org.mozilla.javascript.Wrapper;
|
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.cache.ehcache.EhCacheCacheManager;
|
import org.springframework.web.context.WebApplicationContext;
|
import org.springframework.web.multipart.MultipartFile;
|
|
public class SMTAIServerApp extends SMTApp implements SMTEhCacheManagerInitialize,SMTApp.SMTSessionListenerEvent
|
{
|
private static class SessionChatStreamReply
|
{
|
public String _replyId;
|
public Json _jsonReply;
|
|
public SessionChatStreamReply(String replyId, Json jsonReply)
|
{
|
_replyId = replyId;
|
_jsonReply = jsonReply;
|
}
|
}
|
|
|
protected Json _jsonSwaggerApiDoc;
|
protected DruidDataSource _dsDataSource;
|
|
@Value("${hswater.logger.sql}")
|
protected Boolean _logSQL;
|
|
// 数据库连接信息,暂时和系统库一致,将来可以改成其他地方
|
@Value("${spring.datasource.driver-class-name}")
|
protected String _dbDriver;
|
@Value("${spring.datasource.url}")
|
protected String _dbUrl;
|
@Value("${spring.datasource.username}")
|
protected String _dbUser;
|
@Value("${spring.datasource.password}")
|
protected String _dbPass;
|
@Value("${spring.datasource.druid.validation-query}")
|
protected String _dbAlidationQuery;
|
@Value("${spring.datasource.druid.max-active}")
|
protected int _dbMaxActive;
|
@Value("${spring.datasource.druid.initial-size}")
|
protected int _dbInitialSize;
|
@Value("${spring.datasource.druid.min-idle}")
|
protected int _dbMinIdle;
|
@Value("${spring.datasource.druid.max-wait}")
|
protected int _dbMaxWait;
|
@Value("${spring.datasource.druid.time-between-eviction-runs-millis}")
|
protected int _dbTimeBetweenEvictionRunsMillis;
|
@Value("${spring.datasource.druid.min-evictable-idle-time-millis}")
|
protected int _dbMinEvictableIdleTimeMillis;
|
@Value("${spring.datasource.druid.test-while-idle}")
|
protected boolean _dbTestWhileIdle;
|
@Value("${spring.datasource.druid.test-on-borrow}")
|
protected boolean _dbTestOnBorrow;
|
@Value("${spring.datasource.druid.test-on-return}")
|
protected boolean _dbTestOnReturn;
|
@Value("${spring.datasource.druid.pool-prepared-statements}")
|
protected boolean _dbPoolPreparedStatements;
|
@Value("${spring.datasource.druid.max-pool-prepared-statement-per-connection-size}")
|
protected int _dbMaxPoolPreparedStatementPerConnectionSize;
|
@Value("${wiai.debug_mode}")
|
protected boolean _isDebugMode;
|
|
@Value("${wiai.table_data_source}")
|
protected String _tableDataSource;
|
|
protected SMTAIServerEncache _serverEncache;
|
|
protected Map<String, Map<String, String>> _mapSess2AsyncProcId2Process = new HashMap<>();
|
protected Map<String, SessionChatStreamReply> _mapSess2ChatStreamReply = new HashMap<>();
|
protected SMTJsonFlowScriptJet _scriptEsprima = null;
|
protected Function _funcEsprima = null;
|
protected Object _lockScriptEsprima = new Object();
|
|
protected Map<String, SMTSSEBroadcastChat> _mapUser2SMTSSEBroadcastChat = new HashMap<>();
|
|
private static Pattern _patGroupStep = Pattern.compile("(\\d+)\\s*(minutes|hours|days|months|years|month|hour|year|day|minute)");
|
private static Pattern _patGlobalMacro = Pattern.compile("\\{\\{\\{([\\w\\.]+)\\}\\}\\}");
|
private static Logger _logger = LogManager.getLogger(SMTQwenApp.class);
|
private static Pattern _patIsNumber = Pattern.compile("^[1-9]\\d*$");
|
|
private static String[] _encacheIdList = {
|
"GlobalConfig",
|
"MetricsDefMap",
|
"DataSourceMap",
|
"DimensionMap",
|
"QwenAgentManager",
|
"AIQuestionReplace",
|
"GISTransform",
|
"queryDetailMap",
|
"getLLMFactoryMap",
|
"getGroupTypeMap",
|
"getMapLayerDef",
|
"getMapTableDefMap",
|
"getMapVPropDefMap",
|
"getMapThemeTableDefMap",
|
"getMapThemeDefMap",
|
"getAttachTableDefMap",
|
"getAttachMetricDefMap"
|
};
|
|
public static SMTAIServerApp getApp()
|
{
|
return (SMTAIServerApp)SMTApp._ThisPtr;
|
}
|
|
public String getDefaultLLMId() throws Exception
|
{
|
String defaultLLMId = System.getProperty("default_llm_id");
|
if(SMTStatic.isNullOrEmpty(defaultLLMId))
|
return (String)SMTAIServerApp.getApp().getGlobalConfig("llm.default.id");
|
|
return defaultLLMId;
|
}
|
|
public String getTableDataSource()
|
{
|
return _tableDataSource;
|
}
|
|
public boolean isAppDebugMode()
|
{
|
return _isDebugMode;
|
}
|
|
public SMTSSEBroadcastChat allocBroadcastChat(String userId)
|
{
|
synchronized(_mapUser2SMTSSEBroadcastChat)
|
{
|
SMTSSEBroadcastChat chat = _mapUser2SMTSSEBroadcastChat.get(userId);
|
if(chat == null)
|
{
|
chat = new SMTSSEBroadcastChat(userId);
|
_mapUser2SMTSSEBroadcastChat.put(userId, chat);
|
}
|
|
return chat;
|
}
|
}
|
|
public SMTSSEBroadcastChat getBroadcastChat(String userId)
|
{
|
synchronized(_mapUser2SMTSSEBroadcastChat)
|
{
|
SMTSSEBroadcastChat chat = _mapUser2SMTSSEBroadcastChat.get(userId);
|
return chat;
|
}
|
}
|
|
public void setServiceEncache(SMTAIServerEncache serverEncache)
|
{
|
_serverEncache = serverEncache;
|
}
|
|
public Map<String, Map<String, SMTMetricsDef>> getMetricsMapGroupMap() throws Exception
|
{
|
return _serverEncache.queryMetricsMapGroup();
|
}
|
|
public Map<String, SMTMetricsDef> getMetricsMap(String groupId) throws Exception
|
{
|
Map<String, Map<String, SMTMetricsDef>> mapMapMetrics = _serverEncache.queryMetricsMapGroup();
|
Map<String, SMTMetricsDef> mapResult = mapMapMetrics.get(groupId);
|
|
if(mapResult == null)
|
return new HashMap<String, SMTMetricsDef>();
|
|
return mapResult;
|
}
|
|
public DruidDataSource createDruidDataSource(String driver, String dbUrl, String dbUser, String dbPass)
|
{
|
DruidDataSource dsDataSource = new DruidDataSource();
|
dsDataSource.setDriverClassName(driver);
|
dsDataSource.setUrl(dbUrl);
|
dsDataSource.setUsername(dbUser);
|
dsDataSource.setPassword(dbPass);
|
// dsDataSource.setValidationQuery(_dbAlidationQuery);
|
dsDataSource.setMaxActive(_dbMaxActive);
|
dsDataSource.setInitialSize(0);
|
dsDataSource.setMinIdle(0);
|
dsDataSource.setMaxWait(_dbMaxWait);
|
dsDataSource.setTimeBetweenEvictionRunsMillis(_dbTimeBetweenEvictionRunsMillis);
|
dsDataSource.setMinEvictableIdleTimeMillis(_dbMinEvictableIdleTimeMillis);
|
dsDataSource.setTestWhileIdle(_dbTestWhileIdle);
|
dsDataSource.setTestOnBorrow(_dbTestOnBorrow);
|
dsDataSource.setTestOnReturn(_dbTestOnReturn);
|
dsDataSource.setPoolPreparedStatements(_dbPoolPreparedStatements);
|
dsDataSource.setMaxPoolPreparedStatementPerConnectionSize(_dbMaxPoolPreparedStatementPerConnectionSize);
|
|
return dsDataSource;
|
}
|
|
@Override
|
protected void onWebStartup(WebApplicationContext webApplicationContext) throws Exception
|
{
|
System.out.println("=====================================================>onWebStartup:你好");
|
_logger.info("=====================================================>onWebStartup:你好");
|
|
// 创建数据源
|
DruidDataSource dsDataSource = new DruidDataSource();
|
dsDataSource.setDriverClassName(_dbDriver);
|
dsDataSource.setUrl(_dbUrl);
|
dsDataSource.setUsername(_dbUser);
|
dsDataSource.setPassword(_dbPass);
|
dsDataSource.setValidationQuery(_dbAlidationQuery);
|
dsDataSource.setMaxActive(_dbMaxActive);
|
dsDataSource.setInitialSize(_dbInitialSize);
|
dsDataSource.setMinIdle(_dbMinIdle);
|
dsDataSource.setMaxWait(_dbMaxWait);
|
dsDataSource.setTimeBetweenEvictionRunsMillis(_dbTimeBetweenEvictionRunsMillis);
|
dsDataSource.setMinEvictableIdleTimeMillis(_dbMinEvictableIdleTimeMillis);
|
dsDataSource.setTestWhileIdle(_dbTestWhileIdle);
|
dsDataSource.setTestOnBorrow(_dbTestOnBorrow);
|
dsDataSource.setTestOnReturn(_dbTestOnReturn);
|
dsDataSource.setPoolPreparedStatements(_dbPoolPreparedStatements);
|
dsDataSource.setMaxPoolPreparedStatementPerConnectionSize(_dbMaxPoolPreparedStatementPerConnectionSize);
|
_dsDataSource = dsDataSource;
|
|
|
super.onWebStartup(webApplicationContext);
|
|
|
_serverEncache.getQueryDetailMap();
|
_serverEncache.getLLMFactoryMap();
|
_serverEncache.getMapLayerDef();
|
_serverEncache.getMapTableDefMap();
|
_serverEncache.getMapVPropDefMap();
|
_serverEncache.getMapThemeTableDefMap();
|
_serverEncache.getMapThemeDefMap();
|
_serverEncache.getAttachTableDefMap();
|
_serverEncache.getAttachMetricDefMap();
|
_serverEncache.getQwenAgentManager();
|
}
|
|
public SMTMapTableDef getMapTableDef(String tableId) throws Exception
|
{
|
SMTMapTableDef tableDef = _serverEncache.getMapTableDefMap().get(tableId);
|
if(tableDef == null)
|
throw new Exception("can't find table id : " + tableId);
|
return tableDef;
|
}
|
|
public SMTMapVPropDef getMapVPropDefMap(String OTYPE, String VPROP) throws Exception
|
{
|
SMTMapOtypeDef otypeDef = _serverEncache.getMapVPropDefMap().get(OTYPE);
|
if(otypeDef == null)
|
throw new Exception("can't get otype : " + OTYPE);
|
SMTMapVPropDef vpropDef = otypeDef.getVPropDef(VPROP);
|
|
return vpropDef;
|
}
|
|
public SMTMapOtypeDef getMapOTypeDef(String OTYPE) throws Exception
|
{
|
SMTMapOtypeDef otypeDef = _serverEncache.getMapVPropDefMap().get(OTYPE);
|
return otypeDef;
|
}
|
|
public String esprimaJs2ASTStr(String code1) throws Exception
|
{
|
synchronized(_lockScriptEsprima)
|
{
|
if(_scriptEsprima == null)
|
{
|
// 创建esprima脚本引擎
|
_scriptEsprima = new SMTJsonFlowScriptJet();
|
Context cx = _scriptEsprima.entryContext();
|
try
|
{
|
InputStream is = SMTJsonFlowManager.class.getResourceAsStream("/javascript/esprima.min.js");
|
try
|
{
|
String code = SMTStatic.readTextStream(is);
|
_scriptEsprima.executeScript(cx, code);
|
|
_funcEsprima = _scriptEsprima.compileFunction(cx, "esprimaJs2AST", "function(code){return JSON.stringify(esprima.parse(code));};");
|
}
|
finally
|
{
|
is.close();
|
}
|
}
|
finally
|
{
|
Context.exit();
|
}
|
|
}
|
|
Context cx = _scriptEsprima.entryContext();
|
try
|
{
|
String strJson = (String)_scriptEsprima.callFunction(cx, _funcEsprima, new Object[] {code1});
|
|
return strJson;
|
}
|
finally
|
{
|
Context.exit();
|
}
|
}
|
}
|
|
public SMTDatabase allocDatabase() throws Exception
|
{
|
if(_dsDataSource == null)
|
return null;
|
|
Connection conn = _dsDataSource.getConnection();
|
|
return new SMTDatabase(conn);
|
}
|
|
public SMTDatabase allocNativeDatabase() throws Exception
|
{
|
Connection conn = DriverManager.getConnection(_dbUrl, _dbUser, _dbPass);
|
return new SMTDatabase(conn);
|
}
|
|
|
public boolean isLogSQL()
|
{
|
return (_logSQL == null) ? false : _logSQL;
|
}
|
|
public void readSwaggerJson(SMTJsonWriter jsonWr)
|
{
|
for(Entry<String, SMTRequestConfig> entry : this._mapName2RequestConfig.entrySet())
|
{
|
String url = "/" + entry.getKey();
|
SMTRequestConfig requestConfig = entry.getValue();
|
|
if(requestConfig._jsonConfig == null)
|
continue;
|
|
Json jsonSwaggers = requestConfig._jsonConfig.safeGetJson("swaggers");
|
if(jsonSwaggers == null)
|
continue;
|
|
List<Json> listJsonSwagger = jsonSwaggers.asJsonList();
|
if(listJsonSwagger.size() > 0)
|
{
|
int index = 0;
|
|
Json jsonSwagger = listJsonSwagger.get(index);
|
jsonWr.addKeyRaw(url, jsonSwagger);
|
}
|
}
|
}
|
|
public synchronized Json readSwaggerApiDocJson()
|
{
|
if(_jsonSwaggerApiDoc == null)
|
{
|
Set<String> setGroups = new HashSet<String>();
|
SMTJsonWriter jsonWr = new SMTJsonWriter(false);
|
jsonWr.addKeyValue("swagger", "2.0");
|
jsonWr.beginMap("info");
|
{
|
jsonWr.addKeyValue("title", "Swagger操作");
|
jsonWr.addKeyValue("description", "WI水务智能系统Swagger操作页面");
|
jsonWr.addKeyValue("version", "1.0.0");
|
}
|
jsonWr.endMap();
|
jsonWr.beginMap("paths");
|
for(Entry<String, SMTRequestConfig> entry : this._mapName2RequestConfig.entrySet())
|
{
|
String url = "/" + entry.getKey();
|
SMTRequestConfig requestConfig = entry.getValue();
|
|
if(requestConfig._jsonConfig == null)
|
continue;
|
|
Json jsonSwaggers = requestConfig._jsonConfig.safeGetJson("swaggers");
|
if(jsonSwaggers == null)
|
continue;
|
|
List<Json> listJsonSwagger = jsonSwaggers.asJsonList();
|
int count = listJsonSwagger.size();
|
for(int index = 0; index < count; index ++)
|
{
|
Json jsonSwagger = listJsonSwagger.get(index);
|
jsonWr.beginMap(url + (count == 1 ? "" : String.format("?dummy=%d", index)));
|
{
|
String groupName = jsonSwagger.safeGetStr("group", null);
|
if(!SMTStatic.isNullOrEmpty(groupName))
|
{
|
jsonWr.addKeyValue("hwngroup", groupName);
|
setGroups.add(groupName);
|
}
|
|
jsonWr.beginMap("post");
|
{
|
// 设置入参类型
|
jsonWr.beginArray("consumes");
|
jsonWr.addKeyValue(null, jsonSwagger.safeGetStr("consumes", "application/x-www-form-urlencoded"));
|
jsonWr.endArray();
|
|
// 设置出参类型
|
jsonWr.beginArray("produces");
|
jsonWr.addKeyValue(null, "application/json");
|
jsonWr.endArray();
|
|
// 设置返回类型
|
jsonWr.beginMap("responses");
|
{
|
jsonWr.beginMap("200");
|
{
|
jsonWr.addKeyValue("description", "OK");
|
jsonWr.beginMap("schema");
|
jsonWr.addKeyValue("type", "object");
|
Json jsonResponses = jsonSwagger.safeGetJson("responses");
|
if(jsonResponses != null)
|
{
|
jsonWr.beginMap("properties");
|
parseSwaggerRespnseJson(jsonResponses, jsonWr);
|
jsonWr.endMap();
|
}
|
jsonWr.endMap();
|
}
|
jsonWr.endMap();
|
}
|
jsonWr.endMap();
|
|
// 设置接口所属分组
|
jsonWr.addKeyRaw("tags", jsonSwagger.getJson("tags"));
|
|
// 设置接口说明
|
jsonWr.addKeyValue("summary", jsonSwagger.getJson("title"));
|
|
// 设置参数
|
jsonWr.beginArray("parameters");
|
|
Json jsonParams = jsonSwagger.safeGetJson("parameters");
|
if(jsonParams != null)
|
{
|
for(Json jsonParam : jsonParams.asJsonList())
|
{
|
jsonWr.beginMap(null);
|
{
|
jsonWr.addKeyValue("in", "formData");
|
jsonWr.addKeyValue("name", jsonParam.getJson("name").asString());
|
jsonWr.addKeyValue("description", jsonParam.getJson("title").asString());
|
jsonWr.addKeyValue("required", jsonParam.safeGetBoolean("required", false));
|
jsonWr.addKeyValue("type", jsonParam.safeGetStr("type", "string"));
|
String defValue = jsonParam.safeGetStr("default", null);
|
if(!SMTStatic.isNullOrEmpty(defValue))
|
{
|
jsonWr.addKeyValue("default", defValue);
|
}
|
}
|
jsonWr.endMap();
|
}
|
}
|
|
|
jsonWr.endArray();
|
|
}
|
jsonWr.endMap();
|
}
|
jsonWr.endMap();
|
}
|
}
|
jsonWr.endMap();
|
|
jsonWr.beginArray("hwngroups");
|
for(String groupName : setGroups)
|
{
|
jsonWr.addKeyValue(null, groupName);
|
}
|
jsonWr.endArray();
|
|
_jsonSwaggerApiDoc = jsonWr.getRootJson();
|
|
}
|
return _jsonSwaggerApiDoc;
|
}
|
|
private void parseSwaggerRespnseJson(Json jsonResponses, SMTJsonWriter jsonWr)
|
{
|
for(Json jsonResponse : jsonResponses.asJsonList())
|
{
|
String type = jsonResponse.safeGetStr("type", "string");
|
String name = jsonResponse.getJson("name").asString();
|
String title = jsonResponse.safeGetStr("title", null);
|
String defValue = jsonResponse.safeGetStr("default", null);
|
boolean required = jsonResponse.safeGetBoolean("required", true);
|
String subType = null;
|
|
if(type.endsWith("[]"))
|
{
|
subType = type.substring(0, type.length() - 2);
|
type = "array";
|
}
|
|
jsonWr.beginMap(name);
|
{
|
jsonWr.addKeyValue("type", type);
|
jsonWr.addKeyValue("required", required);
|
if(!SMTStatic.isNullOrEmpty(defValue))
|
jsonWr.addKeyValue("default", title);
|
if(!SMTStatic.isNullOrEmpty(title))
|
jsonWr.addKeyValue("description", title);
|
|
if("array".equals(type))
|
{
|
jsonWr.beginMap("items");
|
{
|
jsonWr.addKeyValue("type", subType);
|
if("object".equals(subType))
|
{
|
jsonWr.beginMap("properties");
|
parseSwaggerRespnseJson(jsonResponse.getJson("children"), jsonWr);
|
jsonWr.endMap();
|
}
|
}
|
jsonWr.endMap();
|
}
|
else if("object".equals(type))
|
{
|
jsonWr.beginMap("properties");
|
parseSwaggerRespnseJson(jsonResponse.getJson("children"), jsonWr);
|
jsonWr.endMap();
|
}
|
}
|
jsonWr.endMap();
|
}
|
}
|
|
@Override
|
public void initEhCacheManager(CacheManager cacheManager)
|
{
|
for(String encacheId : _encacheIdList)
|
{
|
cacheManager.addCache(new Cache(encacheId, 1000, false, true, 100, 100));
|
}
|
|
}
|
|
@Override
|
public void clearEhCacheManager(CacheManager cacheManager)
|
{
|
for(String encacheId : _encacheIdList)
|
{
|
cacheManager.getCache(encacheId).removeAll();
|
}
|
}
|
|
public Object getGlobalConfig(String key, Object defValue) throws Exception
|
{
|
Map<String, Object> map = _serverEncache.queryGlobalConfigMap();
|
Object value = map.get(key);
|
if(value == null)
|
return defValue;
|
|
return value;
|
}
|
|
public Object getGlobalConfig(String key) throws Exception
|
{
|
Object value = getGlobalConfig(key, null);
|
if(value == null)
|
throw new Exception("can't find global key : " + key);
|
|
return value;
|
}
|
|
public Json queryAIPythonServer(String url, SMTJsonWriter jsonWr) throws Exception
|
{
|
String urlRoot = (String) getGlobalConfig("aipython.url");
|
SMTHttpClient web = new SMTHttpClient();
|
return web.postHttpBodyToJson(urlRoot + url, jsonWr.getFullJson(), null);
|
}
|
|
public String createQuestionSession(SMTDatabase db, String question, SMTJsonWriter jsonResult) throws Exception
|
{
|
String sessionId = SMTStatic.newUUID();
|
db.executeSQL(
|
"INSERT INTO ai_question_session(session_id, create_time, question, result_json)VALUES(?, ?, ?, ?)", new Object[] {
|
sessionId,
|
new Date(),
|
question,
|
jsonResult.getFullJson()
|
});
|
|
return sessionId;
|
}
|
|
@Override
|
public void sessionCreated(HttpSessionEvent event) throws Exception
|
{
|
synchronized(_mapSess2AsyncProcId2Process)
|
{
|
_mapSess2AsyncProcId2Process.put(event.getSession().getId(), new HashMap<>());
|
}
|
|
}
|
|
@Override
|
public void sessionDestroyed(HttpSessionEvent event) throws Exception
|
{
|
String sessionId = event.getSession().getId();
|
|
synchronized(_mapSess2AsyncProcId2Process)
|
{
|
_mapSess2AsyncProcId2Process.remove(sessionId);
|
}
|
|
synchronized(_mapSess2ChatStreamReply)
|
{
|
_mapSess2ChatStreamReply.remove(sessionId);
|
}
|
|
synchronized(_mapUser2SMTSSEBroadcastChat)
|
{
|
// 因为不知道所属用户,所以需要扫描一下用户
|
for(SMTSSEBroadcastChat chat : _mapUser2SMTSSEBroadcastChat.values())
|
{
|
if(chat.removeSSEConnect(sessionId))
|
break;
|
}
|
}
|
}
|
|
public void clearChatStreamReply(String sessionId)
|
{
|
synchronized(_mapSess2ChatStreamReply)
|
{
|
_mapSess2ChatStreamReply.remove(sessionId);
|
}
|
}
|
|
public void setChatStreamReply(String sessionId, String replyId, Json jsonReply)
|
{
|
synchronized(_mapSess2ChatStreamReply)
|
{
|
_mapSess2ChatStreamReply.put(sessionId, new SessionChatStreamReply(replyId, jsonReply));
|
}
|
}
|
|
public Json getChatStreamReply(String sessionId, String replyId)
|
{
|
SessionChatStreamReply reply = null;
|
synchronized(_mapSess2ChatStreamReply)
|
{
|
reply = _mapSess2ChatStreamReply.get(sessionId);
|
if(reply == null || !reply._replyId.equals(replyId))
|
return null;
|
|
return reply._jsonReply;
|
}
|
|
|
}
|
|
public void removeAsyncProcessText(String sessionId, String processId)
|
{
|
synchronized(_mapSess2AsyncProcId2Process)
|
{
|
Map<String, String> mapId2Process = _mapSess2AsyncProcId2Process.get(sessionId);
|
if(mapId2Process == null)
|
return;
|
mapId2Process.remove(processId);
|
}
|
}
|
|
public void setAsyncProcessText(String sessionId, String processId, String text)
|
{
|
synchronized(_mapSess2AsyncProcId2Process)
|
{
|
Map<String, String> mapId2Process = _mapSess2AsyncProcId2Process.get(sessionId);
|
if(mapId2Process == null)
|
return;
|
mapId2Process.put(processId, text);
|
}
|
}
|
|
public String getAsyncProcessText(String sessionId, String processId)
|
{
|
synchronized(_mapSess2AsyncProcId2Process)
|
{
|
Map<String, String> mapId2Process = _mapSess2AsyncProcId2Process.get(sessionId);
|
if(mapId2Process == null)
|
return null;
|
|
return mapId2Process.get(processId);
|
|
}
|
}
|
|
public Map<String, SMTDataSource> getDataSourceMap() throws Exception
|
{
|
return _serverEncache.queryDataSourceMap();
|
}
|
|
public SMTDataSource getDataSource(String id) throws Exception
|
{
|
Map<String, SMTDataSource> map = getDataSourceMap();
|
SMTDataSource result = map.get(id);
|
if(result == null)
|
throw new Exception("data source is not exist : " + id);
|
|
return result;
|
}
|
|
public SMTDimensionDef getDimensionDef(String id) throws Exception
|
{
|
Map<String, SMTDimensionDef> map = _serverEncache.queryDimensionMap();
|
SMTDimensionDef dimDef = map.get(id);
|
if(dimDef == null)
|
throw new Exception("can't find dimension def : " + id);
|
|
return dimDef;
|
}
|
|
public Map<String, SMTDimensionDef> getDimensionDefMap() throws Exception
|
{
|
return _serverEncache.queryDimensionMap();
|
}
|
|
public String convGlobalMacroString(String str, Json jsonExtMacro) throws Exception
|
{
|
while(true)
|
{
|
boolean hasMatcher = false;
|
Matcher m = _patGlobalMacro.matcher(str);
|
String newStr = str;
|
while(m.find())
|
{
|
hasMatcher = true;
|
|
String newValue = null;
|
|
if(jsonExtMacro != null)
|
newValue = jsonExtMacro.safeGetStr(m.group(1), null);
|
if(newValue != null)
|
{
|
newStr = str.replace(m.group(), newValue);
|
}
|
else
|
{
|
newStr = str.replace(m.group(), (String)this.getGlobalConfig(m.group(1)));
|
}
|
}
|
str = newStr;
|
if(!hasMatcher)
|
return newStr;
|
}
|
|
}
|
|
public static String formatXmlToNoRootStr(Document doc) throws Exception
|
{
|
OutputFormat format = OutputFormat.createPrettyPrint();
|
format.setEncoding("UTF-8");
|
format.setNewLineAfterDeclaration(false);
|
format.setNewlines(true);
|
format.setTrimText(false);
|
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
XMLWriter writer= new XMLWriter(bos,format);
|
writer.setEscapeText(true);
|
|
writer.write(doc);
|
writer.close();
|
String str = bos.toString("UTF-8");
|
|
int posS = str.indexOf("<ROOT>");
|
if(posS < 0)
|
throw new Exception("can't find <ROOT>");
|
int posE = str.lastIndexOf("</ROOT>");
|
if(posE < 0)
|
throw new Exception("can't find </ROOT>");
|
|
String[] lines = str.substring(posS + 6, posE).replace("\r\n", "\n").split("\n");
|
StringBuilder sb = new StringBuilder();
|
for(String line : lines)
|
{
|
if(line.trim().length() == 0)
|
continue;
|
sb.append(line + "\n");
|
}
|
|
return sb.toString();
|
}
|
|
public SMTQwenAgentManager getQwenAgentManager() throws Exception
|
{
|
return this._serverEncache.getQwenAgentManager();
|
}
|
|
public int getOutputAITableMax() throws Exception
|
{
|
return SMTStatic.toInt(getGlobalConfig("ai_table_output.max_rows", "100"));
|
}
|
|
public void clearQwenAgentManager() throws Exception
|
{
|
EhCacheCacheManager springCacheManager = SMTApp.getBean(EhCacheCacheManager.class);
|
if(springCacheManager != null)
|
{
|
CacheManager cacheManager = springCacheManager.getCacheManager();
|
cacheManager.getCache("QwenAgentManager").removeAll();
|
}
|
}
|
|
public static String convTimeStepToUnitStr(int unit, int value)
|
{
|
if(unit == 0)
|
{
|
int deltaDay = 24 * 60;
|
if((value % deltaDay) == 0)
|
return SMTStatic.toString(value / deltaDay) + " days";
|
|
if((value % 60) == 0)
|
return SMTStatic.toString(value / 60) + " hours";
|
|
return SMTStatic.toString(value) + " minutes";
|
}
|
else
|
{
|
if((value % 12) == 0)
|
return SMTStatic.toString(value / 12) + " years";
|
|
return SMTStatic.toString(value) + " months";
|
}
|
|
}
|
|
public static String convTimeStepToStr(int unit, int value)
|
{
|
if(unit == 0)
|
{
|
int deltaDay = 24 * 60;
|
if((value % deltaDay) == 0)
|
return SMTStatic.toString(value / deltaDay) + "天";
|
|
if((value % 60) == 0)
|
return SMTStatic.toString(value / 60) + "时";
|
|
return SMTStatic.toString(value) + "分";
|
}
|
else
|
{
|
if((value % 12) == 0)
|
return SMTStatic.toString(value / 12) + "年";
|
|
return SMTStatic.toString(value) + "月";
|
}
|
|
}
|
|
public static int[] convStrToTimeStep(String sTimeStep)
|
{
|
int _timeStepUnit = 0;
|
int _timeStepValue = 0;
|
|
Matcher m = _patGroupStep.matcher(sTimeStep);
|
if(!m.find())
|
return null;
|
|
int groupStep = SMTStatic.toInt(m.group(1));
|
String sGroupUnit = m.group(2);
|
if("minutes".equals(sGroupUnit))
|
{
|
_timeStepUnit = 0;
|
_timeStepValue = groupStep;
|
}
|
else if("hours".equals(sGroupUnit) || "hour".equals(sGroupUnit))
|
{
|
_timeStepUnit = 0;
|
_timeStepValue = groupStep * 60;
|
}
|
else if("days".equals(sGroupUnit) || "day".equals(sGroupUnit))
|
{
|
_timeStepUnit = 0;
|
_timeStepValue = groupStep * 60 * 24;
|
}
|
else if("months".equals(sGroupUnit) || "month".equals(sGroupUnit))
|
{
|
_timeStepUnit = 1;
|
_timeStepValue = groupStep;
|
}
|
else if("years".equals(sGroupUnit) || "year".equals(sGroupUnit))
|
{
|
_timeStepUnit = 1;
|
_timeStepValue = groupStep * 12;
|
}
|
|
return new int[] {_timeStepUnit, _timeStepValue};
|
}
|
|
public ASTQuestionReplace getQueryAIQuestionReplace() throws Exception
|
{
|
return _serverEncache.getQueryAIQuestionReplace();
|
}
|
|
public double[] convMapToGisTransform(double[] pos) throws Exception
|
{
|
CoordinateTransform[] transforms = _serverEncache.getGisTransform();
|
|
double[] result = new double[pos.length];
|
for(int i = 0; i < pos.length; i += 2)
|
{
|
ProjCoordinate sourceCoord = new ProjCoordinate(pos[i + 0], pos[i + 1]);
|
ProjCoordinate targetCoord = new ProjCoordinate();
|
transforms[1].transform(sourceCoord, targetCoord);
|
result[i + 0] = targetCoord.x;
|
result[i + 1] = targetCoord.y;
|
}
|
|
return result;
|
}
|
|
public double[] convGisToMapTransform(double[] pos) throws Exception
|
{
|
CoordinateTransform[] transforms = _serverEncache.getGisTransform();
|
|
double[] result = new double[pos.length];
|
for(int i = 0; i < pos.length; i += 2)
|
{
|
ProjCoordinate sourceCoord = new ProjCoordinate(pos[i + 0], pos[i + 1]);
|
ProjCoordinate targetCoord = new ProjCoordinate();
|
transforms[0].transform(sourceCoord, targetCoord);
|
result[i + 0] = targetCoord.x;
|
result[i + 1] = targetCoord.y;
|
}
|
|
return result;
|
}
|
|
public SMTAIQueryDetail getQueryDetail(String id) throws Exception
|
{
|
SMTAIQueryDetail queryDetail = _serverEncache.getQueryDetailMap().get(id);
|
if(queryDetail == null)
|
throw new Exception("can't find query detail id : " + id);
|
|
return queryDetail;
|
}
|
|
public static Object unwrapObject(Object value)
|
{
|
if(value == null)
|
return null;
|
|
if(value instanceof Wrapper)
|
value = ((Wrapper)value).unwrap();
|
|
if(value instanceof Undefined)
|
return null;
|
|
if(value instanceof ConsString)
|
value = ((ConsString)value).toString();
|
|
return value;
|
}
|
|
public static void convJSToJsonWriter(Object jsObject, SMTJsonWriter jsonWr)
|
{
|
if(jsObject instanceof NativeObject)
|
{
|
NativeObject nvObject = (NativeObject)jsObject;
|
for(Entry<Object, Object> entry : nvObject.entrySet())
|
{
|
String key = SMTStatic.toString(unwrapObject(entry.getKey()));
|
putJSToJsonWriter(jsonWr, key, entry.getValue());
|
}
|
}
|
else if(jsObject instanceof NativeArray)
|
{
|
NativeArray arrObject =(NativeArray)jsObject;
|
for(int i = 0; i < arrObject.size(); i ++)
|
{
|
putJSToJsonWriter(jsonWr, null, arrObject.get(i));
|
}
|
}
|
}
|
|
public static void putJSToJsonWriter(SMTJsonWriter jsonWr, String jsonKey, Object jsObject)
|
{
|
if(jsObject instanceof NativeObject)
|
{
|
NativeObject nvObject = (NativeObject)jsObject;
|
jsonWr.beginMap(jsonKey);
|
for(Entry<Object, Object> entry : nvObject.entrySet())
|
{
|
String key = SMTStatic.toString(unwrapObject(entry.getKey()));
|
putJSToJsonWriter(jsonWr, key, entry.getValue());
|
}
|
jsonWr.endMap();
|
}
|
else if(jsObject instanceof NativeArray)
|
{
|
NativeArray arrObject =(NativeArray)jsObject;
|
jsonWr.beginArray(jsonKey);
|
for(int i = 0; i < arrObject.size(); i ++)
|
{
|
putJSToJsonWriter(jsonWr, null, arrObject.get(i));
|
}
|
jsonWr.endArray();
|
}
|
else
|
{
|
jsonWr.addKeyValue(jsonKey, unwrapObject(jsObject));
|
}
|
}
|
|
public static Object convJsonToJS(Json json)
|
{
|
if(json.isObject())
|
{
|
NativeObject nv = new NativeObject();
|
for(Entry<String, Json> entry : json.asJsonMap().entrySet())
|
{
|
putJSNotNullValue(nv, entry.getKey(), convJsonToJS(entry.getValue()));
|
}
|
return nv;
|
}
|
else if(json.isArray())
|
{
|
List<Object> list = new ArrayList<Object>();
|
for(Json subJson : json.asJsonList())
|
{
|
list.add(convJsonToJS(subJson));
|
}
|
|
return new NativeArray(list.toArray(new Object[list.size()]));
|
}
|
else if(json.isNull())
|
return null;
|
else
|
return json.getValue();
|
}
|
|
public static void putJSNotNullValue(NativeObject nv, String key, Object value)
|
{
|
if(value == null)
|
return;
|
if(_patIsNumber.matcher(key).find())
|
nv.put(Integer.parseInt(key), nv, value);
|
else
|
nv.put(key, nv, value);
|
}
|
|
public static Object getJSValue(NativeObject nv, String key) throws Exception
|
{
|
if(!nv.containsKey(key))
|
throw new Exception("NativeObject can't find key : " + key);
|
Object value = unwrapObject(nv.get(key));
|
if(value == null)
|
throw new Exception("NativeObject can't find key : " + key);
|
return value;
|
}
|
|
public static Object getJSValue(NativeObject nv, String key, Object defValue) throws Exception
|
{
|
Object okey;
|
if(_patIsNumber.matcher(key).find())
|
okey = Long.parseLong(key);
|
else
|
okey = key;
|
if(!nv.containsKey(okey))
|
return defValue;
|
Object value = unwrapObject(nv.get(okey));
|
if(value == null)
|
return defValue;
|
|
return value;
|
}
|
|
public SMTLLMConnect allocLLMConnect(String llmId) throws Exception
|
{
|
if(SMTStatic.isNullOrEmpty(llmId))
|
llmId = (String) getDefaultLLMId();
|
|
Map<String, SMTLLMFactory> map = _serverEncache.getLLMFactoryMap();
|
SMTLLMFactory factory = map.get(llmId);
|
if(factory == null)
|
throw new Exception("can't find llm factory : " + llmId);
|
|
return factory.allocLLM();
|
}
|
|
public String getGroupTypeByGroupId(String groupId) throws Exception
|
{
|
String groupType = _serverEncache.getGroupTypeMap().get(groupId);
|
if(groupType == null)
|
throw new Exception("can't find group id : " + groupId);
|
|
return groupType;
|
}
|
|
public SMTGisMapLayerDef getMapLayerDef(String layerId) throws Exception
|
{
|
SMTGisMapLayerDef mapLayerDef = _serverEncache.getMapLayerDef().get(layerId);
|
if(mapLayerDef == null)
|
throw new Exception("can't find layer id : " + layerId);
|
|
return mapLayerDef;
|
}
|
|
public Map<String, SMTGisMapLayerDef> getMapLayerDefMap() throws Exception
|
{
|
Map<String, SMTGisMapLayerDef> map = _serverEncache.getMapLayerDef();
|
|
return map;
|
}
|
|
public Map<String, SMTMapOtypeDef> getMapVPropDefMap() throws Exception
|
{
|
Map<String, SMTMapOtypeDef> map = _serverEncache.getMapVPropDefMap();
|
|
return map;
|
}
|
|
public SMTMapThemeTableDef getMapThemeTableDefMap(String id) throws Exception
|
{
|
SMTMapThemeTableDef themeTableDef = _serverEncache.getMapThemeTableDefMap().get(id);
|
if(themeTableDef == null)
|
throw new Exception("can't find theme table : " + id);
|
|
return themeTableDef;
|
}
|
|
public Map<String, SMTMapThemeDef> getMapThemeDefMap() throws Exception
|
{
|
return _serverEncache.getMapThemeDefMap();
|
}
|
|
public SMTMapThemeTableDef getMapThemeTableDef(String id) throws Exception
|
{
|
SMTMapThemeTableDef themeTableDef = _serverEncache.getMapThemeTableDefMap().get(id);
|
if(themeTableDef == null)
|
throw new Exception("can't find theme table define : " + id);
|
|
return themeTableDef;
|
}
|
|
public SMTMapThemeDef getMapThemeDef(String id) throws Exception
|
{
|
SMTMapThemeDef themeDef = _serverEncache.getMapThemeDefMap().get(id);
|
if(themeDef == null)
|
throw new Exception("can't find theme def : " + id);
|
|
return themeDef;
|
}
|
|
public Map<String, SMTAIAttachTableDef> getAttachTableDefMap() throws Exception
|
{
|
return _serverEncache.getAttachTableDefMap();
|
}
|
|
public SMTAIAttachTableDef getAttachTableDef(String id) throws Exception
|
{
|
SMTAIAttachTableDef attachTableDef = _serverEncache.getAttachTableDefMap().get(id);
|
if(attachTableDef == null)
|
throw new Exception("can't find attach table define : " + id);
|
|
return attachTableDef;
|
}
|
|
public Map<String, SMTAIAttachMetricDef> getAttachMetricDefMap() throws Exception
|
{
|
return _serverEncache.getAttachMetricDefMap();
|
}
|
|
public SMTAIAttachMetricDef getAttachMetricDef(String id) throws Exception
|
{
|
SMTAIAttachMetricDef attachMetricDef = _serverEncache.getAttachMetricDefMap().get(id);
|
if(attachMetricDef == null)
|
throw new Exception("can't find attach metric def : " + id);
|
|
return attachMetricDef;
|
}
|
|
/**
|
* 文件(word、pdf)转txt
|
*/
|
public static String fileTranslTxt(MultipartFile file) throws Exception {
|
InputStream inputStream = file.getInputStream();
|
try (BufferedInputStream bis = new BufferedInputStream(file.getInputStream())) {
|
String mimeType = file.getContentType();
|
if (mimeType != null) {
|
switch (mimeType) {
|
case "application/pdf":
|
_logger.info("文件类型是 PDF");
|
PDDocument document = PDDocument.load(inputStream);
|
PDFTextStripper stripper = new PDFTextStripper();
|
return stripper.getText(document);
|
case "application/vnd.openxmlformats-officedocument.wordprocessingml.document":
|
_logger.info("文件类型是 Word (DOCX)");
|
try (XWPFDocument docx = new XWPFDocument(bis)) {
|
XWPFWordExtractor docxExtractor = new XWPFWordExtractor(docx);
|
return docxExtractor.getText();
|
}
|
case "application/msword":
|
_logger.info("文件类型是 Word (DOC)");
|
try (HWPFDocument doc = new HWPFDocument(bis)) {
|
WordExtractor wordExtractor = new WordExtractor(doc);
|
return wordExtractor.getText();
|
}
|
case "text/plain":
|
_logger.info("文件类型是 TXT");
|
byte[] fileData = readAttachFile(file);
|
return new String(fileData, "UTF-8");
|
default:
|
_logger.info("未知文件类型: " + mimeType);
|
break;
|
}
|
} else {
|
_logger.info("无法获取文件类型");
|
}
|
} catch (Exception e) {
|
_logger.error("文件处理失败: " + e.getMessage());
|
throw new Exception("文件处理失败: " + e.getMessage());
|
}
|
return "";
|
}
|
public static byte[] readAttachFile(MultipartFile file) throws Exception
|
{
|
InputStream is = file.getInputStream();
|
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
byte[] data = new byte[1024 * 1024];
|
while(true)
|
{
|
int size = is.read(data);
|
if(size <= 0)
|
return bos.toByteArray();
|
|
bos.write(data, 0, size);
|
}
|
}
|
|
public static String buildUrl(
|
String active,
|
String tags,
|
String name,
|
String projectId,
|
String excludePinnedData,
|
int limit)
|
throws Exception {
|
// 使用Map来存储参数
|
Map<String, String> params = new HashMap<>();
|
params.put("active", active);
|
params.put("tags", tags);
|
params.put("name", name != null ? URLEncoder.encode(name, "UTF-8") : null);
|
params.put("projectId", projectId);
|
params.put("excludePinnedData", excludePinnedData);
|
params.put("limit", String.valueOf(limit));
|
|
String workflows = (String)SMTAIServerApp.getApp().getGlobalConfig("n8n_workflows");
|
// 基本URL
|
StringBuilder urlBuilder = new StringBuilder(workflows);
|
|
// 遍历map并构建URL
|
for (Map.Entry<String, String> entry : params.entrySet()) {
|
if (entry.getValue() != null) {
|
urlBuilder.append(entry.getKey())
|
.append("=")
|
.append(entry.getValue())
|
.append("&");
|
}
|
}
|
// 去除最后一个多余的&符号
|
String requestUrl = urlBuilder.toString();
|
if (requestUrl.endsWith("&")) {
|
requestUrl = requestUrl.substring(0, requestUrl.length() - 1);
|
}
|
return requestUrl;
|
}
|
public static List<String> extractParts(String input, Pattern pattern) {
|
Matcher matcher = pattern.matcher(input);
|
List<String> results = new ArrayList<>();
|
while (matcher.find()) {
|
results.add(matcher.group(1)); // 提取第一个捕获组内容
|
}
|
return results;
|
}
|
}
|