diff --git a/packages/plugins/package.json b/packages/plugins/package.json index 3ff76befb..353dbb8ac 100644 --- a/packages/plugins/package.json +++ b/packages/plugins/package.json @@ -3,11 +3,14 @@ "version": "1.0.0", "type": "module", "dependencies": { + "@types/pg": "^8.6.6", "axios": "^1.5.1", "duck-duck-scrape": "^2.2.5", "echarts": "5.4.1", "expr-eval": "^2.0.2", "lodash": "^4.17.21", + "mysql2": "^3.11.3", + "pg": "^8.10.0", "wikijs": "^6.4.1" }, "devDependencies": { diff --git a/packages/plugins/register.ts b/packages/plugins/register.ts index 7ffa23982..4798d51a6 100644 --- a/packages/plugins/register.ts +++ b/packages/plugins/register.ts @@ -25,7 +25,8 @@ const packagePluginList = [ 'duckduckgo/searchVideo', 'drawing', 'drawing/baseChart', - 'wiki' + 'wiki', + 'databaseConnection' ]; export const list = [...staticPluginList, ...packagePluginList]; diff --git a/packages/plugins/src/databaseConnection/index.ts b/packages/plugins/src/databaseConnection/index.ts new file mode 100644 index 000000000..1735e44bd --- /dev/null +++ b/packages/plugins/src/databaseConnection/index.ts @@ -0,0 +1,71 @@ +import { Client as PgClient } from 'pg'; // PostgreSQL 客户端 +import mysql from 'mysql2/promise'; // MySQL 客户端 + +type Props = { + databaseType: string; + host: string; + port: string; + databaseName: string; + user: string; + password: string; + sql: string; +}; + +type Response = Promise<{ + result: any; // 根据你的 SQL 查询结果类型调整 +}>; + +const main = async ({ + databaseType, + host, + port, + databaseName, + user, + password, + sql +}: Props): Response => { + let result; + + try { + if (databaseType === 'PostgreSQL') { + const client = new PgClient({ + host, + port: parseInt(port, 10), + database: databaseName, + user, + password + }); + + await client.connect(); + const res = await client.query(sql); + result = res.rows; + await client.end(); + } else if (databaseType === 'MySQL') { + const connection = await mysql.createConnection({ + host, + port: parseInt(port, 10), + database: databaseName, + user, + password + }); + + const [rows] = await connection.execute(sql); + result = rows; + await connection.end(); + } + return { + result + }; + } catch (error: unknown) { + // 使用类型断言来处理错误 + if (error instanceof Error) { + console.error('Database query error:', error.message); + throw new Error(error.message); + } else { + console.error('Database query error:', error); + throw new Error('An unknown error occurred'); + } + } +}; + +export default main; diff --git a/packages/plugins/src/databaseConnection/template.json b/packages/plugins/src/databaseConnection/template.json new file mode 100644 index 000000000..30cc57c83 --- /dev/null +++ b/packages/plugins/src/databaseConnection/template.json @@ -0,0 +1,759 @@ +{ + "author": "", + "version": "4811", + "name": "数据源配置", + "avatar": "core/workflow/template/datasource", + "intro": "可连接常用数据库,并执行sql", + "showStatus": true, + "weight": 10, + + "isTool": true, + "templateType": "tools", + + "workflow": { + "nodes": [ + { + "nodeId": "pluginInput", + "name": "workflow:template.plugin_start", + "intro": "workflow:intro_plugin_input", + "avatar": "core/workflow/template/workflowStart", + "flowNodeType": "pluginInput", + "showStatus": false, + "position": { + "x": 335.8310044079668, + "y": -260.8285440670886 + }, + "version": "481", + "inputs": [ + { + "renderTypeList": [ + "select" + ], + "selectedTypeIndex": 0, + "valueType": "string", + "canEdit": true, + "key": "databaseType", + "label": "databaseType", + "description": "数据库的类型", + "defaultValue": "", + "list": [ + { + "label": "MySQL", + "value": "MySQL" + }, + { + "label": "PostgreSQL", + "value": "PostgreSQL" + } + ], + "required": true + }, + { + "renderTypeList": [ + "input" + ], + "selectedTypeIndex": 0, + "valueType": "string", + "canEdit": true, + "key": "host", + "label": "host", + "description": "数据库连接host", + "defaultValue": "", + "required": true, + "list": [ + { + "label": "", + "value": "" + } + ] + }, + { + "renderTypeList": [ + "input" + ], + "selectedTypeIndex": 0, + "valueType": "string", + "canEdit": true, + "key": "port", + "label": "port", + "description": "数据库连接端口号", + "defaultValue": "", + "required": true, + "list": [ + { + "label": "", + "value": "" + } + ] + }, + { + "renderTypeList": [ + "input" + ], + "selectedTypeIndex": 0, + "valueType": "string", + "canEdit": true, + "key": "databaseName", + "label": "databaseName", + "description": "数据库名称", + "defaultValue": "", + "required": true, + "list": [ + { + "label": "", + "value": "" + } + ] + }, + { + "renderTypeList": [ + "input" + ], + "selectedTypeIndex": 0, + "valueType": "string", + "canEdit": true, + "key": "password", + "label": "password", + "description": "数据库密码", + "defaultValue": "", + "list": [ + { + "label": "", + "value": "" + } + ], + "required": true + }, + { + "renderTypeList": [ + "input" + ], + "selectedTypeIndex": 0, + "valueType": "string", + "canEdit": true, + "key": "user", + "label": "user", + "description": "数据库账号", + "defaultValue": "", + "list": [ + { + "label": "", + "value": "" + } + ], + "required": true + }, + { + "renderTypeList": [ + "reference" + ], + "selectedTypeIndex": 0, + "valueType": "string", + "canEdit": true, + "key": "sql", + "label": "sql", + "description": "sql语句,可以传入sql语句直接执行", + "defaultValue": "", + "list": [ + { + "label": "", + "value": "" + } + ], + "required": true, + "toolDescription": "sql语句,可以传入sql语句直接执行" + } + ], + "outputs": [ + { + "id": "databaseType", + "valueType": "string", + "key": "databaseType", + "label": "databaseType", + "type": "hidden" + }, + { + "id": "host", + "valueType": "string", + "key": "host", + "label": "host", + "type": "hidden" + }, + { + "id": "port", + "valueType": "string", + "key": "port", + "label": "port", + "type": "hidden" + }, + { + "id": "dataBaseName", + "valueType": "string", + "key": "databaseName", + "label": "databaseName", + "type": "hidden" + }, + { + "id": "dataBasePwd", + "valueType": "string", + "key": "password", + "label": "password", + "type": "hidden" + }, + { + "id": "user", + "valueType": "string", + "key": "user", + "label": "user", + "type": "hidden" + }, + { + "id": "sql", + "valueType": "string", + "key": "sql", + "label": "sql", + "type": "hidden" + } + ] + }, + { + "nodeId": "pluginOutput", + "name": "common:core.module.template.self_output", + "intro": "workflow:intro_custom_plugin_output", + "avatar": "core/workflow/template/pluginOutput", + "flowNodeType": "pluginOutput", + "showStatus": false, + "position": { + "x": 1788.4723692358186, + "y": -153.2313912808486 + }, + "version": "481", + "inputs": [ + { + "renderTypeList": [ + "reference" + ], + "valueType": "string", + "canEdit": true, + "key": "result", + "label": "result", + "isToolOutput": true, + "description": "数据库连接结果", + "value": [ + "zBeXy7YZEiXe", + "httpRawResponse" + ] + } + ], + "outputs": [] + }, + { + "nodeId": "pluginConfig", + "name": "common:core.module.template.system_config", + "intro": "", + "avatar": "core/workflow/template/systemConfig", + "flowNodeType": "pluginConfig", + "position": { + "x": -133.25818142678844, + "y": -200.98784849888733 + }, + "version": "4811", + "inputs": [], + "outputs": [] + }, + { + "nodeId": "zBeXy7YZEiXe", + "name": "数据库连接", + "intro": "可以发出一个 HTTP 请求,实现更为复杂的操作(联网搜索、数据库查询等)", + "avatar": "core/workflow/template/httpRequest", + "flowNodeType": "httpRequest468", + "showStatus": true, + "position": { + "x": 1035.92763304296, + "y": -498.57137296107504 + }, + "version": "481", + "inputs": [ + { + "key": "system_addInputParam", + "renderTypeList": [ + "addInputParam" + ], + "valueType": "dynamic", + "label": "", + "required": false, + "description": "common:core.module.input.description.HTTP Dynamic Input", + "customInputConfig": { + "selectValueTypeList": [ + "string", + "number", + "boolean", + "object", + "arrayString", + "arrayNumber", + "arrayBoolean", + "arrayObject", + "arrayAny", + "any", + "chatHistory", + "datasetQuote", + "dynamic", + "selectApp", + "selectDataset" + ], + "showDescription": false, + "showDefaultValue": true + }, + "valueDesc": "", + "debugLabel": "", + "toolDescription": "" + }, + { + "key": "system_httpMethod", + "renderTypeList": [ + "custom" + ], + "valueType": "string", + "label": "", + "value": "POST", + "required": true, + "valueDesc": "", + "description": "", + "debugLabel": "", + "toolDescription": "" + }, + { + "key": "system_httpTimeout", + "renderTypeList": [ + "custom" + ], + "valueType": "number", + "label": "", + "value": 30, + "min": 5, + "max": 600, + "required": true, + "valueDesc": "", + "description": "", + "debugLabel": "", + "toolDescription": "" + }, + { + "key": "system_httpReqUrl", + "renderTypeList": [ + "hidden" + ], + "valueType": "string", + "label": "", + "description": "common:core.module.input.description.Http Request Url", + "placeholder": "https://api.ai.com/getInventory", + "required": false, + "value": "databaseConnection", + "valueDesc": "", + "debugLabel": "", + "toolDescription": "" + }, + { + "key": "system_httpHeader", + "renderTypeList": [ + "custom" + ], + "valueType": "any", + "value": [], + "label": "", + "description": "common:core.module.input.description.Http Request Header", + "placeholder": "common:core.module.input.description.Http Request Header", + "required": false, + "valueDesc": "", + "debugLabel": "", + "toolDescription": "" + }, + { + "key": "system_httpParams", + "renderTypeList": [ + "hidden" + ], + "valueType": "any", + "value": [], + "label": "", + "required": false, + "valueDesc": "", + "description": "", + "debugLabel": "", + "toolDescription": "" + }, + { + "key": "system_httpJsonBody", + "renderTypeList": [ + "hidden" + ], + "valueType": "any", + "value": "{\r\n \"databaseType\":\"{{databaseType-H}}\",\r\n \"host\":\"{{host-H}}\",\r\n \"port\":\"{{port-H}}\",\r\n \"databaseName\":\"{{databaseName-H}}\",\r\n \"user\":\"{{databaseUser-H}}\",\r\n \"password\":\"{{databasePwd-H}}\",\r\n \"sql\":\"{{sql-H}}\"\r\n}", + "label": "", + "required": false, + "valueDesc": "", + "description": "", + "debugLabel": "", + "toolDescription": "" + }, + { + "key": "system_httpFormBody", + "renderTypeList": [ + "hidden" + ], + "valueType": "any", + "value": [], + "label": "", + "required": false, + "valueDesc": "", + "description": "", + "debugLabel": "", + "toolDescription": "" + }, + { + "key": "system_httpContentType", + "renderTypeList": [ + "hidden" + ], + "valueType": "string", + "value": "json", + "label": "", + "required": false, + "valueDesc": "", + "description": "", + "debugLabel": "", + "toolDescription": "" + }, + { + "renderTypeList": [ + "reference" + ], + "valueType": "string", + "canEdit": true, + "key": "databaseType-H", + "label": "databaseType-H", + "customInputConfig": { + "selectValueTypeList": [ + "string", + "number", + "boolean", + "object", + "arrayString", + "arrayNumber", + "arrayBoolean", + "arrayObject", + "arrayAny", + "any", + "chatHistory", + "datasetQuote", + "dynamic", + "selectApp", + "selectDataset" + ], + "showDescription": false, + "showDefaultValue": true + }, + "required": true, + "value": [ + "pluginInput", + "databaseType" + ] + }, + { + "renderTypeList": [ + "reference" + ], + "valueType": "string", + "canEdit": true, + "key": "host-H", + "label": "host-H", + "customInputConfig": { + "selectValueTypeList": [ + "string", + "number", + "boolean", + "object", + "arrayString", + "arrayNumber", + "arrayBoolean", + "arrayObject", + "arrayAny", + "any", + "chatHistory", + "datasetQuote", + "dynamic", + "selectApp", + "selectDataset" + ], + "showDescription": false, + "showDefaultValue": true + }, + "required": true, + "value": [ + "pluginInput", + "host" + ] + }, + { + "renderTypeList": [ + "reference" + ], + "valueType": "string", + "canEdit": true, + "key": "port-H", + "label": "port-H", + "customInputConfig": { + "selectValueTypeList": [ + "string", + "number", + "boolean", + "object", + "arrayString", + "arrayNumber", + "arrayBoolean", + "arrayObject", + "arrayAny", + "any", + "chatHistory", + "datasetQuote", + "dynamic", + "selectApp", + "selectDataset" + ], + "showDescription": false, + "showDefaultValue": true + }, + "required": true, + "value": [ + "pluginInput", + "port" + ] + }, + { + "renderTypeList": [ + "reference" + ], + "valueType": "string", + "canEdit": true, + "key": "databaseName-H", + "label": "databaseName-H", + "customInputConfig": { + "selectValueTypeList": [ + "string", + "number", + "boolean", + "object", + "arrayString", + "arrayNumber", + "arrayBoolean", + "arrayObject", + "arrayAny", + "any", + "chatHistory", + "datasetQuote", + "dynamic", + "selectApp", + "selectDataset" + ], + "showDescription": false, + "showDefaultValue": true + }, + "required": true, + "value": [ + "pluginInput", + "dataBaseName" + ] + }, + { + "renderTypeList": [ + "reference" + ], + "valueType": "string", + "canEdit": true, + "key": "databasePwd-H", + "label": "databasePwd-H", + "customInputConfig": { + "selectValueTypeList": [ + "string", + "number", + "boolean", + "object", + "arrayString", + "arrayNumber", + "arrayBoolean", + "arrayObject", + "arrayAny", + "any", + "chatHistory", + "datasetQuote", + "dynamic", + "selectApp", + "selectDataset" + ], + "showDescription": false, + "showDefaultValue": true + }, + "required": true, + "value": [ + "pluginInput", + "dataBasePwd" + ] + }, + { + "renderTypeList": [ + "reference" + ], + "valueType": "string", + "canEdit": true, + "key": "databaseUser-H", + "label": "databaseUser-H", + "customInputConfig": { + "selectValueTypeList": [ + "string", + "number", + "boolean", + "object", + "arrayString", + "arrayNumber", + "arrayBoolean", + "arrayObject", + "arrayAny", + "any", + "chatHistory", + "datasetQuote", + "dynamic", + "selectApp", + "selectDataset" + ], + "showDescription": false, + "showDefaultValue": true + }, + "required": true, + "value": [ + "pluginInput", + "user" + ] + }, + { + "renderTypeList": [ + "reference" + ], + "valueType": "string", + "canEdit": true, + "key": "sql-H", + "label": "sql-H", + "customInputConfig": { + "selectValueTypeList": [ + "string", + "number", + "boolean", + "object", + "arrayString", + "arrayNumber", + "arrayBoolean", + "arrayObject", + "arrayAny", + "any", + "chatHistory", + "datasetQuote", + "dynamic", + "selectApp", + "selectDataset" + ], + "showDescription": false, + "showDefaultValue": true + }, + "required": true, + "value": [ + "pluginInput", + "sql" + ] + } + ], + "outputs": [ + { + "id": "error", + "key": "error", + "label": "workflow:request_error", + "description": "HTTP请求错误信息,成功时返回空", + "valueType": "object", + "type": "static" + }, + { + "id": "httpRawResponse", + "key": "httpRawResponse", + "required": true, + "label": "workflow:raw_response", + "description": "HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。", + "valueType": "any", + "type": "static" + }, + { + "id": "system_addOutputParam", + "key": "system_addOutputParam", + "type": "dynamic", + "valueType": "dynamic", + "label": "", + "customFieldConfig": { + "selectValueTypeList": [ + "string", + "number", + "boolean", + "object", + "arrayString", + "arrayNumber", + "arrayBoolean", + "arrayObject", + "arrayAny", + "any", + "chatHistory", + "datasetQuote", + "dynamic", + "selectApp", + "selectDataset" + ], + "showDescription": false, + "showDefaultValue": false + }, + "valueDesc": "", + "description": "" + } + ] + } + ], + "edges": [ + { + "source": "pluginInput", + "target": "zBeXy7YZEiXe", + "sourceHandle": "pluginInput-source-right", + "targetHandle": "zBeXy7YZEiXe-target-left" + }, + { + "source": "zBeXy7YZEiXe", + "target": "pluginOutput", + "sourceHandle": "zBeXy7YZEiXe-source-right", + "targetHandle": "pluginOutput-target-left" + } + ], + "chatConfig": { + "welcomeText": "", + "variables": [], + "questionGuide": false, + "ttsConfig": { + "type": "web" + }, + "whisperConfig": { + "open": false, + "autoSend": false, + "autoTTSResponse": false + }, + "chatInputGuide": { + "open": false, + "textList": [], + "customUrl": "" + }, + "instruction": "数据源配置,支持主流数据库配置", + "_id": "670a23b31957c5b9899b4a4d" + } + } +} diff --git a/packages/web/components/common/Icon/constants.ts b/packages/web/components/common/Icon/constants.ts index 23ea01118..3ab4acc91 100644 --- a/packages/web/components/common/Icon/constants.ts +++ b/packages/web/components/common/Icon/constants.ts @@ -229,6 +229,8 @@ export const iconPaths = { 'core/workflow/template/extractJson': () => import('./icons/core/workflow/template/extractJson.svg'), 'core/workflow/template/wiki': () => import('./icons/core/workflow/template/wiki.svg'), + 'core/workflow/template/datasource': () => + import('./icons/core/workflow/template/datasource.svg'), 'core/workflow/template/fetchUrl': () => import('./icons/core/workflow/template/fetchUrl.svg'), 'core/workflow/template/formInput': () => import('./icons/core/workflow/template/formInput.svg'), 'core/workflow/template/getTime': () => import('./icons/core/workflow/template/getTime.svg'), diff --git a/packages/web/components/common/Icon/icons/core/workflow/template/datasource.svg b/packages/web/components/common/Icon/icons/core/workflow/template/datasource.svg new file mode 100644 index 000000000..cad8390e6 --- /dev/null +++ b/packages/web/components/common/Icon/icons/core/workflow/template/datasource.svg @@ -0,0 +1 @@ + \ No newline at end of file