feat: Support internal functionlib
--story=1017939 --user=刘瑞斌 【函数库】- 支持 系统内置函数 https://www.tapd.cn/57709429/s/1665943
This commit is contained in:
parent
ad0b032384
commit
510fae6bf1
@ -16,6 +16,7 @@ from application.flow.i_step_node import NodeResult
|
|||||||
from application.flow.step_node.function_lib_node.i_function_lib_node import IFunctionLibNode
|
from application.flow.step_node.function_lib_node.i_function_lib_node import IFunctionLibNode
|
||||||
from common.exception.app_exception import AppApiException
|
from common.exception.app_exception import AppApiException
|
||||||
from common.util.function_code import FunctionExecutor
|
from common.util.function_code import FunctionExecutor
|
||||||
|
from common.util.rsa_util import rsa_long_decrypt
|
||||||
from function_lib.models.function import FunctionLib
|
from function_lib.models.function import FunctionLib
|
||||||
from smartdoc.const import CONFIG
|
from smartdoc.const import CONFIG
|
||||||
|
|
||||||
@ -107,8 +108,11 @@ class BaseFunctionLibNodeNode(IFunctionLibNode):
|
|||||||
), **field}
|
), **field}
|
||||||
for field in
|
for field in
|
||||||
function_lib.input_field_list]}
|
function_lib.input_field_list]}
|
||||||
|
|
||||||
self.context['params'] = params
|
self.context['params'] = params
|
||||||
result = function_executor.exec_code(function_lib.code, params)
|
# 合并初始化参数
|
||||||
|
all_params = json.loads(rsa_long_decrypt(function_lib.init_params)) | params
|
||||||
|
result = function_executor.exec_code(function_lib.code, all_params)
|
||||||
return NodeResult({'result': result}, {}, _write_context=write_context)
|
return NodeResult({'result': result}, {}, _write_context=write_context)
|
||||||
|
|
||||||
def get_details(self, index: int, **kwargs):
|
def get_details(self, index: int, **kwargs):
|
||||||
|
|||||||
@ -45,7 +45,7 @@ from common.util.file_util import get_file_content
|
|||||||
from dataset.models import DataSet, Document, Image
|
from dataset.models import DataSet, Document, Image
|
||||||
from dataset.serializers.common_serializers import list_paragraph, get_embedding_model_by_dataset_id_list
|
from dataset.serializers.common_serializers import list_paragraph, get_embedding_model_by_dataset_id_list
|
||||||
from embedding.models import SearchMode
|
from embedding.models import SearchMode
|
||||||
from function_lib.models.function import FunctionLib, PermissionType
|
from function_lib.models.function import FunctionLib, PermissionType, FunctionType
|
||||||
from function_lib.serializers.function_lib_serializer import FunctionLibSerializer, FunctionLibModelSerializer
|
from function_lib.serializers.function_lib_serializer import FunctionLibSerializer, FunctionLibModelSerializer
|
||||||
from setting.models import AuthOperate, TeamMemberPermission
|
from setting.models import AuthOperate, TeamMemberPermission
|
||||||
from setting.models.model_management import Model
|
from setting.models.model_management import Model
|
||||||
@ -810,8 +810,10 @@ class ApplicationSerializer(serializers.Serializer):
|
|||||||
if with_valid:
|
if with_valid:
|
||||||
self.is_valid(raise_exception=True)
|
self.is_valid(raise_exception=True)
|
||||||
application = QuerySet(Application).filter(id=self.data.get("application_id")).first()
|
application = QuerySet(Application).filter(id=self.data.get("application_id")).first()
|
||||||
return FunctionLibSerializer.Query(data={'user_id': application.user_id, 'is_active': True}).list(
|
return FunctionLibSerializer.Query(
|
||||||
with_valid=True)
|
data={'user_id': application.user_id, 'is_active': True,
|
||||||
|
'function_type': FunctionType.PUBLIC}
|
||||||
|
).list(with_valid=True)
|
||||||
|
|
||||||
def get_function_lib(self, function_lib_id, with_valid=True):
|
def get_function_lib(self, function_lib_id, with_valid=True):
|
||||||
if with_valid:
|
if with_valid:
|
||||||
|
|||||||
@ -0,0 +1,107 @@
|
|||||||
|
# Generated by Django 4.2.15 on 2025-03-13 07:21
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
function_template = '''
|
||||||
|
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-10 06:20:35.945414 +00:00', '2025-03-10 09:19:23.608026 +00:00', 'c75cb48e-fd77-11ef-84d2-5618c4394482', '博查AI', '从博查搜索任何信息和网页URL', e'def bocha_search(query, apikey):
|
||||||
|
import requests
|
||||||
|
import json
|
||||||
|
url = "https://api.bochaai.com/v1/web-search"
|
||||||
|
payload = json.dumps({
|
||||||
|
"query": query,
|
||||||
|
"Boolean": "true",
|
||||||
|
"count": 8
|
||||||
|
})
|
||||||
|
|
||||||
|
headers = {
|
||||||
|
"Authorization": "Bearer " + apikey, #鉴权参数,示例:Bearer xxxxxx,API KEY请先前往博查AI开放平台(https://open.bochaai.com)> API KEY 管理中获取。
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
}
|
||||||
|
|
||||||
|
response = requests.request("POST", url, headers=headers, data=payload)
|
||||||
|
if response.status_code == 200:
|
||||||
|
return response.json()
|
||||||
|
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/bochaai/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-02-26 03:36:48.187286 +00:00', '2025-03-11 07:23:46.123972 +00:00', 'e89ad2ae-f3f2-11ef-ad09-0242ac110002', 'Google Search', 'Google Web Search', e'def google_search(query, apikey, cx):
|
||||||
|
import requests
|
||||||
|
import json
|
||||||
|
url = "https://customsearch.googleapis.com/customsearch/v1"
|
||||||
|
params = {
|
||||||
|
"q": query,
|
||||||
|
"key": apikey,
|
||||||
|
"cx": cx,
|
||||||
|
"num": 10, # 每次最多返回10条
|
||||||
|
}
|
||||||
|
|
||||||
|
response = requests.get(url, params=params)
|
||||||
|
if response.status_code == 200:
|
||||||
|
return response.json()
|
||||||
|
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/google_search/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}, {"attrs": {"maxlength": 200, "minlength": 1, "show-word-limit": true}, "field": "cx", "label": "cx", "required": true, "input_type": "TextInput", "props_info": {"rules": [{"message": "cx 为必填属性", "required": true}, {"max": 200, "min": 1, "message": "cx长度在 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-02-25 07:44:40.141515 +00:00', '2025-03-11 06:33:53.248495 +00:00', '5e912f00-f34c-11ef-8a9c-5618c4394482', 'LangSearch API', e'A Web Search API supporting natural language search
|
||||||
|
', e'
|
||||||
|
def langsearch(query, apikey):
|
||||||
|
import json
|
||||||
|
import requests
|
||||||
|
|
||||||
|
url = "https://api.langsearch.com/v1/web-search"
|
||||||
|
payload = json.dumps({
|
||||||
|
"query": query,
|
||||||
|
"summary": True,
|
||||||
|
"freshness": "noLimit",
|
||||||
|
"livecrawl": True,
|
||||||
|
"count": 20
|
||||||
|
})
|
||||||
|
headers = {
|
||||||
|
"Authorization": apikey,
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
}
|
||||||
|
# key从官网申请 https://langsearch.com/
|
||||||
|
response = requests.request("POST", url, headers=headers, data=payload)
|
||||||
|
if response.status_code == 200:
|
||||||
|
return response.json()
|
||||||
|
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);
|
||||||
|
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies = [
|
||||||
|
('function_lib', '0002_functionlib_is_active_functionlib_permission_type'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='functionlib',
|
||||||
|
name='function_type',
|
||||||
|
field=models.CharField(choices=[('INTERNAL', '内置'), ('PUBLIC', '公开')],
|
||||||
|
default='PUBLIC', max_length=20, verbose_name='函数类型'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='functionlib',
|
||||||
|
name='icon',
|
||||||
|
field=models.CharField(default='/ui/favicon.ico', max_length=256,
|
||||||
|
verbose_name='函数库icon'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='functionlib',
|
||||||
|
name='init_field_list',
|
||||||
|
field=models.JSONField(default=list, verbose_name='启动字段列表'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='functionlib',
|
||||||
|
name='init_params',
|
||||||
|
field=models.CharField(max_length=102400, null=True, verbose_name='初始化参数'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='functionlib',
|
||||||
|
name='template_id',
|
||||||
|
field=models.UUIDField(default=None, null=True, verbose_name='模版id'),
|
||||||
|
),
|
||||||
|
migrations.RunSQL(function_template)
|
||||||
|
]
|
||||||
@ -1,23 +0,0 @@
|
|||||||
# Generated by Django 4.2.15 on 2025-03-07 10:31
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('function_lib', '0002_functionlib_is_active_functionlib_permission_type'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='functionlib',
|
|
||||||
name='icon',
|
|
||||||
field=models.CharField(default='/ui/favicon.ico', max_length=256, verbose_name='函数库icon'),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='functionlib',
|
|
||||||
name='init_field_list',
|
|
||||||
field=models.JSONField(default=list, verbose_name='启动字段列表'),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
@ -19,6 +19,10 @@ class PermissionType(models.TextChoices):
|
|||||||
PUBLIC = "PUBLIC", '公开'
|
PUBLIC = "PUBLIC", '公开'
|
||||||
PRIVATE = "PRIVATE", "私有"
|
PRIVATE = "PRIVATE", "私有"
|
||||||
|
|
||||||
|
class FunctionType(models.TextChoices):
|
||||||
|
INTERNAL = "INTERNAL", '内置'
|
||||||
|
PUBLIC = "PUBLIC", "公开"
|
||||||
|
|
||||||
|
|
||||||
class FunctionLib(AppModelMixin):
|
class FunctionLib(AppModelMixin):
|
||||||
id = models.UUIDField(primary_key=True, max_length=128, default=uuid.uuid1, editable=False, verbose_name="主键id")
|
id = models.UUIDField(primary_key=True, max_length=128, default=uuid.uuid1, editable=False, verbose_name="主键id")
|
||||||
@ -34,6 +38,10 @@ class FunctionLib(AppModelMixin):
|
|||||||
is_active = models.BooleanField(default=True)
|
is_active = models.BooleanField(default=True)
|
||||||
permission_type = models.CharField(max_length=20, verbose_name='权限类型', choices=PermissionType.choices,
|
permission_type = models.CharField(max_length=20, verbose_name='权限类型', choices=PermissionType.choices,
|
||||||
default=PermissionType.PRIVATE)
|
default=PermissionType.PRIVATE)
|
||||||
|
function_type = models.CharField(max_length=20, verbose_name='函数类型', choices=FunctionType.choices,
|
||||||
|
default=FunctionType.PUBLIC)
|
||||||
|
template_id = models.UUIDField(max_length=128, verbose_name="模版id", null=True, default=None)
|
||||||
|
init_params = models.CharField(max_length=102400, verbose_name="初始化参数", null=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
db_table = "function_lib"
|
db_table = "function_lib"
|
||||||
|
|||||||
8
apps/function_lib/serializers/__init__.py
Normal file
8
apps/function_lib/serializers/__init__.py
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# coding=utf-8
|
||||||
|
"""
|
||||||
|
@project: MaxKB
|
||||||
|
@Author:虎
|
||||||
|
@file: __init__.py.py
|
||||||
|
@date:2024/8/2 14:55
|
||||||
|
@desc:
|
||||||
|
"""
|
||||||
@ -13,7 +13,7 @@ import uuid
|
|||||||
|
|
||||||
from django.core import validators
|
from django.core import validators
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from django.db.models import QuerySet, Q
|
from django.db.models import QuerySet, Q, OuterRef, Exists
|
||||||
from django.http import HttpResponse
|
from django.http import HttpResponse
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from rest_framework import serializers, status
|
from rest_framework import serializers, status
|
||||||
@ -24,8 +24,9 @@ from common.field.common import UploadedFileField, UploadedImageField
|
|||||||
from common.response import result
|
from common.response import result
|
||||||
from common.util.field_message import ErrMessage
|
from common.util.field_message import ErrMessage
|
||||||
from common.util.function_code import FunctionExecutor
|
from common.util.function_code import FunctionExecutor
|
||||||
from dataset.models import Image
|
from common.util.rsa_util import rsa_long_decrypt, rsa_long_encrypt
|
||||||
from function_lib.models.function import FunctionLib
|
from dataset.models import File
|
||||||
|
from function_lib.models.function import FunctionLib, PermissionType, FunctionType
|
||||||
from smartdoc.const import CONFIG
|
from smartdoc.const import CONFIG
|
||||||
|
|
||||||
function_executor = FunctionExecutor(CONFIG.get('SANDBOX'))
|
function_executor = FunctionExecutor(CONFIG.get('SANDBOX'))
|
||||||
@ -35,11 +36,33 @@ class FlibInstance:
|
|||||||
self.function_lib = function_lib
|
self.function_lib = function_lib
|
||||||
self.version = version
|
self.version = version
|
||||||
|
|
||||||
|
def encryption(message: str):
|
||||||
|
"""
|
||||||
|
加密敏感字段数据 加密方式是 如果密码是 1234567890 那么给前端则是 123******890
|
||||||
|
:param message:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
max_pre_len = 8
|
||||||
|
max_post_len = 4
|
||||||
|
message_len = len(message)
|
||||||
|
pre_len = int(message_len / 5 * 2)
|
||||||
|
post_len = int(message_len / 5 * 1)
|
||||||
|
pre_str = "".join([message[index] for index in
|
||||||
|
range(0,
|
||||||
|
max_pre_len if pre_len > max_pre_len else 1 if pre_len <= 0 else int(
|
||||||
|
pre_len))])
|
||||||
|
end_str = "".join(
|
||||||
|
[message[index] for index in
|
||||||
|
range(message_len - (int(post_len) if pre_len < max_post_len else max_post_len),
|
||||||
|
message_len)])
|
||||||
|
content = "***************"
|
||||||
|
return pre_str + content + end_str
|
||||||
|
|
||||||
|
|
||||||
class FunctionLibModelSerializer(serializers.ModelSerializer):
|
class FunctionLibModelSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = FunctionLib
|
model = FunctionLib
|
||||||
fields = ['id', 'name', 'icon', 'desc', 'code', 'input_field_list','init_field_list', 'permission_type', 'is_active', 'user_id',
|
fields = ['id', 'name', 'icon', 'desc', 'code', 'input_field_list','init_field_list', 'init_params', 'permission_type', 'is_active', 'user_id', 'template_id',
|
||||||
'create_time', 'update_time']
|
'create_time', 'update_time']
|
||||||
|
|
||||||
|
|
||||||
@ -66,6 +89,7 @@ class DebugInstance(serializers.Serializer):
|
|||||||
debug_field_list = DebugField(required=True, many=True)
|
debug_field_list = DebugField(required=True, many=True)
|
||||||
input_field_list = FunctionLibInputField(required=True, many=True)
|
input_field_list = FunctionLibInputField(required=True, many=True)
|
||||||
init_field_list = serializers.ListField(required=False, default=list)
|
init_field_list = serializers.ListField(required=False, default=list)
|
||||||
|
init_params = serializers.JSONField(required=False, default=dict)
|
||||||
code = serializers.CharField(required=True, error_messages=ErrMessage.char(_('function content')))
|
code = serializers.CharField(required=True, error_messages=ErrMessage.char(_('function content')))
|
||||||
|
|
||||||
|
|
||||||
@ -116,6 +140,8 @@ class FunctionLibSerializer(serializers.Serializer):
|
|||||||
|
|
||||||
user_id = serializers.UUIDField(required=True, error_messages=ErrMessage.uuid(_('user id')))
|
user_id = serializers.UUIDField(required=True, error_messages=ErrMessage.uuid(_('user id')))
|
||||||
select_user_id = serializers.CharField(required=False, allow_null=True, allow_blank=True)
|
select_user_id = serializers.CharField(required=False, allow_null=True, allow_blank=True)
|
||||||
|
function_type = serializers.CharField(required=False, allow_null=True, allow_blank=True)
|
||||||
|
|
||||||
|
|
||||||
def get_query_set(self):
|
def get_query_set(self):
|
||||||
query_set = QuerySet(FunctionLib).filter(
|
query_set = QuerySet(FunctionLib).filter(
|
||||||
@ -128,19 +154,38 @@ class FunctionLibSerializer(serializers.Serializer):
|
|||||||
query_set = query_set.filter(is_active=self.data.get('is_active'))
|
query_set = query_set.filter(is_active=self.data.get('is_active'))
|
||||||
if self.data.get('select_user_id') is not None:
|
if self.data.get('select_user_id') is not None:
|
||||||
query_set = query_set.filter(user_id=self.data.get('select_user_id'))
|
query_set = query_set.filter(user_id=self.data.get('select_user_id'))
|
||||||
|
if self.data.get('function_type') is not None:
|
||||||
|
query_set = query_set.filter(function_type=self.data.get('function_type'))
|
||||||
query_set = query_set.order_by("-create_time")
|
query_set = query_set.order_by("-create_time")
|
||||||
|
|
||||||
|
subquery = FunctionLib.objects.filter(template_id=OuterRef('id'))
|
||||||
|
subquery = subquery.filter(user_id=self.data.get('user_id'))
|
||||||
|
query_set = query_set.annotate(added=Exists(subquery))
|
||||||
|
|
||||||
return query_set
|
return query_set
|
||||||
|
|
||||||
def list(self, with_valid=True):
|
def list(self, with_valid=True):
|
||||||
if with_valid:
|
if with_valid:
|
||||||
self.is_valid(raise_exception=True)
|
self.is_valid(raise_exception=True)
|
||||||
return [FunctionLibModelSerializer(item).data for item in self.get_query_set()]
|
rs = []
|
||||||
|
for item in self.get_query_set():
|
||||||
|
data = {**FunctionLibModelSerializer(item).data, 'init_params': None}
|
||||||
|
rs.append(data)
|
||||||
|
return rs
|
||||||
|
|
||||||
def page(self, current_page: int, page_size: int, with_valid=True):
|
def page(self, current_page: int, page_size: int, with_valid=True):
|
||||||
if with_valid:
|
if with_valid:
|
||||||
self.is_valid(raise_exception=True)
|
self.is_valid(raise_exception=True)
|
||||||
|
|
||||||
|
def post_records_handler(row):
|
||||||
|
return {
|
||||||
|
**FunctionLibModelSerializer(row).data,
|
||||||
|
'added': row.added,
|
||||||
|
'init_params': None
|
||||||
|
}
|
||||||
|
|
||||||
return page_search(current_page, page_size, self.get_query_set(),
|
return page_search(current_page, page_size, self.get_query_set(),
|
||||||
post_records_handler=lambda row: FunctionLibModelSerializer(row).data)
|
post_records_handler=post_records_handler)
|
||||||
|
|
||||||
class Create(serializers.Serializer):
|
class Create(serializers.Serializer):
|
||||||
user_id = serializers.UUIDField(required=True, error_messages=ErrMessage.uuid(_('user id')))
|
user_id = serializers.UUIDField(required=True, error_messages=ErrMessage.uuid(_('user id')))
|
||||||
@ -169,8 +214,7 @@ class FunctionLibSerializer(serializers.Serializer):
|
|||||||
input_field_list = debug_instance.get('input_field_list')
|
input_field_list = debug_instance.get('input_field_list')
|
||||||
code = debug_instance.get('code')
|
code = debug_instance.get('code')
|
||||||
debug_field_list = debug_instance.get('debug_field_list')
|
debug_field_list = debug_instance.get('debug_field_list')
|
||||||
init_field_list = debug_instance.get('init_field_list')
|
init_params = debug_instance.get('init_params')
|
||||||
init_params = {field.get('field'): field.get('value') if field.get('value', None) is not None else field.get('default_value') for field in init_field_list}
|
|
||||||
params = {field.get('name'): self.convert_value(field.get('name'), field.get('value'), field.get('type'),
|
params = {field.get('name'): self.convert_value(field.get('name'), field.get('value'), field.get('type'),
|
||||||
field.get('is_required'))
|
field.get('is_required'))
|
||||||
for field in
|
for field in
|
||||||
@ -227,6 +271,9 @@ class FunctionLibSerializer(serializers.Serializer):
|
|||||||
def delete(self, with_valid=True):
|
def delete(self, with_valid=True):
|
||||||
if with_valid:
|
if with_valid:
|
||||||
self.is_valid(raise_exception=True)
|
self.is_valid(raise_exception=True)
|
||||||
|
fun = QuerySet(FunctionLib).filter(id=self.data.get('id')).first()
|
||||||
|
if fun.template_id is None and fun.icon != '/ui/favicon.ico':
|
||||||
|
QuerySet(File).filter(id=fun.icon.split('/')[-1]).delete()
|
||||||
QuerySet(FunctionLib).filter(id=self.data.get('id')).delete()
|
QuerySet(FunctionLib).filter(id=self.data.get('id')).delete()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@ -234,9 +281,19 @@ class FunctionLibSerializer(serializers.Serializer):
|
|||||||
if with_valid:
|
if with_valid:
|
||||||
self.is_valid(raise_exception=True)
|
self.is_valid(raise_exception=True)
|
||||||
EditFunctionLib(data=instance).is_valid(raise_exception=True)
|
EditFunctionLib(data=instance).is_valid(raise_exception=True)
|
||||||
edit_field_list = ['name', 'desc', 'code', 'input_field_list', 'init_field_list', 'permission_type', 'is_active']
|
edit_field_list = ['name', 'desc', 'code', 'icon', 'input_field_list', 'init_field_list', 'init_params', 'permission_type', 'is_active']
|
||||||
edit_dict = {field: instance.get(field) for field in edit_field_list if (
|
edit_dict = {field: instance.get(field) for field in edit_field_list if (
|
||||||
field in instance and instance.get(field) is not None)}
|
field in instance and instance.get(field) is not None)}
|
||||||
|
|
||||||
|
function_lib = QuerySet(FunctionLib).filter(id=self.data.get('id')).first()
|
||||||
|
if 'init_params' in edit_dict:
|
||||||
|
if function_lib.init_params:
|
||||||
|
old_init_params = json.loads(rsa_long_decrypt(function_lib.init_params))
|
||||||
|
for key in edit_dict['init_params']:
|
||||||
|
if edit_dict['init_params'][key] == encryption(old_init_params[key]):
|
||||||
|
edit_dict['init_params'][key] = old_init_params[key]
|
||||||
|
|
||||||
|
edit_dict['init_params'] = rsa_long_encrypt(json.dumps(edit_dict['init_params']))
|
||||||
QuerySet(FunctionLib).filter(id=self.data.get('id')).update(**edit_dict)
|
QuerySet(FunctionLib).filter(id=self.data.get('id')).update(**edit_dict)
|
||||||
return self.one(False)
|
return self.one(False)
|
||||||
|
|
||||||
@ -247,7 +304,15 @@ class FunctionLibSerializer(serializers.Serializer):
|
|||||||
Q(user_id=self.data.get('user_id')) | Q(permission_type='PUBLIC')).exists():
|
Q(user_id=self.data.get('user_id')) | Q(permission_type='PUBLIC')).exists():
|
||||||
raise AppApiException(500, _('Function does not exist'))
|
raise AppApiException(500, _('Function does not exist'))
|
||||||
function_lib = QuerySet(FunctionLib).filter(id=self.data.get('id')).first()
|
function_lib = QuerySet(FunctionLib).filter(id=self.data.get('id')).first()
|
||||||
return FunctionLibModelSerializer(function_lib).data
|
if function_lib.init_params:
|
||||||
|
function_lib.init_params = json.loads(rsa_long_decrypt(function_lib.init_params))
|
||||||
|
if function_lib.init_field_list:
|
||||||
|
password_fields = [i["field"] for i in function_lib.init_field_list if i.get("input_type") == "PasswordInput"]
|
||||||
|
if function_lib.init_params:
|
||||||
|
for k in function_lib.init_params:
|
||||||
|
if k in password_fields:
|
||||||
|
function_lib.init_params[k] = encryption(function_lib.init_params[k])
|
||||||
|
return {**FunctionLibModelSerializer(function_lib).data, 'init_params': function_lib.init_params}
|
||||||
|
|
||||||
def export(self, with_valid=True):
|
def export(self, with_valid=True):
|
||||||
try:
|
try:
|
||||||
@ -284,6 +349,7 @@ class FunctionLibSerializer(serializers.Serializer):
|
|||||||
code=function_lib.get('code'),
|
code=function_lib.get('code'),
|
||||||
user_id=user_id,
|
user_id=user_id,
|
||||||
input_field_list=function_lib.get('input_field_list'),
|
input_field_list=function_lib.get('input_field_list'),
|
||||||
|
init_field_list=function_lib.get('init_field_list'),
|
||||||
permission_type='PRIVATE',
|
permission_type='PRIVATE',
|
||||||
is_active=function_lib.get('is_active'))
|
is_active=function_lib.get('is_active'))
|
||||||
function_lib_model.save()
|
function_lib_model.save()
|
||||||
@ -300,10 +366,54 @@ class FunctionLibSerializer(serializers.Serializer):
|
|||||||
functionLib = QuerySet(FunctionLib).filter(id=self.data.get('id')).first()
|
functionLib = QuerySet(FunctionLib).filter(id=self.data.get('id')).first()
|
||||||
if functionLib is None:
|
if functionLib is None:
|
||||||
raise AppApiException(500, _('Function does not exist'))
|
raise AppApiException(500, _('Function does not exist'))
|
||||||
image_id = uuid.uuid1()
|
# 删除旧的图片
|
||||||
image = Image(id=image_id, image=self.data.get('image').read(), image_name=self.data.get('image').name)
|
if functionLib.icon != '/ui/favicon.ico':
|
||||||
image.save()
|
QuerySet(File).filter(id=functionLib.icon.split('/')[-1]).delete()
|
||||||
functionLib.icon = f'/api/image/{image_id}'
|
if self.data.get('image') is None:
|
||||||
|
functionLib.icon = '/ui/favicon.ico'
|
||||||
|
else:
|
||||||
|
meta = {
|
||||||
|
'debug': False
|
||||||
|
}
|
||||||
|
file_id = uuid.uuid1()
|
||||||
|
file = File(id=file_id, file_name=self.data.get('image').name, meta=meta)
|
||||||
|
file.save(self.data.get('image').read())
|
||||||
|
|
||||||
|
functionLib.icon = f'/api/file/{file_id}'
|
||||||
functionLib.save()
|
functionLib.save()
|
||||||
|
|
||||||
return functionLib.icon
|
return functionLib.icon
|
||||||
|
|
||||||
|
class InternalFunction(serializers.Serializer):
|
||||||
|
id = serializers.UUIDField(required=True, error_messages=ErrMessage.uuid(_("function ID")))
|
||||||
|
user_id = serializers.UUIDField(required=True, error_messages=ErrMessage.uuid(_("User ID")))
|
||||||
|
|
||||||
|
def add(self, with_valid=True):
|
||||||
|
if with_valid:
|
||||||
|
self.is_valid(raise_exception=True)
|
||||||
|
|
||||||
|
if QuerySet(FunctionLib).filter(template_id=self.data.get('id')).filter(
|
||||||
|
user_id=self.data.get('user_id')).exists():
|
||||||
|
raise AppApiException(500, _('Function already exists'))
|
||||||
|
|
||||||
|
internal_function_lib = QuerySet(FunctionLib).filter(id=self.data.get('id')).first()
|
||||||
|
if internal_function_lib is None:
|
||||||
|
raise AppApiException(500, _('Function does not exist'))
|
||||||
|
|
||||||
|
function_lib = FunctionLib(
|
||||||
|
id=uuid.uuid1(),
|
||||||
|
name=internal_function_lib.name,
|
||||||
|
desc=internal_function_lib.desc,
|
||||||
|
code=internal_function_lib.code,
|
||||||
|
user_id=self.data.get('user_id'),
|
||||||
|
input_field_list=internal_function_lib.input_field_list,
|
||||||
|
init_field_list=internal_function_lib.init_field_list,
|
||||||
|
permission_type=PermissionType.PRIVATE,
|
||||||
|
template_id=internal_function_lib.id,
|
||||||
|
function_type=FunctionType.PUBLIC,
|
||||||
|
icon=internal_function_lib.icon,
|
||||||
|
is_active=False
|
||||||
|
)
|
||||||
|
function_lib.save()
|
||||||
|
|
||||||
|
return FunctionLibModelSerializer(function_lib).data
|
||||||
|
|||||||
8
apps/function_lib/swagger_api/__init__.py
Normal file
8
apps/function_lib/swagger_api/__init__.py
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# coding=utf-8
|
||||||
|
"""
|
||||||
|
@project: MaxKB
|
||||||
|
@Author:虎
|
||||||
|
@file: __init__.py.py
|
||||||
|
@date:2024/8/2 14:55
|
||||||
|
@desc:
|
||||||
|
"""
|
||||||
@ -9,6 +9,7 @@ urlpatterns = [
|
|||||||
path('function_lib/<str:id>/export', views.FunctionLibView.Export.as_view()),
|
path('function_lib/<str:id>/export', views.FunctionLibView.Export.as_view()),
|
||||||
path('function_lib/import', views.FunctionLibView.Import.as_view()),
|
path('function_lib/import', views.FunctionLibView.Import.as_view()),
|
||||||
path('function_lib/<str:id>/edit_icon', views.FunctionLibView.EditIcon.as_view()),
|
path('function_lib/<str:id>/edit_icon', views.FunctionLibView.EditIcon.as_view()),
|
||||||
|
path('function_lib/<str:id>/add_internal_fun', views.FunctionLibView.AddInternalFun.as_view()),
|
||||||
path('function_lib/pylint', views.PyLintView.as_view()),
|
path('function_lib/pylint', views.PyLintView.as_view()),
|
||||||
path('function_lib/<str:function_lib_id>', views.FunctionLibView.Operate.as_view()),
|
path('function_lib/<str:function_lib_id>', views.FunctionLibView.Operate.as_view()),
|
||||||
path("function_lib/<int:current_page>/<int:page_size>", views.FunctionLibView.Page.as_view(),
|
path("function_lib/<int:current_page>/<int:page_size>", views.FunctionLibView.Page.as_view(),
|
||||||
|
|||||||
@ -34,6 +34,7 @@ class FunctionLibView(APIView):
|
|||||||
FunctionLibSerializer.Query(
|
FunctionLibSerializer.Query(
|
||||||
data={'name': request.query_params.get('name'),
|
data={'name': request.query_params.get('name'),
|
||||||
'desc': request.query_params.get('desc'),
|
'desc': request.query_params.get('desc'),
|
||||||
|
'function_type': request.query_params.get('function_type'),
|
||||||
'user_id': request.user.id}).list())
|
'user_id': request.user.id}).list())
|
||||||
|
|
||||||
@action(methods=['POST'], detail=False)
|
@action(methods=['POST'], detail=False)
|
||||||
@ -107,6 +108,7 @@ class FunctionLibView(APIView):
|
|||||||
FunctionLibSerializer.Query(
|
FunctionLibSerializer.Query(
|
||||||
data={'name': request.query_params.get('name'),
|
data={'name': request.query_params.get('name'),
|
||||||
'desc': request.query_params.get('desc'),
|
'desc': request.query_params.get('desc'),
|
||||||
|
'function_type': request.query_params.get('function_type'),
|
||||||
'user_id': request.user.id,
|
'user_id': request.user.id,
|
||||||
'select_user_id': request.query_params.get('select_user_id')}).page(
|
'select_user_id': request.query_params.get('select_user_id')}).page(
|
||||||
current_page, page_size))
|
current_page, page_size))
|
||||||
@ -148,4 +150,14 @@ class FunctionLibView(APIView):
|
|||||||
return result.success(
|
return result.success(
|
||||||
FunctionLibSerializer.IconOperate(
|
FunctionLibSerializer.IconOperate(
|
||||||
data={'id': id, 'user_id': request.user.id,
|
data={'id': id, 'user_id': request.user.id,
|
||||||
'image': request.FILES.get('file')}).edit(request.data))
|
'image': request.FILES.get('file')}).edit(request.data))
|
||||||
|
|
||||||
|
class AddInternalFun(APIView):
|
||||||
|
authentication_classes = [TokenAuth]
|
||||||
|
|
||||||
|
@action(methods=['GET'], detail=False)
|
||||||
|
@has_permissions(RoleConstants.ADMIN, RoleConstants.USER)
|
||||||
|
def get(self, request: Request, id: str):
|
||||||
|
return result.success(
|
||||||
|
FunctionLibSerializer.InternalFunction(
|
||||||
|
data={'id': id, 'user_id': request.user.id}).add())
|
||||||
@ -120,6 +120,13 @@ const putFunctionLibIcon: (
|
|||||||
return put(`${prefix}/${id}/edit_icon`, data, undefined, loading)
|
return put(`${prefix}/${id}/edit_icon`, data, undefined, loading)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const addInternalFunction: (
|
||||||
|
id: string,
|
||||||
|
loading?: Ref<boolean>
|
||||||
|
) => Promise<Result<any>> = (id, loading) => {
|
||||||
|
return get(`${prefix}/${id}/add_internal_fun`, undefined, loading)
|
||||||
|
}
|
||||||
|
|
||||||
const importFunctionLib: (data: any, loading?: Ref<boolean>) => Promise<Result<any>> = (
|
const importFunctionLib: (data: any, loading?: Ref<boolean>) => Promise<Result<any>> = (
|
||||||
data,
|
data,
|
||||||
loading
|
loading
|
||||||
@ -137,5 +144,6 @@ export default {
|
|||||||
exportFunctionLib,
|
exportFunctionLib,
|
||||||
importFunctionLib,
|
importFunctionLib,
|
||||||
pylint,
|
pylint,
|
||||||
putFunctionLibIcon
|
putFunctionLibIcon,
|
||||||
|
addInternalFunction
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
ui/src/assets/fx/bochaai/icon.png
Normal file
BIN
ui/src/assets/fx/bochaai/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
29
ui/src/assets/fx/bochaai/index.vue
Normal file
29
ui/src/assets/fx/bochaai/index.vue
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<template>
|
||||||
|
<el-drawer v-model="visible" size="40%" :append-to-body="true">
|
||||||
|
<template #header>
|
||||||
|
<div class="flex align-center" style="margin-left: -8px">
|
||||||
|
<el-button class="cursor mr-4" link @click.prevent="visible = false">
|
||||||
|
<el-icon :size="20">
|
||||||
|
<Back />
|
||||||
|
</el-icon>
|
||||||
|
</el-button>
|
||||||
|
<h4>详情</h4>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-drawer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, watch } from 'vue'
|
||||||
|
import { t } from '@/locales'
|
||||||
|
|
||||||
|
const visible = ref(false)
|
||||||
|
|
||||||
|
const open = (data: any) => {
|
||||||
|
visible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
open
|
||||||
|
})
|
||||||
|
</script>
|
||||||
BIN
ui/src/assets/fx/google_search/icon.png
Normal file
BIN
ui/src/assets/fx/google_search/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.4 KiB |
29
ui/src/assets/fx/google_search/index.vue
Normal file
29
ui/src/assets/fx/google_search/index.vue
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<template>
|
||||||
|
<el-drawer v-model="visible" size="40%" :append-to-body="true">
|
||||||
|
<template #header>
|
||||||
|
<div class="flex align-center" style="margin-left: -8px">
|
||||||
|
<el-button class="cursor mr-4" link @click.prevent="visible = false">
|
||||||
|
<el-icon :size="20">
|
||||||
|
<Back />
|
||||||
|
</el-icon>
|
||||||
|
</el-button>
|
||||||
|
<h4>详情</h4>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-drawer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, watch } from 'vue'
|
||||||
|
import { t } from '@/locales'
|
||||||
|
|
||||||
|
const visible = ref(false)
|
||||||
|
|
||||||
|
const open = (data: any) => {
|
||||||
|
visible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
open
|
||||||
|
})
|
||||||
|
</script>
|
||||||
BIN
ui/src/assets/fx/langsearch/icon.png
Normal file
BIN
ui/src/assets/fx/langsearch/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 67 KiB |
29
ui/src/assets/fx/langsearch/index.vue
Normal file
29
ui/src/assets/fx/langsearch/index.vue
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<template>
|
||||||
|
<el-drawer v-model="visible" size="40%" :append-to-body="true">
|
||||||
|
<template #header>
|
||||||
|
<div class="flex align-center" style="margin-left: -8px">
|
||||||
|
<el-button class="cursor mr-4" link @click.prevent="visible = false">
|
||||||
|
<el-icon :size="20">
|
||||||
|
<Back />
|
||||||
|
</el-icon>
|
||||||
|
</el-button>
|
||||||
|
<h4>详情</h4>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-drawer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, watch } from 'vue'
|
||||||
|
import { t } from '@/locales'
|
||||||
|
|
||||||
|
const visible = ref(false)
|
||||||
|
|
||||||
|
const open = (data: any) => {
|
||||||
|
visible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
open
|
||||||
|
})
|
||||||
|
</script>
|
||||||
@ -35,6 +35,7 @@ export default {
|
|||||||
private: 'Private',
|
private: 'Private',
|
||||||
paramSetting: 'Parameter Settings',
|
paramSetting: 'Parameter Settings',
|
||||||
creator: 'Creator',
|
creator: 'Creator',
|
||||||
|
author: 'Author',
|
||||||
debug: 'Debug',
|
debug: 'Debug',
|
||||||
required: 'Required',
|
required: 'Required',
|
||||||
noData: 'No data',
|
noData: 'No data',
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
export default {
|
export default {
|
||||||
title: 'Function',
|
title: 'Function',
|
||||||
|
internalTitle: 'Internal Function',
|
||||||
|
added: 'Added',
|
||||||
createFunction: 'Create Function',
|
createFunction: 'Create Function',
|
||||||
editFunction: 'Edit Function',
|
editFunction: 'Edit Function',
|
||||||
copyFunction: 'Copy Function',
|
copyFunction: 'Copy Function',
|
||||||
|
|||||||
@ -35,6 +35,7 @@ export default {
|
|||||||
private: '私有',
|
private: '私有',
|
||||||
paramSetting: '参数设置',
|
paramSetting: '参数设置',
|
||||||
creator: '创建者',
|
creator: '创建者',
|
||||||
|
author: '作者',
|
||||||
debug: '调试',
|
debug: '调试',
|
||||||
required: '必填',
|
required: '必填',
|
||||||
noData: '暂无数据',
|
noData: '暂无数据',
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
export default {
|
export default {
|
||||||
title: '函数库',
|
title: '函数库',
|
||||||
|
internalTitle: '内置函数',
|
||||||
|
added: '已添加',
|
||||||
createFunction: '创建函数',
|
createFunction: '创建函数',
|
||||||
editFunction: '编辑函数',
|
editFunction: '编辑函数',
|
||||||
copyFunction: '复制函数',
|
copyFunction: '复制函数',
|
||||||
|
|||||||
@ -35,6 +35,7 @@ export default {
|
|||||||
private: '私有',
|
private: '私有',
|
||||||
paramSetting: '參數設定',
|
paramSetting: '參數設定',
|
||||||
creator: '建立者',
|
creator: '建立者',
|
||||||
|
author: '作者',
|
||||||
debug: '調試',
|
debug: '調試',
|
||||||
required: '必填',
|
required: '必填',
|
||||||
noData: '暂无数据',
|
noData: '暂无数据',
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
export default {
|
export default {
|
||||||
title: '函數庫',
|
title: '函數庫',
|
||||||
|
internalTitle: '內置函數',
|
||||||
|
added: '已新增',
|
||||||
createFunction: '建立函數',
|
createFunction: '建立函數',
|
||||||
editFunction: '編輯函數',
|
editFunction: '編輯函數',
|
||||||
copyFunction: '複製函數',
|
copyFunction: '複製函數',
|
||||||
|
|||||||
@ -111,11 +111,8 @@ const onChange = (file: any) => {
|
|||||||
|
|
||||||
function submit() {
|
function submit() {
|
||||||
if (radioType.value === 'default') {
|
if (radioType.value === 'default') {
|
||||||
// application.asyncPutApplication(props.id as string, { icon: defaultIcon }, loading).then((res: any) => {
|
emit('refresh', '/ui/favicon.ico')
|
||||||
// emit('refresh')
|
dialogVisible.value = false
|
||||||
// MsgSuccess(t('views.applicationOverview.appInfo.EditAvatarDialog.setSuccess'))
|
|
||||||
// dialogVisible.value = false
|
|
||||||
// })
|
|
||||||
} else if (radioType.value === 'custom' && iconFile.value) {
|
} else if (radioType.value === 'custom' && iconFile.value) {
|
||||||
let fd = new FormData()
|
let fd = new FormData()
|
||||||
fd.append('file', iconFile.value.raw)
|
fd.append('file', iconFile.value.raw)
|
||||||
|
|||||||
@ -16,9 +16,9 @@
|
|||||||
{{ $t('common.param.initParam') }}
|
{{ $t('common.param.initParam') }}
|
||||||
</h4>
|
</h4>
|
||||||
<el-card shadow="never" class="card-never" style="--el-card-padding: 12px">
|
<el-card shadow="never" class="card-never" style="--el-card-padding: 12px">
|
||||||
<DynamicsForm
|
<DynamicsForm
|
||||||
v-model="init_form_data"
|
v-model="form.init_params"
|
||||||
:model="init_form_data"
|
:model="form.init_params"
|
||||||
label-position="top"
|
label-position="top"
|
||||||
require-asterisk-position="right"
|
require-asterisk-position="right"
|
||||||
:render_data="form.init_field_list"
|
:render_data="form.init_field_list"
|
||||||
@ -53,7 +53,7 @@
|
|||||||
<template #label>
|
<template #label>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<span
|
<span
|
||||||
>{{ item.name }} <span class="danger" v-if="item.is_required">*</span></span
|
>{{ item.name }} <span class="danger" v-if="item.is_required">*</span></span
|
||||||
>
|
>
|
||||||
<el-tag type="info" class="info-tag ml-4">{{ item.type }}</el-tag>
|
<el-tag type="info" class="info-tag ml-4">{{ item.type }}</el-tag>
|
||||||
</div>
|
</div>
|
||||||
@ -114,18 +114,19 @@ import type { FormInstance } from 'element-plus'
|
|||||||
import DynamicsForm from '@/components/dynamics-form/index.vue'
|
import DynamicsForm from '@/components/dynamics-form/index.vue'
|
||||||
|
|
||||||
const FormRef = ref()
|
const FormRef = ref()
|
||||||
|
const dynamicsFormRef = ref()
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const debugVisible = ref(false)
|
const debugVisible = ref(false)
|
||||||
const showResult = ref(false)
|
const showResult = ref(false)
|
||||||
const isSuccess = ref(false)
|
const isSuccess = ref(false)
|
||||||
const result = ref('')
|
const result = ref('')
|
||||||
const init_form_data = ref<any>({})
|
|
||||||
|
|
||||||
const form = ref<any>({
|
const form = ref<any>({
|
||||||
debug_field_list: [],
|
debug_field_list: [],
|
||||||
code: '',
|
code: '',
|
||||||
input_field_list: [],
|
input_field_list: [],
|
||||||
init_field_list: []
|
init_field_list: [],
|
||||||
|
init_params: {}
|
||||||
})
|
})
|
||||||
|
|
||||||
watch(debugVisible, (bool) => {
|
watch(debugVisible, (bool) => {
|
||||||
@ -137,14 +138,15 @@ watch(debugVisible, (bool) => {
|
|||||||
debug_field_list: [],
|
debug_field_list: [],
|
||||||
code: '',
|
code: '',
|
||||||
input_field_list: [],
|
input_field_list: [],
|
||||||
init_field_list: []
|
init_field_list: [],
|
||||||
|
init_params: {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const submit = async (formEl: FormInstance | undefined) => {
|
const submit = async (formEl: FormInstance | undefined) => {
|
||||||
const validate = formEl ? formEl.validate() : Promise.resolve()
|
const validate = formEl ? formEl.validate() : Promise.resolve()
|
||||||
validate.then(() => {
|
Promise.all([dynamicsFormRef.value?.validate(), validate]).then(() => {
|
||||||
functionLibApi.postFunctionLibDebug(form.value, loading).then((res) => {
|
functionLibApi.postFunctionLibDebug(form.value, loading).then((res) => {
|
||||||
if (res.code === 500) {
|
if (res.code === 500) {
|
||||||
showResult.value = true
|
showResult.value = true
|
||||||
|
|||||||
@ -26,13 +26,13 @@
|
|||||||
@mouseleave="showEditIcon = false"
|
@mouseleave="showEditIcon = false"
|
||||||
>
|
>
|
||||||
<AppAvatar
|
<AppAvatar
|
||||||
v-if="isAppIcon(form.icon)"
|
v-if="isAppIcon(form.icon as string)"
|
||||||
:id="form.id"
|
:id="form.id"
|
||||||
shape="square"
|
shape="square"
|
||||||
:size="32"
|
:size="32"
|
||||||
style="background: none"
|
style="background: none"
|
||||||
>
|
>
|
||||||
<img :src="form.icon" alt="" />
|
<img :src="form.icon as string" alt="" />
|
||||||
</AppAvatar>
|
</AppAvatar>
|
||||||
<AppAvatar
|
<AppAvatar
|
||||||
v-else-if="form.name"
|
v-else-if="form.name"
|
||||||
@ -72,6 +72,7 @@
|
|||||||
@blur="form.desc = form.desc?.trim()"
|
@blur="form.desc = form.desc?.trim()"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<!--
|
||||||
<el-form-item prop="permission_type">
|
<el-form-item prop="permission_type">
|
||||||
<template #label>
|
<template #label>
|
||||||
<span>{{ $t('views.functionLib.functionForm.form.permission_type.label') }}</span>
|
<span>{{ $t('views.functionLib.functionForm.form.permission_type.label') }}</span>
|
||||||
@ -98,6 +99,7 @@
|
|||||||
</el-row>
|
</el-row>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
-->
|
||||||
</el-form>
|
</el-form>
|
||||||
<div class="flex-between">
|
<div class="flex-between">
|
||||||
<h4 class="title-decoration-1 mb-16">
|
<h4 class="title-decoration-1 mb-16">
|
||||||
|
|||||||
@ -11,10 +11,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<div>
|
<div>
|
||||||
<div v-if="form.init_field_list.length > 0">
|
<div v-if="form.init_field_list?.length > 0">
|
||||||
<DynamicsForm
|
<DynamicsForm
|
||||||
v-model="init_form_data"
|
v-model="form.init_params"
|
||||||
:model="init_form_data"
|
:model="form.init_params"
|
||||||
label-position="top"
|
label-position="top"
|
||||||
require-asterisk-position="right"
|
require-asterisk-position="right"
|
||||||
:render_data="form.init_field_list"
|
:render_data="form.init_field_list"
|
||||||
@ -51,10 +51,9 @@ const debugVisible = ref(false)
|
|||||||
const showResult = ref(false)
|
const showResult = ref(false)
|
||||||
const isSuccess = ref(false)
|
const isSuccess = ref(false)
|
||||||
const result = ref('')
|
const result = ref('')
|
||||||
const init_form_data = ref<any>({})
|
|
||||||
|
|
||||||
const form = ref<any>({
|
const form = ref<any>({
|
||||||
init_field_list: []
|
init_params: {}
|
||||||
})
|
})
|
||||||
|
|
||||||
watch(debugVisible, (bool) => {
|
watch(debugVisible, (bool) => {
|
||||||
@ -63,17 +62,13 @@ watch(debugVisible, (bool) => {
|
|||||||
isSuccess.value = false
|
isSuccess.value = false
|
||||||
result.value = ''
|
result.value = ''
|
||||||
form.value = {
|
form.value = {
|
||||||
init_field_list: []
|
init_params: {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const submit = async () => {
|
const submit = async () => {
|
||||||
dynamicsFormRef.value.validate().then(() => {
|
dynamicsFormRef.value.validate().then(() => {
|
||||||
form.value.init_field_list.forEach((item: any) => {
|
|
||||||
item.value = init_form_data.value[item.field]
|
|
||||||
})
|
|
||||||
// console.log(init_form_data.value)
|
|
||||||
functionLibApi.putFunctionLib(form.value?.id as string, form.value, loading)
|
functionLibApi.putFunctionLib(form.value?.id as string, form.value, loading)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
MsgSuccess(t('common.editSuccess'))
|
MsgSuccess(t('common.editSuccess'))
|
||||||
@ -87,17 +82,15 @@ const open = (data: any) => {
|
|||||||
if (data) {
|
if (data) {
|
||||||
form.value = cloneDeep(data)
|
form.value = cloneDeep(data)
|
||||||
}
|
}
|
||||||
init_form_data.value = form.value.init_field_list
|
const init_params = form.value.init_field_list
|
||||||
.map((item: any) => {
|
.map((item: any) => {
|
||||||
if (item.value) {
|
|
||||||
return { [item.field]: item.value }
|
|
||||||
}
|
|
||||||
if (item.show_default_value === false) {
|
if (item.show_default_value === false) {
|
||||||
return { [item.field]: undefined }
|
return { [item.field]: undefined }
|
||||||
}
|
}
|
||||||
return { [item.field]: item.default_value }
|
return { [item.field]: item.default_value }
|
||||||
})
|
})
|
||||||
.reduce((x: any, y: any) => ({ ...x, ...y }), {})
|
.reduce((x: any, y: any) => ({ ...x, ...y }), {})
|
||||||
|
form.value.init_params = { ...init_params, ...form.value.init_params }
|
||||||
debugVisible.value = true
|
debugVisible.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="function-lib-list-container p-24" style="padding-top: 16px">
|
<div class="function-lib-list-container p-24" style="padding-top: 16px">
|
||||||
|
<el-tabs v-model="functionType" >
|
||||||
|
<el-tab-pane :label="$t('views.functionLib.title')" name="PUBLIC"></el-tab-pane>
|
||||||
|
<el-tab-pane :label="$t('views.functionLib.internalTitle')" name="INTERNAL"></el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
<div class="flex-between mb-16">
|
<div class="flex-between mb-16">
|
||||||
<h4>{{ $t('views.functionLib.title') }}</h4>
|
<h4></h4>
|
||||||
<div class="flex-between">
|
<div class="flex-between">
|
||||||
<el-select
|
<el-select
|
||||||
v-model="selectUserId"
|
v-model="selectUserId"
|
||||||
@ -41,7 +45,7 @@
|
|||||||
:loading="loading"
|
:loading="loading"
|
||||||
>
|
>
|
||||||
<el-row :gutter="15">
|
<el-row :gutter="15">
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6" class="mb-16">
|
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6" class="mb-16" v-if="functionType === 'PUBLIC'">
|
||||||
<el-card shadow="hover" class="application-card-add" style="--el-card-padding: 8px">
|
<el-card shadow="hover" class="application-card-add" style="--el-card-padding: 8px">
|
||||||
<div class="card-add-button flex align-center cursor p-8" @click="openCreateDialog()">
|
<div class="card-add-button flex align-center cursor p-8" @click="openCreateDialog()">
|
||||||
<AppIcon iconName="app-add-application" class="mr-8"></AppIcon>
|
<AppIcon iconName="app-add-application" class="mr-8"></AppIcon>
|
||||||
@ -77,6 +81,7 @@
|
|||||||
class="mb-16"
|
class="mb-16"
|
||||||
>
|
>
|
||||||
<CardBox
|
<CardBox
|
||||||
|
v-if="functionType === 'PUBLIC'"
|
||||||
:title="item.name"
|
:title="item.name"
|
||||||
:description="item.desc"
|
:description="item.desc"
|
||||||
class="function-lib-card"
|
class="function-lib-card"
|
||||||
@ -84,12 +89,26 @@
|
|||||||
:class="item.permission_type === 'PUBLIC' && !canEdit(item) ? '' : 'cursor'"
|
:class="item.permission_type === 'PUBLIC' && !canEdit(item) ? '' : 'cursor'"
|
||||||
>
|
>
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<AppAvatar class="mr-12 avatar-green" shape="square" :size="32">
|
<AppAvatar
|
||||||
<img src="@/assets/icon_function_outlined.svg" style="width: 58%" alt="" />
|
v-if="isAppIcon(item?.icon)"
|
||||||
|
shape="square"
|
||||||
|
:size="32"
|
||||||
|
style="background: none"
|
||||||
|
class="mr-8"
|
||||||
|
>
|
||||||
|
<img :src="getImageUrl(item?.icon)" alt="" />
|
||||||
</AppAvatar>
|
</AppAvatar>
|
||||||
|
<AppAvatar
|
||||||
|
v-else-if="item?.name"
|
||||||
|
:name="item?.name"
|
||||||
|
pinyinColor
|
||||||
|
shape="square"
|
||||||
|
:size="32"
|
||||||
|
class="mr-8"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template #subTitle>
|
<template #subTitle>
|
||||||
<el-text class="color-secondary" size="small">
|
<el-text class="color-secondary" size="small" v-if="!item.template_id">
|
||||||
<auto-tooltip :content="item.username">
|
<auto-tooltip :content="item.username">
|
||||||
{{ $t('common.creator') }}: {{ item.username }}
|
{{ $t('common.creator') }}: {{ item.username }}
|
||||||
</auto-tooltip>
|
</auto-tooltip>
|
||||||
@ -113,7 +132,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="footer-content flex-between">
|
<div class="footer-content flex-between">
|
||||||
<div></div>
|
<div><span v-if="item.template_id"> {{ $t('common.author') }}: MaxKB</span></div>
|
||||||
<div @click.stop>
|
<div @click.stop>
|
||||||
<el-switch
|
<el-switch
|
||||||
:disabled="item.permission_type === 'PUBLIC' && !canEdit(item)"
|
:disabled="item.permission_type === 'PUBLIC' && !canEdit(item)"
|
||||||
@ -129,6 +148,7 @@
|
|||||||
<el-dropdown-menu>
|
<el-dropdown-menu>
|
||||||
<el-dropdown-item
|
<el-dropdown-item
|
||||||
:disabled="item.permission_type === 'PUBLIC' && !canEdit(item)"
|
:disabled="item.permission_type === 'PUBLIC' && !canEdit(item)"
|
||||||
|
v-if="!item.template_id"
|
||||||
@click.stop="copyFunctionLib(item)"
|
@click.stop="copyFunctionLib(item)"
|
||||||
>
|
>
|
||||||
<AppIcon iconName="app-copy"></AppIcon>
|
<AppIcon iconName="app-copy"></AppIcon>
|
||||||
@ -150,6 +170,7 @@
|
|||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
<el-dropdown-item
|
<el-dropdown-item
|
||||||
:disabled="item.permission_type === 'PUBLIC' && !canEdit(item)"
|
:disabled="item.permission_type === 'PUBLIC' && !canEdit(item)"
|
||||||
|
v-if="!item.template_id"
|
||||||
@click.stop="exportFunctionLib(item)"
|
@click.stop="exportFunctionLib(item)"
|
||||||
>
|
>
|
||||||
<AppIcon iconName="app-export"></AppIcon>
|
<AppIcon iconName="app-export"></AppIcon>
|
||||||
@ -169,6 +190,57 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</CardBox>
|
</CardBox>
|
||||||
|
<CardBox
|
||||||
|
v-if="functionType === 'INTERNAL'"
|
||||||
|
:title="item.name"
|
||||||
|
:description="item.desc"
|
||||||
|
class="function-lib-card"
|
||||||
|
@click="openDescDrawer(item)"
|
||||||
|
:class="item.permission_type === 'PUBLIC' && !canEdit(item) ? '' : 'cursor'"
|
||||||
|
>
|
||||||
|
<template #icon>
|
||||||
|
<AppAvatar
|
||||||
|
v-if="isAppIcon(item?.icon)"
|
||||||
|
shape="square"
|
||||||
|
:size="32"
|
||||||
|
style="background: none"
|
||||||
|
class="mr-8"
|
||||||
|
>
|
||||||
|
<img :src="getImageUrl(item?.icon)" alt="" />
|
||||||
|
</AppAvatar>
|
||||||
|
<AppAvatar
|
||||||
|
v-else-if="item?.name"
|
||||||
|
:name="item?.name"
|
||||||
|
pinyinColor
|
||||||
|
shape="square"
|
||||||
|
:size="32"
|
||||||
|
class="mr-8"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<div class="status-button">
|
||||||
|
<el-tag
|
||||||
|
class="info-tag"
|
||||||
|
v-if="item.added"
|
||||||
|
style="height: 22px"
|
||||||
|
>
|
||||||
|
{{ $t('views.functionLib.added') }}</el-tag
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<template #footer>
|
||||||
|
<div class="footer-content flex-between">
|
||||||
|
<div>{{ $t('common.author') }}: MaxKB</div>
|
||||||
|
<div @click.stop v-if="!item.added">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
link
|
||||||
|
@click="addInternalFunction(item)"
|
||||||
|
>
|
||||||
|
{{ $t('common.add') }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</CardBox>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</InfiniteScroll>
|
</InfiniteScroll>
|
||||||
@ -176,10 +248,11 @@
|
|||||||
<FunctionFormDrawer ref="FunctionFormDrawerRef" @refresh="refresh" :title="title" />
|
<FunctionFormDrawer ref="FunctionFormDrawerRef" @refresh="refresh" :title="title" />
|
||||||
<PermissionDialog ref="PermissionDialogRef" @refresh="refresh" />
|
<PermissionDialog ref="PermissionDialogRef" @refresh="refresh" />
|
||||||
<InitParamDrawer ref="InitParamDrawerRef" @refresh="refresh" />
|
<InitParamDrawer ref="InitParamDrawerRef" @refresh="refresh" />
|
||||||
|
<component :is="internalDescComponent" ref="internalDescRef" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted, reactive } from 'vue'
|
import { ref, onMounted, reactive, watch, nextTick } from 'vue'
|
||||||
import { cloneDeep } from 'lodash'
|
import { cloneDeep } from 'lodash'
|
||||||
import functionLibApi from '@/api/function-lib'
|
import functionLibApi from '@/api/function-lib'
|
||||||
import FunctionFormDrawer from './component/FunctionFormDrawer.vue'
|
import FunctionFormDrawer from './component/FunctionFormDrawer.vue'
|
||||||
@ -189,6 +262,16 @@ import applicationApi from '@/api/application'
|
|||||||
import { t } from '@/locales'
|
import { t } from '@/locales'
|
||||||
import PermissionDialog from '@/views/function-lib/component/PermissionDialog.vue'
|
import PermissionDialog from '@/views/function-lib/component/PermissionDialog.vue'
|
||||||
import InitParamDrawer from '@/views/function-lib/component/InitParamDrawer.vue'
|
import InitParamDrawer from '@/views/function-lib/component/InitParamDrawer.vue'
|
||||||
|
import { isAppIcon } from '@/utils/application'
|
||||||
|
import InfiniteScroll from '@/components/infinite-scroll/index.vue'
|
||||||
|
import CardBox from '@/components/card-box/index.vue'
|
||||||
|
import type { Dict } from '@/api/type/common'
|
||||||
|
|
||||||
|
const internalIcons: Dict<any> = import.meta.glob('@/assets/fx/*/*.png', { eager: true })
|
||||||
|
let internalDesc: Dict<any> = import.meta.glob('@/assets/fx/*/index.vue', { eager: true })
|
||||||
|
const internalDescRef = ref()
|
||||||
|
const internalDescComponent = ref()
|
||||||
|
|
||||||
const { user } = useStore()
|
const { user } = useStore()
|
||||||
|
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
@ -219,21 +302,65 @@ const userOptions = ref<UserOption[]>([])
|
|||||||
const selectUserId = ref('all')
|
const selectUserId = ref('all')
|
||||||
const elUploadRef = ref<any>()
|
const elUploadRef = ref<any>()
|
||||||
|
|
||||||
|
const functionType = ref('PUBLIC')
|
||||||
|
|
||||||
|
watch(
|
||||||
|
functionType,
|
||||||
|
(val) => {
|
||||||
|
paginationConfig.total = 0
|
||||||
|
paginationConfig.current_page = 1
|
||||||
|
functionLibList.value = []
|
||||||
|
getList()
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
)
|
||||||
|
|
||||||
const canEdit = (row: any) => {
|
const canEdit = (row: any) => {
|
||||||
return user.userInfo?.id === row?.user_id
|
return user.userInfo?.id === row?.user_id
|
||||||
}
|
}
|
||||||
|
|
||||||
function openCreateDialog(data?: any) {
|
function openCreateDialog(data?: any) {
|
||||||
|
// 有template_id的不允许编辑,是模板转换来的
|
||||||
|
if (data?.template_id) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// console.log(data)
|
||||||
title.value = data ? t('views.functionLib.editFunction') : t('views.functionLib.createFunction')
|
title.value = data ? t('views.functionLib.editFunction') : t('views.functionLib.createFunction')
|
||||||
if (data) {
|
if (data) {
|
||||||
if (data?.permission_type !== 'PUBLIC' || canEdit(data)) {
|
if (data?.permission_type !== 'PUBLIC' || canEdit(data)) {
|
||||||
FunctionFormDrawerRef.value.open(data)
|
functionLibApi.getFunctionLibById(data?.id, changeStateloading).then((res) => {
|
||||||
|
FunctionFormDrawerRef.value.open(res.data)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
FunctionFormDrawerRef.value.open(data)
|
FunctionFormDrawerRef.value.open(data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getImageUrl(name: string) {
|
||||||
|
if (name.startsWith('/src/assets/fx/')) {
|
||||||
|
return internalIcons[name]?.default;
|
||||||
|
}
|
||||||
|
return name
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function openDescDrawer(row: any) {
|
||||||
|
const index = row.icon.replace('icon.png', 'index.vue')
|
||||||
|
internalDescComponent.value = internalDesc[index].default
|
||||||
|
nextTick(()=> {
|
||||||
|
internalDescRef.value?.open(row);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function addInternalFunction(data?: any) {
|
||||||
|
functionLibApi.addInternalFunction(data.id, changeStateloading)
|
||||||
|
.then((res) => {
|
||||||
|
MsgSuccess(t('common.submitSuccess'))
|
||||||
|
searchHandle()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
function searchHandle() {
|
function searchHandle() {
|
||||||
if (user.userInfo) {
|
if (user.userInfo) {
|
||||||
localStorage.setItem(user.userInfo.id + 'function', selectUserId.value)
|
localStorage.setItem(user.userInfo.id + 'function', selectUserId.value)
|
||||||
@ -244,7 +371,7 @@ function searchHandle() {
|
|||||||
getList()
|
getList()
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeState(bool: Boolean, row: any) {
|
async function changeState(bool: Boolean, row: any) {
|
||||||
if (!bool) {
|
if (!bool) {
|
||||||
MsgConfirm(
|
MsgConfirm(
|
||||||
`${t('views.functionLib.disabled.confirmTitle')}${row.name} ?`,
|
`${t('views.functionLib.disabled.confirmTitle')}${row.name} ?`,
|
||||||
@ -264,6 +391,12 @@ function changeState(bool: Boolean, row: any) {
|
|||||||
row.is_active = true
|
row.is_active = true
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
|
const res = await functionLibApi.getFunctionLibById(row.id, changeStateloading)
|
||||||
|
if (!res.data.init_params && res.data.init_field_list && res.data.init_field_list.length > 0) {
|
||||||
|
InitParamDrawerRef.value.open(res.data)
|
||||||
|
row.is_active = false
|
||||||
|
return
|
||||||
|
}
|
||||||
const obj = {
|
const obj = {
|
||||||
is_active: bool
|
is_active: bool
|
||||||
}
|
}
|
||||||
@ -315,7 +448,9 @@ function configPermission(item: any) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function configInitParams(item: any) {
|
function configInitParams(item: any) {
|
||||||
InitParamDrawerRef.value.open(item)
|
functionLibApi.getFunctionLibById(item?.id, changeStateloading).then((res) => {
|
||||||
|
InitParamDrawerRef.value.open(res.data)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function importFunctionLib(file: any) {
|
function importFunctionLib(file: any) {
|
||||||
@ -344,6 +479,7 @@ function importFunctionLib(file: any) {
|
|||||||
function getList() {
|
function getList() {
|
||||||
const params = {
|
const params = {
|
||||||
...(searchValue.value && { name: searchValue.value }),
|
...(searchValue.value && { name: searchValue.value }),
|
||||||
|
...(functionType.value && { function_type: functionType.value }),
|
||||||
...(selectUserId.value &&
|
...(selectUserId.value &&
|
||||||
selectUserId.value !== 'all' && { select_user_id: selectUserId.value })
|
selectUserId.value !== 'all' && { select_user_id: selectUserId.value })
|
||||||
}
|
}
|
||||||
@ -369,12 +505,11 @@ function refresh(data: any) {
|
|||||||
data.username = userOptions.value.find((v) => v.value === data.user_id)?.label
|
data.username = userOptions.value.find((v) => v.value === data.user_id)?.label
|
||||||
}
|
}
|
||||||
functionLibList.value.splice(index, 1, data)
|
functionLibList.value.splice(index, 1, data)
|
||||||
} else {
|
|
||||||
paginationConfig.total = 0
|
|
||||||
paginationConfig.current_page = 1
|
|
||||||
functionLibList.value = []
|
|
||||||
getList()
|
|
||||||
}
|
}
|
||||||
|
paginationConfig.total = 0
|
||||||
|
paginationConfig.current_page = 1
|
||||||
|
functionLibList.value = []
|
||||||
|
getList()
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUserList() {
|
function getUserList() {
|
||||||
@ -392,7 +527,7 @@ function getUserList() {
|
|||||||
selectUserId.value = selectUserIdValue
|
selectUserId.value = selectUserIdValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
getList()
|
// getList()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user