diff --git a/apps/function_lib/migrations/0003_functionlib_function_type_functionlib_icon_and_more.py b/apps/function_lib/migrations/0003_functionlib_function_type_functionlib_icon_and_more.py
index 28f9c288c..beb5ac3bb 100644
--- a/apps/function_lib/migrations/0003_functionlib_function_type_functionlib_icon_and_more.py
+++ b/apps/function_lib/migrations/0003_functionlib_function_type_functionlib_icon_and_more.py
@@ -66,6 +66,55 @@ def langsearch(query, apikey):
else:
raise Exception(f"API请求失败: {response.status_code}, 错误信息: {response.text}")
return (response.text)', '{"{\\"name\\": \\"query\\", \\"type\\": \\"string\\", \\"source\\": \\"reference\\", \\"is_required\\": true}"}', 'f0dd8f71-e4ee-11ee-8c84-a8a1595801ab', TRUE, 'PUBLIC', 'INTERNAL', '/src/assets/fx/langsearch/icon.png', '[{"attrs": {"type": "password", "maxlength": 200, "minlength": 1, "show-password": true, "show-word-limit": true}, "field": "apikey", "label": "apikey", "required": true, "input_type": "PasswordInput", "props_info": {"rules": [{"message": "apikey 为必填属性", "required": true}, {"max": 200, "min": 1, "message": "apikey长度在 1 到 200 个字符", "trigger": "blur"}]}, "default_value": "x", "show_default_value": false}]', '', NULL);
+INSERT INTO function_lib (create_time, update_time, id, name, "desc", code, input_field_list, user_id, is_active, permission_type, function_type, icon, init_field_list, init_params, template_id) VALUES ('2025-03-17 07:37:54.620836 +00:00', '2025-03-17 07:37:54.620887 +00:00', 'bd1e8b88-0302-11f0-87bb-5618c4394482', 'PostgreSQL 查询', '', e'def queryPgSQL(dbname, user, password, host, port, query):
+ import psycopg2
+ import json
+ from datetime import datetime
+
+ # 自定义 JSON 序列化函数
+ def default_serializer(obj):
+ if isinstance(obj, datetime):
+ return obj.isoformat() # 将 datetime 转换为 ISO 格式字符串
+ raise TypeError(f"Type {type(obj)} not serializable")
+
+ # 数据库连接信息
+ conn_params = {
+ "dbname": dbname,
+ "user": user,
+ "password": password,
+ "host": host,
+ "port": port
+ }
+ try:
+ # 建立连接
+ conn = psycopg2.connect(**conn_params)
+ print("连接成功!")
+ # 创建游标对象
+ cursor = conn.cursor()
+ # 执行查询语句
+ cursor.execute(query)
+ # 获取查询结果
+ rows = cursor.fetchall()
+ # 如果能查到数据代表不是第一次提问,或者用户名为“请稍等”代表是企业微信不请求接口
+ if rows is None:
+ return json.dumps({"status": "no", "data": []})
+ else:
+ columns = [desc[0] for desc in cursor.description]
+ result = [dict(zip(columns, row)) for row in rows]
+ # 转换为 JSON 格式
+ json_result = json.dumps({"status": "yes", "data": result}, default=default_serializer,
+ ensure_ascii=False)
+ return json_result
+ except Exception as e:
+ print(f"发生错误:{e}")
+ raise e
+ finally:
+ # 关闭游标和连接
+ if cursor:
+ cursor.close()
+ if conn:
+ conn.close()
+', '{"{\"name\": \"query\", \"type\": \"string\", \"source\": \"reference\", \"is_required\": true}"}', 'f0dd8f71-e4ee-11ee-8c84-a8a1595801ab', true, 'PUBLIC', 'INTERNAL', '/src/assets/fx/postgresql/icon.png', '[{"attrs": {"maxlength": 200, "minlength": 1, "show-word-limit": true}, "field": "dbname", "label": "dbname", "required": true, "input_type": "TextInput", "props_info": {"rules": [{"message": "dbname 为必填属性", "required": true}, {"max": 200, "min": 1, "message": "dbname长度在 1 到 200 个字符", "trigger": "blur"}]}, "default_value": "x", "show_default_value": false}, {"attrs": {"maxlength": 200, "minlength": 1, "show-word-limit": true}, "field": "user", "label": "user", "required": true, "input_type": "TextInput", "props_info": {"rules": [{"message": "user 为必填属性", "required": true}, {"max": 200, "min": 1, "message": "user长度在 1 到 200 个字符", "trigger": "blur"}]}, "default_value": "x", "show_default_value": false}, {"attrs": {"type": "password", "maxlength": 200, "minlength": 1, "show-password": true, "show-word-limit": true}, "field": "password", "label": "password", "required": true, "input_type": "PasswordInput", "props_info": {"rules": [{"message": "password 为必填属性", "required": true}, {"max": 200, "min": 1, "message": "password长度在 1 到 200 个字符", "trigger": "blur"}]}, "default_value": "x", "show_default_value": false}, {"attrs": {"maxlength": 200, "minlength": 1, "show-word-limit": true}, "field": "host", "label": "host", "required": true, "input_type": "TextInput", "props_info": {"rules": [{"message": "host 为必填属性", "required": true}, {"max": 200, "min": 1, "message": "host长度在 1 到 200 个字符", "trigger": "blur"}]}, "default_value": "x", "show_default_value": false}, {"attrs": {"maxlength": 20, "minlength": 1, "show-word-limit": true}, "field": "port", "label": "port", "required": true, "input_type": "TextInput", "props_info": {"rules": [{"message": "port 为必填属性", "required": true}, {"max": 20, "min": 1, "message": "port长度在 1 到 20 个字符", "trigger": "blur"}]}, "default_value": "x", "show_default_value": false}]', null, null);
'''
diff --git a/ui/src/assets/fx/postgresql/icon.png b/ui/src/assets/fx/postgresql/icon.png
new file mode 100644
index 000000000..7893e74ea
Binary files /dev/null and b/ui/src/assets/fx/postgresql/icon.png differ
diff --git a/ui/src/assets/fx/postgresql/index.vue b/ui/src/assets/fx/postgresql/index.vue
new file mode 100644
index 000000000..c03b178d7
--- /dev/null
+++ b/ui/src/assets/fx/postgresql/index.vue
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
详情
+
+
+
+
+
+
\ No newline at end of file