秦芳睿
2025-03-20 babbb668e1b305be8cb754b0b4d5efab908bc9ec
feat(server): 新增维度管理、样本管理、角色管理等功能

- 新增维度管理相关接口和功能
- 新增样本管理相关接口和功能
- 新增角色管理相关接口和功能
- 新增 n8n 工作流查询功能
- 优化 JSON flow节点处理逻辑
已修改9个文件
已添加1个文件
656 ■■■■■ 文件已修改
JAVA/SMTAIServer/src/main/java/com/smtaiserver/smtaiserver/control/SMTAIServerControl.java 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
JAVA/SMTAIServer/src/main/java/com/smtaiserver/smtaiserver/control/SMTMetricsManagerControl.java 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
JAVA/SMTAIServer/src/main/java/com/smtaiserver/smtaiserver/control/SMTSystemManagerControl.java 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
JAVA/SMTAIServer/src/main/java/com/smtaiserver/smtaiserver/control/SMTWorkflowManagerControl.java 128 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
JAVA/SMTAIServer/src/main/java/com/smtaiserver/smtaiserver/javaai/jsonflow/core/SMTJsonFlowManager.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
JAVA/SMTAIServer/src/main/java/com/smtaiserver/smtaiserver/javaai/jsonflow/node/SMTJsonFlowNodeN8n.java 144 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
JAVA/SMTAIServer/src/main/resources/requestmap/metric_manager.json 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
JAVA/SMTAIServer/src/main/resources/requestmap/server_api.json 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
JAVA/SMTAIServer/src/main/resources/requestmap/system_manager.json 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
JAVA/SMTAIServer/src/main/resources/requestmap/workflow_manager.json 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
JAVA/SMTAIServer/src/main/java/com/smtaiserver/smtaiserver/control/SMTAIServerControl.java
@@ -530,8 +530,82 @@
            db.close();
        }       
    }
    public ModelAndView addSceneSample(SMTAIServerRequest tranReq) throws Exception {
        String groupId = tranReq.convParamToString("group_id", true);
        String sampleId = tranReq.convParamToString("sample_id", true);
        String sampleQuestion = tranReq.convParamToString("sample_question", true);
        String sampleTitle = tranReq.convParamToString("sample_title", true);
        String sampleEnable = tranReq.convParamToString("sample_enable", true);
        String autoTestSupervisor = tranReq.convParamToString("auto_test_supervisor", false);
        String autoTestJson = tranReq.convParamToString("auto_test_json", false);
        String autoTestMacro = tranReq.convParamToString("auto_test_macro", false);
        String autoTestNote = tranReq.convParamToString("auto_test_note", false);
        String autoTestEnable = tranReq.convParamToString("auto_test_enable", false);
        String sampleMatch = tranReq.convParamToString("sample_match", false);
    public ModelAndView createHistoryGroup(SMTAIServerRequest tranReq) throws Exception
        SMTDatabase db = SMTAIServerApp.getApp().allocDatabase();
        try {
            // æ£€æŸ¥æ ·æœ¬ID是否已存在
            String selectSql = "SELECT * FROM ai_doc.ai_scene_sample WHERE sample_id = ?";
            Object[] selectParams = {sampleId};
            if (db.querySQL(selectSql, selectParams).getRowCount() > 0) {
                return tranReq.returnJsonState(false, "样本ID已存在", null);
            }
            // æ’入新样本
            String insertSql = "INSERT INTO ai_doc.ai_scene_sample (group_id, sample_id, sample_question, sample_title, sample_enable, auto_test_supervisor, auto_test_json, auto_test_macro, auto_test_note, auto_test_enable, sample_match) " +
                    "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
            Object[] insertParams = {groupId, sampleId, sampleQuestion, sampleTitle, sampleEnable, autoTestSupervisor, autoTestJson, autoTestMacro, autoTestNote, autoTestEnable, sampleMatch};
            db.executeSQL(insertSql, insertParams);
            // è¿”回 JSON ç»“æžœ
            SMTJsonWriter jsonWr = tranReq.newReturnJsonWriter(true, null, null);
            return tranReq.returnJson(jsonWr);
        } finally {
            db.close();
        }
    }
    public ModelAndView updateSceneSample(SMTAIServerRequest tranReq) throws Exception {
        String sampleId = tranReq.convParamToString("sample_id", true);
        String sampleQuestion = tranReq.convParamToString("sample_question", false);
        String sampleTitle = tranReq.convParamToString("sample_title", false);
        String sampleEnable = tranReq.convParamToString("sample_enable", false);
        String autoTestSupervisor = tranReq.convParamToString("auto_test_supervisor", false);
        String autoTestJson = tranReq.convParamToString("auto_test_json", false);
        String autoTestMacro = tranReq.convParamToString("auto_test_macro", false);
        String autoTestNote = tranReq.convParamToString("auto_test_note", false);
        String autoTestEnable = tranReq.convParamToString("auto_test_enable", false);
        String sampleMatch = tranReq.convParamToString("sample_match", false);
        SMTDatabase db = SMTAIServerApp.getApp().allocDatabase();
        try {
            // æ£€æŸ¥æ ·æœ¬ID是否存在
            String selectSql = "SELECT * FROM ai_doc.ai_scene_sample WHERE sample_id = ?";
            Object[] selectParams = {sampleId};
            if (db.querySQL(selectSql, selectParams).getRowCount() == 0) {
                return tranReq.returnJsonState(false, "样本ID不存在", null);
            }
            // æ›´æ–°æ ·æœ¬ä¿¡æ¯
            String updateSql = "UPDATE ai_doc.ai_scene_sample SET sample_question = ?, sample_title = ?, sample_enable = ?, auto_test_supervisor = ?, auto_test_json = ?, auto_test_macro = ?, auto_test_note = ?, auto_test_enable = ?, sample_match = ? WHERE sample_id = ?";
            Object[] updateParams = {sampleQuestion, sampleTitle, sampleEnable, autoTestSupervisor, autoTestJson, autoTestMacro, autoTestNote, autoTestEnable, sampleMatch, sampleId};
            db.executeSQL(updateSql, updateParams);
            // è¿”回 JSON ç»“æžœ
            SMTJsonWriter jsonWr = tranReq.newReturnJsonWriter(true, null, null);
            return tranReq.returnJson(jsonWr);
        } finally {
            db.close();
        }
    }
    public ModelAndView createHistoryGroup(SMTAIServerRequest tranReq) throws Exception
    {
        String groupTitle = tranReq.convParamToString("group_title", true);
        SMTDatabase db = SMTAIServerApp.getApp().allocDatabase();
JAVA/SMTAIServer/src/main/java/com/smtaiserver/smtaiserver/control/SMTMetricsManagerControl.java
@@ -108,7 +108,82 @@
            db.close();
        }        
    }
    public ModelAndView addDimension(SMTAIServerRequest tranReq) throws Exception {
        String loginUserId = tranReq.getLoginUserId();
        // è§£æžè¯·æ±‚参数
        String dimId = tranReq.convParamToString("dim_id", true);
        String dimTitle = tranReq.convParamToString("dim_title", true);
        String dimType = tranReq.convParamToString("dim_type", true);
        String dimAlias = tranReq.convParamToString("dim_alias", false);
        String dimName = tranReq.convParamToString("dim_name", true);
        String dimGroup = tranReq.convParamToString("dim_group", false);
        String dimUnit = tranReq.convParamToString("dim_unit", false);
        String dimValueList = tranReq.convParamToString("dim_value_list", false);
        SMTDatabase db = SMTAIServerApp.getApp().allocDatabase();
        try {
            // æ£€æŸ¥ç»´åº¦ID是否已存在
            String selectSql = "SELECT * FROM ai_doc.ai_dimension WHERE dim_id = ?";
            Object[] selectParams = {dimId};
            if (db.querySQL(selectSql, selectParams).getRowCount() > 0) {
                return tranReq.returnJsonState(false, "维度ID已存在", null);
            }
            // æž„建 SQL è¯­å¥
            String insertSql = "INSERT INTO ai_doc.ai_dimension (dim_id, dim_title, dim_type, dim_alias, dim_name, dim_group, dim_unit, dim_value_list) " +
                    "VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
            Object[] insertParams = {dimId, dimTitle, dimType, dimAlias, dimName, dimGroup, dimUnit, dimValueList};
            // æ‰§è¡Œæ’入操作
            db.executeSQL(insertSql, insertParams);
            // è¿”回 JSON ç»“æžœ
            SMTJsonWriter jsonWr = tranReq.newReturnJsonWriter(true, null, null);
            return tranReq.returnJson(jsonWr);
        } finally {
            db.close();
        }
    }
    public ModelAndView updateDimension(SMTAIServerRequest tranReq) throws Exception {
        // è§£æžè¯·æ±‚参数
        String dimId = tranReq.convParamToString("dim_id", true);
        String dimTitle = tranReq.convParamToString("dim_title", false);
        String dimType = tranReq.convParamToString("dim_type", false);
        String dimAlias = tranReq.convParamToString("dim_alias", false);
        String dimName = tranReq.convParamToString("dim_name", false);
        String dimGroup = tranReq.convParamToString("dim_group", false);
        String dimUnit = tranReq.convParamToString("dim_unit", false);
        String dimValueList = tranReq.convParamToString("dim_value_list", false);
        SMTDatabase db = SMTAIServerApp.getApp().allocDatabase();
        try {
            // æ£€æŸ¥ç»´åº¦ID是否存在
            String selectSql = "SELECT * FROM ai_doc.ai_dimension WHERE dim_id = ?";
            Object[] selectParams = {dimId};
            if (db.querySQL(selectSql, selectParams).getRowCount() == 0) {
                return tranReq.returnJsonState(false, "维度ID不存在", null);
            }
            // æž„建 SQL è¯­å¥
            String updateSql = "UPDATE ai_doc.ai_dimension SET dim_title = ?, dim_type = ?, dim_alias = ?, dim_name = ?, dim_group = ?, dim_unit = ?, dim_value_list = ? " +
                    "WHERE dim_id = ?";
            Object[] updateParams = {dimTitle, dimType, dimAlias, dimName, dimGroup, dimUnit, dimValueList, dimId};
            // æ‰§è¡Œæ›´æ–°æ“ä½œ
            db.executeSQL(updateSql, updateParams);
            // è¿”回 JSON ç»“æžœ
            SMTJsonWriter jsonWr = tranReq.newReturnJsonWriter(true, null, null);
            return tranReq.returnJson(jsonWr);
        } finally {
            db.close();
        }
    }
    public ModelAndView checkMetricsAgentValidate(SMTAIServerRequest tranReq) throws Exception 
    {
        String agentId = tranReq.convParamToString("agent_id", true);
JAVA/SMTAIServer/src/main/java/com/smtaiserver/smtaiserver/control/SMTSystemManagerControl.java
@@ -167,8 +167,65 @@
        {
            db.close();
        }
    }
    }
    public ModelAndView addRoleInfo(SMTAIServerRequest tranReq) throws Exception {
        String roleId = tranReq.convParamToString("role_id", true);
        String roleTitle = tranReq.convParamToString("role_title", true);
        SMTDatabase db = SMTAIServerApp.getApp().allocDatabase();
        try {
            // æ£€æŸ¥è§’色ID是否已存在
            String selectSql = "SELECT * FROM ai_sys.sys_role_info WHERE role_id = ?";
            Object[] selectParams = {roleId};
            if (db.querySQL(selectSql, selectParams).getRowCount() > 0) {
                return tranReq.returnJsonState(false, "角色ID已存在", null);
            }
            // æ’入新角色
            String insertSql = "INSERT INTO ai_sys.sys_role_info (role_id, role_title) VALUES (?, ?)";
            Object[] insertParams = {roleId, roleTitle};
            db.executeSQL(insertSql, insertParams);
            // è¿”回 JSON ç»“æžœ
            SMTJsonWriter jsonWr = tranReq.newReturnJsonWriter(true, null, null);
            return tranReq.returnJson(jsonWr);
        } finally {
            db.close();
        }
    }
    public ModelAndView updateRoleInfo(SMTAIServerRequest tranReq) throws Exception {
        String roleId = tranReq.convParamToString("role_id", true);
        String roleTitle = tranReq.convParamToString("role_title", false);
        SMTDatabase db = SMTAIServerApp.getApp().allocDatabase();
        try {
            // æ£€æŸ¥è§’色ID是否存在
            String selectSql = "SELECT * FROM ai_sys.sys_role_info WHERE role_id = ?";
            Object[] selectParams = {roleId};
            if (db.querySQL(selectSql, selectParams).getRowCount() == 0) {
                return tranReq.returnJsonState(false, "角色ID不存在", null);
            }
            // æ›´æ–°è§’色信息
            String updateSql = "UPDATE ai_sys.sys_role_info SET role_title = ? WHERE role_id = ?";
            Object[] updateParams = {roleTitle, roleId};
            db.executeSQL(updateSql, updateParams);
            // è¿”回 JSON ç»“æžœ
            SMTJsonWriter jsonWr = tranReq.newReturnJsonWriter(true, null, null);
            return tranReq.returnJson(jsonWr);
        } finally {
            db.close();
        }
    }
    public ModelAndView addUserInfo(SMTAIServerRequest tranReq) throws Exception
    {
        String userName = tranReq.convParamToString("user_name", true);
JAVA/SMTAIServer/src/main/java/com/smtaiserver/smtaiserver/control/SMTWorkflowManagerControl.java
@@ -1,9 +1,17 @@
package com.smtaiserver.smtaiserver.control;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSON;
import com.smtservlet.util.Json;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.dom4j.Document;
import org.springframework.web.servlet.ModelAndView;
@@ -18,8 +26,11 @@
import com.smtservlet.util.SMTJsonWriter;
import com.smtservlet.util.SMTStatic;
import static jdk.nashorn.internal.runtime.GlobalFunctions.encodeURIComponent;
public class SMTWorkflowManagerControl
{
    public static final String GET_WORKFLOWS = "http://localhost:15678/api/v1/workflows?";
    private static String[] _flowFuncNames = new String[] {
        "assessment",        "评估"
    };
@@ -399,4 +410,115 @@
        }
    }
    /**
     * æŸ¥è¯¢n8n工作流列表
     * @param tranReq
     * @return
     * @throws Exception
     */
    public ModelAndView getN8NNameList(SMTRequest tranReq) throws Exception {
        String active = tranReq.convParamToString("active", true);
        String tags = tranReq.convParamToString("tags", false);
        String name = tranReq.convParamToString("name", false);
        String projectId = tranReq.convParamToString("projectId", false);
        String excludePinnedData = tranReq.convParamToString("excludePinnedData", false);
        int limit = 250; // ä¸Šé™250条
        // æž„建请求URL
        String requestUrl = buildUrl(active, tags, name, projectId, excludePinnedData, limit);
        // åˆ›å»ºOkHttpClient对象
        OkHttpClient client = new OkHttpClient();
        String n8nApiKey = (String) SMTAIServerApp.getApp().getGlobalConfig("n8n_api_key", null);
        // åˆ›å»ºè¯·æ±‚头
        Request request = new Request.Builder()
                .url(requestUrl)
                .addHeader("X-N8N-API-KEY", n8nApiKey)
                .addHeader("accept", "application/json")
                .build();
        Response response = client.newCall(request).execute();
        String res = response.body().string();
        Json.Reader reader = new Json.Reader();
        Json read = (Json) reader.read(res, null);
        SMTJsonWriter jsonWriter = new SMTJsonWriter(false);
        // æž„建最终的返回数据结构
        List<Json> resultList = new ArrayList<>();
        try {
            if (response.body() != null) {
                List<Json> data = read.safeGetJsonList("data");
                for (Json date : data) {
                    String flOWName = date.safeGetStr("name", null);
                    String id = date.safeGetStr("id", null);
                    // åˆ›å»ºä¸€ä¸ªæ–°çš„ JSON å¯¹è±¡
                    SMTJsonWriter flowObj = new SMTJsonWriter(false);
                    flowObj.addKeyValue("id", id);
                    flowObj.addKeyValue("flOWName", flOWName);
                    List<Json> nodeList = date.safeGetJsonList("nodes");
                    for (Json node : nodeList) {
                        String type = node.safeGetStr("type", null);
                        if (type.equals("n8n-nodes-base.webhook")) {
                            Json parameters = node.safeGetJson("parameters");
                            String path = parameters.safeGetStr("path", null);
                            Pattern pattern = Pattern.compile("/:?([^/]+)");
                            List<String> pathRes = extractParts(path, pattern);
                            flowObj.addKeyValue("path", pathRes);
                        }
                    }
                    // å°†åˆ›å»ºçš„ flowObj æ·»åŠ åˆ° resultList ä¸­
                    resultList.add(flowObj.getRootJson());
                }
                // å°† resultList è®¾ç½®ä¸º "data" é”®çš„值
                jsonWriter.addKeyValue("data", resultList);
            }
            return tranReq.returnJson(jsonWriter);
        } catch (Exception e) {
            throw new Exception(e);
        }
    }
    public static String buildUrl(String active, String tags, String name, String projectId, String excludePinnedData, int limit) throws UnsupportedEncodingException {
        // ä½¿ç”¨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));
        // åŸºæœ¬URL
        StringBuilder urlBuilder = new StringBuilder(GET_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;
    }
    private 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;
    }
}
JAVA/SMTAIServer/src/main/java/com/smtaiserver/smtaiserver/javaai/jsonflow/core/SMTJsonFlowManager.java
@@ -4,6 +4,7 @@
import java.util.List;
import java.util.Map;
import com.smtaiserver.smtaiserver.javaai.jsonflow.node.*;
import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;
@@ -11,16 +12,6 @@
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import com.smtaiserver.smtaiserver.core.SMTAIServerRequest;
import com.smtaiserver.smtaiserver.javaai.SMTJavaAIError;
import com.smtaiserver.smtaiserver.javaai.jsonflow.node.SMTJsonFlowNodeAgent;
import com.smtaiserver.smtaiserver.javaai.jsonflow.node.SMTJsonFlowNodeCondJson;
import com.smtaiserver.smtaiserver.javaai.jsonflow.node.SMTJsonFlowNodeEnd;
import com.smtaiserver.smtaiserver.javaai.jsonflow.node.SMTJsonFlowNodeLLM;
import com.smtaiserver.smtaiserver.javaai.jsonflow.node.SMTJsonFlowNodeProcedure;
import com.smtaiserver.smtaiserver.javaai.jsonflow.node.SMTJsonFlowNodePython;
import com.smtaiserver.smtaiserver.javaai.jsonflow.node.SMTJsonFlowNodeScript;
import com.smtaiserver.smtaiserver.javaai.jsonflow.node.SMTJsonFlowNodeStart;
import com.smtaiserver.smtaiserver.javaai.jsonflow.node.SMTJsonFlowNodeTextResource;
import com.smtaiserver.smtaiserver.javaai.jsonflow.node.SMTJsonFlowNodeUserAsk;
import com.smtaiserver.smtaiserver.javaai.llm.core.SMTLLMConnect;
import com.smtservlet.util.Json;
@@ -98,6 +89,10 @@
            else if("python_code".equals(nodeType))
            {
                wfNode = new SMTJsonFlowNodePython();
            }
            else if("n8n".equals(nodeType))
            {
                wfNode = new SMTJsonFlowNodeN8n();
            }
            
            else
@@ -178,7 +173,7 @@
        execArg._stackNodeExec.addLast(_startNode.createFlowNodeExec());
        
        // æ‰§è¡ŒexecArg._stackNode中的节点,直至结束
        while(execArg._stackNodeExec.size() > 0)
        while(!execArg._stackNodeExec.isEmpty())
        {
            // æ‰§è¡Œä¸‹ä¸€ä¸ªèŠ‚ç‚¹
            SMTJsonFlowNodeExec flowNodeExec = execArg._stackNodeExec.pollFirst();
JAVA/SMTAIServer/src/main/java/com/smtaiserver/smtaiserver/javaai/jsonflow/node/SMTJsonFlowNodeN8n.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,144 @@
package com.smtaiserver.smtaiserver.javaai.jsonflow.node;
import com.smtaiserver.smtaiserver.core.SMTAIServerApp;
import com.smtaiserver.smtaiserver.javaai.SMTJavaAIError;
import com.smtaiserver.smtaiserver.javaai.jsonflow.core.SMTJsonFlowExecArg;
import com.smtaiserver.smtaiserver.javaai.jsonflow.core.SMTJsonFlowManager;
import com.smtaiserver.smtaiserver.javaai.jsonflow.core.SMTJsonFlowNodeOnlyOutput;
import com.smtaiserver.smtaiserver.javaai.qwen.SMTQwenApp;
import com.smtservlet.util.Json;
import com.smtservlet.util.SMTStatic;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
public class SMTJsonFlowNodeN8n extends SMTJsonFlowNodeOnlyOutput
{
    private String[]            _inputArg;
    private String                _outputArg;
    private String                _code;
    private static Logger         _logger = LogManager.getLogger(SMTQwenApp.class);
    @Override
    public void initInstane(SMTJsonFlowManager manager, Json jsonNode) throws Exception
    {
        super.initInstane(manager, jsonNode);
        List<Json> jsonGroupParams = jsonNode.getJsonPath("data|group_params|", false).asJsonList();
        for(Json jsonParams : jsonGroupParams)
        {
            String type = jsonParams.getJsonPath("params|0|type", false).asString();
            if("code_input".equals(type))
            {
                String sInputArg = jsonParams.getJsonPath("params|0|value|value", false).asString();
                if(!SMTStatic.isNullOrEmpty(sInputArg))
                    _inputArg = sInputArg.split(",");
            }
            else if("code_output".equals(type))
            {
                _outputArg = jsonParams.getJsonPath("params|0|value|value", false).asString();
            }
            else if("code".equals(type))
            {
                _code = jsonParams.getJsonPath("params|0|value", false).asString();
            }
        }
    }
    @Override
    public void afterInstance() throws Exception
    {
        super.afterInstance();
        if(SMTStatic.isNullOrEmpty(_code))
            throw new Exception("script function code is not define");
    }
    @Override
    public SMTJavaAIError executeFlowNode(SMTJsonFlowExecArg execArg) throws Exception
    {
        Json jsonPython = (Json)SMTAIServerApp.getApp().getGlobalConfig("python_env");
        String pyPath = jsonPython.getJson("path").asString();
        String argText = "";
        if(_inputArg != null && _inputArg.length > 0)
        {
            Json jsonArg = Json.object();
            for(String key : _inputArg)
            {
                jsonArg.set(key, execArg._jsonArgs.getJson(key));
            }
            argText = jsonArg.toString();
        }
        String id = SMTStatic.newUUID();
        File inputFile = new File(pyPath, "py_i_" + id);
        File outputFile = new File(pyPath, "py_o_" + id);
        File executeFile = new File(pyPath, "py_x_" + id);
        outputFile.delete();
        SMTStatic.saveTextFile(inputFile , argText);
        SMTStatic.saveTextFile(executeFile , _code);
        try
        {
            List<String> params = new ArrayList<String>();
            params.add(jsonPython.getJson("exec").asString());
            params.add(executeFile.getAbsolutePath());
            params.add(inputFile.getAbsolutePath());
            params.add(outputFile.getAbsolutePath());
            _logger.info("python : start : " + executeFile.getAbsolutePath());
            ProcessBuilder pbuilder=new ProcessBuilder(SMTStatic.convProcessArg(params));
            pbuilder.directory(new File(pyPath));
            pbuilder.redirectErrorStream(true);
            Process process = pbuilder.start();
            BufferedReader bufferedStdout = new BufferedReader(new InputStreamReader(process.getInputStream(), SMTStatic.getStdoutEncode()));
            execArg._tranReq.sendChunkedBlock("begin_stream", "");
            try
            {
                int size;
                char[] sBuf = new char[1024];
                while((size = bufferedStdout.read(sBuf)) > 0)
                {
                    String text = new String(sBuf, 0, size);
                    execArg._tranReq.sendChunkedStreamBlock(text);
                }
            }
            finally
            {
                execArg._tranReq.sendChunkedBlock("end_stream", "");
            }
            int exitCode = process.waitFor();
            _logger.info("python : end : " + exitCode + " : " + executeFile.getAbsolutePath());
            if(!SMTStatic.isNullOrEmpty(_outputArg))
            {
                if(outputFile.exists())
                {
                    String text = SMTStatic.readAllText(outputFile);
                    execArg._jsonArgs.set(_outputArg, text);
                }
                else
                {
                    execArg._jsonArgs.set(_outputArg, "");
                }
            }
        }
        finally
        {
            inputFile.delete();
            outputFile.delete();
            executeFile.delete();
        }
        return super.executeFlowNode(execArg);
    }
}
JAVA/SMTAIServer/src/main/resources/requestmap/metric_manager.json
@@ -8,6 +8,51 @@
            }
        ]
    },
    "admin/dimension/add_dimension": {
        "map": {
            "class": "#SMTMetricsManagerControl",
            "method": "addDimension"
        },
        "swaggers": [
            {
                "tags": ["维度管理"],
                "title": "新增维度",
                "parameters": [
                    {"name": "dim_id", "title": "维度ID", "required": true},
                    {"name": "dim_title", "title": "维度标题", "required": true},
                    {"name": "dim_type", "title": "维度类型", "required": true},
                    {"name": "dim_alias", "title": "维度别名", "required": false},
                    {"name": "dim_name", "title": "维度名称", "required": true},
                    {"name": "dim_group", "title": "维度分组", "required": false},
                    {"name": "dim_unit", "title": "维度单位", "required": false},
                    {"name": "dim_value_list", "title": "维度值列表", "required": false}
                ]
            }
        ]
    },
    "admin/dimension/update_dimension": {
        "map": {
            "class": "#SMTMetricsManagerControl",
            "method": "updateDimension"
        },
        "swaggers": [
            {
                "tags": ["维度管理"],
                "title": "修改维度",
                "parameters": [
                    {"name": "dim_id", "title": "维度ID", "required": true},
                    {"name": "dim_title", "title": "维度标题", "required": false},
                    {"name": "dim_type", "title": "维度类型", "required": false},
                    {"name": "dim_alias", "title": "维度别名", "required": false},
                    {"name": "dim_name", "title": "维度名称", "required": false},
                    {"name": "dim_group", "title": "维度分组", "required": false},
                    {"name": "dim_unit", "title": "维度单位", "required": false},
                    {"name": "dim_value_list", "title": "维度值列表", "required": false}
                ]
            }
        ]
    },
    "admin/metrics/get_metrics_agent_list":{"map":{"class":"#SMTMetricsManagerControl", "method":"getMetricsAgentList"},
            "swaggers":[
JAVA/SMTAIServer/src/main/resources/requestmap/server_api.json
@@ -110,8 +110,58 @@
            }
        ]
    },
    "admin/sample/add_scene_sample": {
        "map": {
            "class": "#AIServerControl",
            "method": "addSceneSample"
        },
        "swaggers": [
            {
                "tags": ["样本管理"],
                "title": "新增场景样本",
                "parameters": [
                    {"name": "group_id", "title": "分组唯一标识", "required": true},
                    {"name": "sample_id", "title": "样本唯一标识", "required": true},
                    {"name": "sample_question", "title": "样本问题内容", "required": true},
                    {"name": "sample_title", "title": "样本标题", "required": true},
                    {"name": "sample_enable", "title": "样本是否启用(Y/N)", "required": true},
                    {"name": "auto_test_supervisor", "title": "自动测试监督员", "required": false},
                    {"name": "auto_test_json", "title": "自动测试JSON配置", "required": false},
                    {"name": "auto_test_macro", "title": "自动测试宏配置", "required": false},
                    {"name": "auto_test_note", "title": "自动测试备注", "required": false},
                    {"name": "auto_test_enable", "title": "自动测试是否启用(Y/N)", "required": false},
                    {"name": "sample_match", "title": "样本匹配规则", "required": false}
                ]
            }
        ]
    },
    "admin/sample/update_scene_sample": {
        "map": {
            "class": "#AIServerControl",
            "method": "updateSceneSample"
        },
        "swaggers": [
            {
                "tags": ["样本管理"],
                "title": "更新场景样本",
                "parameters": [
                    {"name": "sample_id", "title": "样本唯一标识", "required": true},
                    {"name": "sample_question", "title": "样本问题内容", "required": false},
                    {"name": "sample_title", "title": "样本标题", "required": false},
                    {"name": "sample_enable", "title": "样本是否启用(Y/N)", "required": false},
                    {"name": "auto_test_supervisor", "title": "自动测试监督员", "required": false},
                    {"name": "auto_test_json", "title": "自动测试JSON配置", "required": false},
                    {"name": "auto_test_macro", "title": "自动测试宏配置", "required": false},
                    {"name": "auto_test_note", "title": "自动测试备注", "required": false},
                    {"name": "auto_test_enable", "title": "自动测试是否启用(Y/N)", "required": false},
                    {"name": "sample_match", "title": "样本匹配规则", "required": false}
                ]
            }
        ]
    },
    "history/create_history_group":{"map":{"class":"#AIServerControl", "method":"createHistoryGroup"},
            "swaggers":[
            {    "tags" : ["AI操作"],
JAVA/SMTAIServer/src/main/resources/requestmap/system_manager.json
@@ -91,6 +91,40 @@
            }
        ]
    },
    "admin/role/add_role_info": {
        "map": {
            "class": "#SMTSystemManagerControl",
            "method": "addRoleInfo"
        },
        "swaggers": [
            {
                "tags": ["角色管理"],
                "title": "新增角色信息",
                "parameters": [
                    {"name": "role_id", "title": "角色唯一标识ID", "required": true},
                    {"name": "role_title", "title": "角色名称", "required": true}
                ]
            }
        ]
    },
    "admin/role/update_role_info": {
        "map": {
            "class": "#SMTSystemManagerControl",
            "method": "updateRoleInfo"
        },
        "swaggers": [
            {
                "tags": ["角色管理"],
                "title": "更新角色信息",
                "parameters": [
                    {"name": "role_id", "title": "角色唯一标识ID", "required": true},
                    {"name": "role_title", "title": "角色名称", "required": false}
                ]
            }
        ]
    },
    "admin/log/get_operate_log":{"map":{"class":"#SMTSystemManagerControl", "method":"getOperateLog"},
            "swaggers":[
            {    "tags" : ["日志管理"],
@@ -252,7 +286,7 @@
            }
        ]
    },
    "admin/sample/add_question_replace": {"map": {"class": "#SMTSystemManagerControl", "method": "addQuestionReplace"} ,"no_shrio": true,
    "admin/sample/add_question_replace": {"map": {"class": "#SMTSystemManagerControl", "method": "addQuestionReplace"},
        "swaggers": [{
                "tags": ["新增问题置换参数"],
                "title": "新增问题置换参数",
@@ -267,7 +301,7 @@
            }
        ]
    },
    "admin/sample/update_question_replace": {"map": {"class": "#SMTSystemManagerControl", "method": "updateQuestionReplace"},"no_shrio": true ,
    "admin/sample/update_question_replace": {"map": {"class": "#SMTSystemManagerControl", "method": "updateQuestionReplace"} ,
        "swaggers": [{
                "tags": ["更新问题替换配置"],
                "title": "更新问题替换配置",
JAVA/SMTAIServer/src/main/resources/requestmap/workflow_manager.json
@@ -121,6 +121,20 @@
                ]
            }
        ]
    },
    "n8n/get_n8n_name_list":{"map":{"class":"#SMTWorkflowManagerControl", "method":"getN8NNameList"},"no_shrio": true,
            "swaggers":[
            {    "tags" : ["查询n8n工作流list"],
                "title" : "查询n8n工作流list",
                "parameters" : [
                    {"name":"active", "title":"active", "required":false},
                    {"name":"tags", "title":"tags", "required":false},
                    {"name":"name", "title":"name", "required":false},
                    {"name":"projectId", "title":"projectId", "required":false},
                    {"name":"excludePinnedData", "title":"excludePinnedData", "required":false}
                ]
            }
        ]
    }
}