Merge branch 'v2' of https://github.com/maxkb-dev/maxkb into v2
commit
4a8963b548
|
|
@ -17,6 +17,19 @@ from application.flow.i_step_node import NodeResult
|
||||||
from application.flow.step_node.form_node.i_form_node import IFormNode
|
from application.flow.step_node.form_node.i_form_node import IFormNode
|
||||||
|
|
||||||
|
|
||||||
|
def get_default_option(option_list, _type, value_field):
|
||||||
|
if option_list is not None and len(option_list) > 0:
|
||||||
|
default_value_list = [o.get(value_field) for o in option_list if o.get('default')]
|
||||||
|
if len(default_value_list) == 0:
|
||||||
|
return option_list[0].get(value_field)
|
||||||
|
else:
|
||||||
|
if _type == 'MultiSelect':
|
||||||
|
return default_value_list
|
||||||
|
else:
|
||||||
|
return default_value_list[0]
|
||||||
|
return []
|
||||||
|
|
||||||
|
|
||||||
def write_context(step_variable: Dict, global_variable: Dict, node, workflow):
|
def write_context(step_variable: Dict, global_variable: Dict, node, workflow):
|
||||||
if step_variable is not None:
|
if step_variable is not None:
|
||||||
for key in step_variable:
|
for key in step_variable:
|
||||||
|
|
@ -44,6 +57,30 @@ class BaseFormNode(IFormNode):
|
||||||
for key in form_data:
|
for key in form_data:
|
||||||
self.context[key] = form_data[key]
|
self.context[key] = form_data[key]
|
||||||
|
|
||||||
|
def reset_field(self, field):
|
||||||
|
if ['SingleSelect', 'MultiSelect', 'RadioCard'].__contains__(field.get('input_type')):
|
||||||
|
if field.get('assignment_method') == 'ref_variables':
|
||||||
|
option_list = self.workflow_manage.get_reference_field(field.get('option_list')[0],
|
||||||
|
field.get('option_list')[1:])
|
||||||
|
field['option_list'] = option_list
|
||||||
|
field['default_value'] = get_default_option(option_list, field.get('input_type'),
|
||||||
|
field.get('value_field'))
|
||||||
|
|
||||||
|
reset_field = ['field', 'label', 'default_value']
|
||||||
|
for f in reset_field:
|
||||||
|
_value = field[f]
|
||||||
|
if _value is None:
|
||||||
|
continue
|
||||||
|
if isinstance(_value, str):
|
||||||
|
field[f] = self.workflow_manage.generate_prompt(_value)
|
||||||
|
elif f == 'label':
|
||||||
|
_label_value = _value.get('label')
|
||||||
|
_value['label'] = self.workflow_manage.generate_prompt(_label_value)
|
||||||
|
tooltip = _value.get('attrs').get('tooltip')
|
||||||
|
if tooltip is not None:
|
||||||
|
_value.get('attrs')['tooltip'] = self.workflow_manage.generate_prompt(tooltip)
|
||||||
|
return field
|
||||||
|
|
||||||
def execute(self, form_field_list, form_content_format, form_data, **kwargs) -> NodeResult:
|
def execute(self, form_field_list, form_content_format, form_data, **kwargs) -> NodeResult:
|
||||||
if form_data is not None:
|
if form_data is not None:
|
||||||
self.context['is_submit'] = True
|
self.context['is_submit'] = True
|
||||||
|
|
@ -52,6 +89,7 @@ class BaseFormNode(IFormNode):
|
||||||
self.context[key] = form_data.get(key)
|
self.context[key] = form_data.get(key)
|
||||||
else:
|
else:
|
||||||
self.context['is_submit'] = False
|
self.context['is_submit'] = False
|
||||||
|
form_field_list = [self.reset_field(field) for field in form_field_list]
|
||||||
form_setting = {"form_field_list": form_field_list, "runtime_node_id": self.runtime_node_id,
|
form_setting = {"form_field_list": form_field_list, "runtime_node_id": self.runtime_node_id,
|
||||||
"chat_record_id": self.flow_params_serializer.data.get("chat_record_id"),
|
"chat_record_id": self.flow_params_serializer.data.get("chat_record_id"),
|
||||||
"is_submit": self.context.get("is_submit", False)}
|
"is_submit": self.context.get("is_submit", False)}
|
||||||
|
|
@ -60,6 +98,7 @@ class BaseFormNode(IFormNode):
|
||||||
form_content_format = self.workflow_manage.reset_prompt(form_content_format)
|
form_content_format = self.workflow_manage.reset_prompt(form_content_format)
|
||||||
prompt_template = PromptTemplate.from_template(form_content_format, template_format='jinja2')
|
prompt_template = PromptTemplate.from_template(form_content_format, template_format='jinja2')
|
||||||
value = prompt_template.format(form=form, context=context)
|
value = prompt_template.format(form=form, context=context)
|
||||||
|
|
||||||
return NodeResult(
|
return NodeResult(
|
||||||
{'result': value, 'form_field_list': form_field_list, 'form_content_format': form_content_format}, {},
|
{'result': value, 'form_field_list': form_field_list, 'form_content_format': form_content_format}, {},
|
||||||
_write_context=write_context)
|
_write_context=write_context)
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,10 @@ class Reasoning:
|
||||||
if not self.reasoning_content_is_end:
|
if not self.reasoning_content_is_end:
|
||||||
self.reasoning_content_is_end = True
|
self.reasoning_content_is_end = True
|
||||||
self.content += self.all_content
|
self.content += self.all_content
|
||||||
return {'content': self.all_content, 'reasoning_content': ''}
|
return {'content': self.all_content,
|
||||||
|
'reasoning_content': chunk.additional_kwargs.get('reasoning_content',
|
||||||
|
'') if chunk.additional_kwargs else ''
|
||||||
|
}
|
||||||
else:
|
else:
|
||||||
if self.reasoning_content_is_start:
|
if self.reasoning_content_is_start:
|
||||||
self.reasoning_content_chunk += chunk.content
|
self.reasoning_content_chunk += chunk.content
|
||||||
|
|
@ -68,7 +71,9 @@ class Reasoning:
|
||||||
self.reasoning_content_end_tag_prefix)
|
self.reasoning_content_end_tag_prefix)
|
||||||
if self.reasoning_content_is_end:
|
if self.reasoning_content_is_end:
|
||||||
self.content += chunk.content
|
self.content += chunk.content
|
||||||
return {'content': chunk.content, 'reasoning_content': ''}
|
return {'content': chunk.content, 'reasoning_content': chunk.additional_kwargs.get('reasoning_content',
|
||||||
|
'') if chunk.additional_kwargs else ''
|
||||||
|
}
|
||||||
# 是否包含结束
|
# 是否包含结束
|
||||||
if reasoning_content_end_tag_prefix_index > -1:
|
if reasoning_content_end_tag_prefix_index > -1:
|
||||||
if len(self.reasoning_content_chunk) - reasoning_content_end_tag_prefix_index >= self.reasoning_content_end_tag_len:
|
if len(self.reasoning_content_chunk) - reasoning_content_end_tag_prefix_index >= self.reasoning_content_end_tag_len:
|
||||||
|
|
@ -93,7 +98,9 @@ class Reasoning:
|
||||||
else:
|
else:
|
||||||
if self.reasoning_content_is_end:
|
if self.reasoning_content_is_end:
|
||||||
self.content += chunk.content
|
self.content += chunk.content
|
||||||
return {'content': chunk.content, 'reasoning_content': ''}
|
return {'content': chunk.content, 'reasoning_content': chunk.additional_kwargs.get('reasoning_content',
|
||||||
|
'') if chunk.additional_kwargs else ''
|
||||||
|
}
|
||||||
else:
|
else:
|
||||||
# aaa
|
# aaa
|
||||||
result = {'content': '', 'reasoning_content': self.reasoning_content_chunk}
|
result = {'content': '', 'reasoning_content': self.reasoning_content_chunk}
|
||||||
|
|
|
||||||
|
|
@ -170,6 +170,7 @@ class Operate(Enum):
|
||||||
TO_CHAT = "READ+TO_CHAT" # 去对话
|
TO_CHAT = "READ+TO_CHAT" # 去对话
|
||||||
SETTING = "READ+SETTING" # 管理
|
SETTING = "READ+SETTING" # 管理
|
||||||
DOWNLOAD = "READ+DOWNLOAD" # 下载
|
DOWNLOAD = "READ+DOWNLOAD" # 下载
|
||||||
|
AUTH = "READ+AUTH"
|
||||||
|
|
||||||
|
|
||||||
class RoleGroup(Enum):
|
class RoleGroup(Enum):
|
||||||
|
|
@ -335,6 +336,7 @@ Permission_Label = {
|
||||||
Operate.DD.value: _('Dingding'),
|
Operate.DD.value: _('Dingding'),
|
||||||
Operate.WEIXIN_PUBLIC_ACCOUNT.value: _('Weixin Public Account'),
|
Operate.WEIXIN_PUBLIC_ACCOUNT.value: _('Weixin Public Account'),
|
||||||
Operate.ADD_KNOWLEDGE.value: _('Add to Knowledge Base'),
|
Operate.ADD_KNOWLEDGE.value: _('Add to Knowledge Base'),
|
||||||
|
Operate.AUTH.value:_('resource authorization'),
|
||||||
Group.APPLICATION_OVERVIEW.value: _('Overview'),
|
Group.APPLICATION_OVERVIEW.value: _('Overview'),
|
||||||
Group.APPLICATION_ACCESS.value: _('Application Access'),
|
Group.APPLICATION_ACCESS.value: _('Application Access'),
|
||||||
Group.APPLICATION_CHAT_USER.value: _('Dialogue users'),
|
Group.APPLICATION_CHAT_USER.value: _('Dialogue users'),
|
||||||
|
|
@ -481,6 +483,11 @@ class PermissionConstants(Enum):
|
||||||
parent_group=[WorkspaceGroup.MODEL, UserGroup.MODEL],
|
parent_group=[WorkspaceGroup.MODEL, UserGroup.MODEL],
|
||||||
resource_permission_group_list=[ResourcePermissionConst.MODEL_MANGE]
|
resource_permission_group_list=[ResourcePermissionConst.MODEL_MANGE]
|
||||||
)
|
)
|
||||||
|
MODEL_RESOURCE_AUTHORIZATION = Permission(
|
||||||
|
group=Group.MODEL, operate=Operate.AUTH, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
|
||||||
|
parent_group=[WorkspaceGroup.MODEL, UserGroup.MODEL],
|
||||||
|
resource_permission_group_list=[ResourcePermissionConst.MODEL_MANGE]
|
||||||
|
)
|
||||||
TOOL_READ = Permission(
|
TOOL_READ = Permission(
|
||||||
group=Group.TOOL, operate=Operate.READ, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
|
group=Group.TOOL, operate=Operate.READ, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
|
||||||
parent_group=[WorkspaceGroup.TOOL, UserGroup.TOOL],
|
parent_group=[WorkspaceGroup.TOOL, UserGroup.TOOL],
|
||||||
|
|
@ -520,6 +527,11 @@ class PermissionConstants(Enum):
|
||||||
parent_group=[WorkspaceGroup.TOOL, UserGroup.TOOL],
|
parent_group=[WorkspaceGroup.TOOL, UserGroup.TOOL],
|
||||||
resource_permission_group_list=[ResourcePermissionConst.TOOL_MANGE]
|
resource_permission_group_list=[ResourcePermissionConst.TOOL_MANGE]
|
||||||
)
|
)
|
||||||
|
TOOL_RESOURCE_AUTHORIZATION = Permission(
|
||||||
|
group=Group.TOOL, operate=Operate.AUTH, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
|
||||||
|
parent_group=[WorkspaceGroup.TOOL, UserGroup.TOOL],
|
||||||
|
resource_permission_group_list=[ResourcePermissionConst.TOOL_MANGE]
|
||||||
|
)
|
||||||
KNOWLEDGE_READ = Permission(
|
KNOWLEDGE_READ = Permission(
|
||||||
group=Group.KNOWLEDGE, operate=Operate.READ, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
|
group=Group.KNOWLEDGE, operate=Operate.READ, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
|
||||||
resource_permission_group_list=[ResourcePermissionConst.KNOWLEDGE_VIEW],
|
resource_permission_group_list=[ResourcePermissionConst.KNOWLEDGE_VIEW],
|
||||||
|
|
@ -560,6 +572,11 @@ class PermissionConstants(Enum):
|
||||||
resource_permission_group_list=[ResourcePermissionConst.KNOWLEDGE_MANGE],
|
resource_permission_group_list=[ResourcePermissionConst.KNOWLEDGE_MANGE],
|
||||||
parent_group=[WorkspaceGroup.KNOWLEDGE, UserGroup.KNOWLEDGE]
|
parent_group=[WorkspaceGroup.KNOWLEDGE, UserGroup.KNOWLEDGE]
|
||||||
)
|
)
|
||||||
|
KNOWLEDGE_RESOURCE_AUTHORIZATION = Permission(
|
||||||
|
group=Group.KNOWLEDGE, operate=Operate.AUTH, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
|
||||||
|
resource_permission_group_list=[ResourcePermissionConst.KNOWLEDGE_MANGE],
|
||||||
|
parent_group=[WorkspaceGroup.KNOWLEDGE, UserGroup.KNOWLEDGE]
|
||||||
|
)
|
||||||
KNOWLEDGE_DOCUMENT_READ = Permission(
|
KNOWLEDGE_DOCUMENT_READ = Permission(
|
||||||
group=Group.KNOWLEDGE_DOCUMENT, operate=Operate.READ,
|
group=Group.KNOWLEDGE_DOCUMENT, operate=Operate.READ,
|
||||||
role_list=[RoleConstants.ADMIN, RoleConstants.USER],
|
role_list=[RoleConstants.ADMIN, RoleConstants.USER],
|
||||||
|
|
@ -819,7 +836,11 @@ class PermissionConstants(Enum):
|
||||||
parent_group=[WorkspaceGroup.APPLICATION, UserGroup.APPLICATION],
|
parent_group=[WorkspaceGroup.APPLICATION, UserGroup.APPLICATION],
|
||||||
resource_permission_group_list=[ResourcePermissionConst.APPLICATION_MANGE],
|
resource_permission_group_list=[ResourcePermissionConst.APPLICATION_MANGE],
|
||||||
)
|
)
|
||||||
|
APPLICATION_RESOURCE_AUTHORIZATION = Permission(group=Group.APPLICATION, operate=Operate.AUTH,
|
||||||
|
role_list=[RoleConstants.ADMIN, RoleConstants.USER],
|
||||||
|
parent_group=[WorkspaceGroup.APPLICATION, UserGroup.APPLICATION],
|
||||||
|
resource_permission_group_list=[ResourcePermissionConst.APPLICATION_MANGE],
|
||||||
|
)
|
||||||
APPLICATION_OVERVIEW_READ = Permission(group=Group.APPLICATION_OVERVIEW, operate=Operate.READ,
|
APPLICATION_OVERVIEW_READ = Permission(group=Group.APPLICATION_OVERVIEW, operate=Operate.READ,
|
||||||
role_list=[RoleConstants.ADMIN, RoleConstants.USER],
|
role_list=[RoleConstants.ADMIN, RoleConstants.USER],
|
||||||
parent_group=[WorkspaceGroup.APPLICATION, UserGroup.APPLICATION],
|
parent_group=[WorkspaceGroup.APPLICATION, UserGroup.APPLICATION],
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ from typing import List, Dict
|
||||||
from common.forms.base_field import BaseExecField, TriggerType
|
from common.forms.base_field import BaseExecField, TriggerType
|
||||||
|
|
||||||
|
|
||||||
class Radio(BaseExecField):
|
class RadioButton(BaseExecField):
|
||||||
"""
|
"""
|
||||||
下拉单选
|
下拉单选
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ from typing import List, Dict
|
||||||
from common.forms.base_field import BaseExecField, TriggerType
|
from common.forms.base_field import BaseExecField, TriggerType
|
||||||
|
|
||||||
|
|
||||||
class Radio(BaseExecField):
|
class RadioCard(BaseExecField):
|
||||||
"""
|
"""
|
||||||
下拉单选
|
下拉单选
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -406,6 +406,15 @@ class ParagraphSerializers(serializers.Serializer):
|
||||||
def association(self, with_valid=True, with_embedding=True):
|
def association(self, with_valid=True, with_embedding=True):
|
||||||
if with_valid:
|
if with_valid:
|
||||||
self.is_valid(raise_exception=True)
|
self.is_valid(raise_exception=True)
|
||||||
|
# 已关联则直接返回
|
||||||
|
if QuerySet(ProblemParagraphMapping).filter(
|
||||||
|
knowledge_id=self.data.get('knowledge_id'),
|
||||||
|
document_id=self.data.get('document_id'),
|
||||||
|
paragraph_id=self.data.get('paragraph_id'),
|
||||||
|
problem_id=self.data.get('problem_id')
|
||||||
|
).exists():
|
||||||
|
return True
|
||||||
|
|
||||||
problem = QuerySet(Problem).filter(id=self.data.get("problem_id")).first()
|
problem = QuerySet(Problem).filter(id=self.data.get("problem_id")).first()
|
||||||
problem_paragraph_mapping = ProblemParagraphMapping(id=uuid.uuid7(),
|
problem_paragraph_mapping = ProblemParagraphMapping(id=uuid.uuid7(),
|
||||||
document_id=self.data.get('document_id'),
|
document_id=self.data.get('document_id'),
|
||||||
|
|
|
||||||
|
|
@ -8649,3 +8649,15 @@ msgstr ""
|
||||||
|
|
||||||
msgid "This interface is used to recognize short audio files within 60 seconds. Supports Mandarin Chinese, English, Cantonese, Japanese, Vietnamese, Malay, Indonesian, Filipino, Thai, Portuguese, Turkish, Arabic, Hindi, French, German, and 23 Chinese dialects."
|
msgid "This interface is used to recognize short audio files within 60 seconds. Supports Mandarin Chinese, English, Cantonese, Japanese, Vietnamese, Malay, Indonesian, Filipino, Thai, Portuguese, Turkish, Arabic, Hindi, French, German, and 23 Chinese dialects."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "CueWord"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "If not passed, the default value is What is this audio saying? Only answer the audio content"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "The Qwen Omni series model supports inputting multiple modalities of data, including video, audio, images, and text, and outputting audio and text."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "resource authorization"
|
||||||
|
msgstr ""
|
||||||
|
|
@ -8775,3 +8775,15 @@ msgstr "多种方言,支持 23 种方言"
|
||||||
|
|
||||||
msgid "This interface is used to recognize short audio files within 60 seconds. Supports Mandarin Chinese, English, Cantonese, Japanese, Vietnamese, Malay, Indonesian, Filipino, Thai, Portuguese, Turkish, Arabic, Hindi, French, German, and 23 Chinese dialects."
|
msgid "This interface is used to recognize short audio files within 60 seconds. Supports Mandarin Chinese, English, Cantonese, Japanese, Vietnamese, Malay, Indonesian, Filipino, Thai, Portuguese, Turkish, Arabic, Hindi, French, German, and 23 Chinese dialects."
|
||||||
msgstr "本接口用于识别 60 秒之内的短音频文件。支持中文普通话、英语、粤语、日语、越南语、马来语、印度尼西亚语、菲律宾语、泰语、葡萄牙语、土耳其语、阿拉伯语、印地语、法语、德语及 23 种汉语方言。"
|
msgstr "本接口用于识别 60 秒之内的短音频文件。支持中文普通话、英语、粤语、日语、越南语、马来语、印度尼西亚语、菲律宾语、泰语、葡萄牙语、土耳其语、阿拉伯语、印地语、法语、德语及 23 种汉语方言。"
|
||||||
|
|
||||||
|
msgid "CueWord"
|
||||||
|
msgstr "提示词"
|
||||||
|
|
||||||
|
msgid "If not passed, the default value is What is this audio saying? Only answer the audio content"
|
||||||
|
msgstr "如果未传递,默认值为 这段音频在说什么,只回答音频的内容"
|
||||||
|
|
||||||
|
msgid "The Qwen Omni series model supports inputting multiple modalities of data, including video, audio, images, and text, and outputting audio and text."
|
||||||
|
msgstr "Qwen-Omni 系列模型支持输入多种模态的数据,包括视频、音频、图片、文本,并输出音频与文本"
|
||||||
|
|
||||||
|
msgid "resource authorization"
|
||||||
|
msgstr "资源授权"
|
||||||
|
|
@ -8775,3 +8775,15 @@ msgstr "多種方言,支持 23 種方言"
|
||||||
|
|
||||||
msgid "This interface is used to recognize short audio files within 60 seconds. Supports Mandarin Chinese, English, Cantonese, Japanese, Vietnamese, Malay, Indonesian, Filipino, Thai, Portuguese, Turkish, Arabic, Hindi, French, German, and 23 Chinese dialects."
|
msgid "This interface is used to recognize short audio files within 60 seconds. Supports Mandarin Chinese, English, Cantonese, Japanese, Vietnamese, Malay, Indonesian, Filipino, Thai, Portuguese, Turkish, Arabic, Hindi, French, German, and 23 Chinese dialects."
|
||||||
msgstr "本介面用於識別 60 秒之內的短音頻文件。支援中文普通話、英語、粵語、日語、越南語、馬來語、印度尼西亞語、菲律賓語、泰語、葡萄牙語、土耳其語、阿拉伯語、印地語、法語、德語及 23 種漢語方言。"
|
msgstr "本介面用於識別 60 秒之內的短音頻文件。支援中文普通話、英語、粵語、日語、越南語、馬來語、印度尼西亞語、菲律賓語、泰語、葡萄牙語、土耳其語、阿拉伯語、印地語、法語、德語及 23 種漢語方言。"
|
||||||
|
|
||||||
|
msgid "CueWord"
|
||||||
|
msgstr "提示詞"
|
||||||
|
|
||||||
|
msgid "If not passed, the default value is What is this audio saying? Only answer the audio content"
|
||||||
|
msgstr "如果未傳遞,預設值為這段音訊在說什麼,只回答音訊的內容"
|
||||||
|
|
||||||
|
msgid "The Qwen Omni series model supports inputting multiple modalities of data, including video, audio, images, and text, and outputting audio and text."
|
||||||
|
msgstr "Qwen-Omni系列模型支持輸入多種模態的數據,包括視頻、音訊、圖片、文字,並輸出音訊與文字"
|
||||||
|
|
||||||
|
msgid "resource authorization"
|
||||||
|
msgstr "資源授權"
|
||||||
|
|
@ -15,6 +15,7 @@ from models_provider.impl.aliyun_bai_lian_model_provider.credential.embedding im
|
||||||
AliyunBaiLianEmbeddingCredential
|
AliyunBaiLianEmbeddingCredential
|
||||||
from models_provider.impl.aliyun_bai_lian_model_provider.credential.image import QwenVLModelCredential
|
from models_provider.impl.aliyun_bai_lian_model_provider.credential.image import QwenVLModelCredential
|
||||||
from models_provider.impl.aliyun_bai_lian_model_provider.credential.llm import BaiLianLLMModelCredential
|
from models_provider.impl.aliyun_bai_lian_model_provider.credential.llm import BaiLianLLMModelCredential
|
||||||
|
from models_provider.impl.aliyun_bai_lian_model_provider.credential.omni_stt import AliyunBaiLianOmiSTTModelCredential
|
||||||
from models_provider.impl.aliyun_bai_lian_model_provider.credential.reranker import \
|
from models_provider.impl.aliyun_bai_lian_model_provider.credential.reranker import \
|
||||||
AliyunBaiLianRerankerCredential
|
AliyunBaiLianRerankerCredential
|
||||||
from models_provider.impl.aliyun_bai_lian_model_provider.credential.stt import AliyunBaiLianSTTModelCredential
|
from models_provider.impl.aliyun_bai_lian_model_provider.credential.stt import AliyunBaiLianSTTModelCredential
|
||||||
|
|
@ -23,6 +24,7 @@ from models_provider.impl.aliyun_bai_lian_model_provider.credential.tts import A
|
||||||
from models_provider.impl.aliyun_bai_lian_model_provider.model.embedding import AliyunBaiLianEmbedding
|
from models_provider.impl.aliyun_bai_lian_model_provider.model.embedding import AliyunBaiLianEmbedding
|
||||||
from models_provider.impl.aliyun_bai_lian_model_provider.model.image import QwenVLChatModel
|
from models_provider.impl.aliyun_bai_lian_model_provider.model.image import QwenVLChatModel
|
||||||
from models_provider.impl.aliyun_bai_lian_model_provider.model.llm import BaiLianChatModel
|
from models_provider.impl.aliyun_bai_lian_model_provider.model.llm import BaiLianChatModel
|
||||||
|
from models_provider.impl.aliyun_bai_lian_model_provider.model.omni_stt import AliyunBaiLianOmiSpeechToText
|
||||||
from models_provider.impl.aliyun_bai_lian_model_provider.model.reranker import AliyunBaiLianReranker
|
from models_provider.impl.aliyun_bai_lian_model_provider.model.reranker import AliyunBaiLianReranker
|
||||||
from models_provider.impl.aliyun_bai_lian_model_provider.model.stt import AliyunBaiLianSpeechToText
|
from models_provider.impl.aliyun_bai_lian_model_provider.model.stt import AliyunBaiLianSpeechToText
|
||||||
from models_provider.impl.aliyun_bai_lian_model_provider.model.tti import QwenTextToImageModel
|
from models_provider.impl.aliyun_bai_lian_model_provider.model.tti import QwenTextToImageModel
|
||||||
|
|
@ -33,6 +35,7 @@ from django.utils.translation import gettext as _, gettext
|
||||||
aliyun_bai_lian_model_credential = AliyunBaiLianRerankerCredential()
|
aliyun_bai_lian_model_credential = AliyunBaiLianRerankerCredential()
|
||||||
aliyun_bai_lian_tts_model_credential = AliyunBaiLianTTSModelCredential()
|
aliyun_bai_lian_tts_model_credential = AliyunBaiLianTTSModelCredential()
|
||||||
aliyun_bai_lian_stt_model_credential = AliyunBaiLianSTTModelCredential()
|
aliyun_bai_lian_stt_model_credential = AliyunBaiLianSTTModelCredential()
|
||||||
|
aliyun_bai_lian_omi_stt_model_credential = AliyunBaiLianOmiSTTModelCredential()
|
||||||
aliyun_bai_lian_embedding_model_credential = AliyunBaiLianEmbeddingCredential()
|
aliyun_bai_lian_embedding_model_credential = AliyunBaiLianEmbeddingCredential()
|
||||||
aliyun_bai_lian_llm_model_credential = BaiLianLLMModelCredential()
|
aliyun_bai_lian_llm_model_credential = BaiLianLLMModelCredential()
|
||||||
qwenvl_model_credential = QwenVLModelCredential()
|
qwenvl_model_credential = QwenVLModelCredential()
|
||||||
|
|
@ -73,7 +76,13 @@ model_info_list = [ModelInfo('gte-rerank',
|
||||||
ModelInfo('qwen-plus', '', ModelTypeConst.LLM, aliyun_bai_lian_llm_model_credential,
|
ModelInfo('qwen-plus', '', ModelTypeConst.LLM, aliyun_bai_lian_llm_model_credential,
|
||||||
BaiLianChatModel),
|
BaiLianChatModel),
|
||||||
ModelInfo('qwen-max', '', ModelTypeConst.LLM, aliyun_bai_lian_llm_model_credential,
|
ModelInfo('qwen-max', '', ModelTypeConst.LLM, aliyun_bai_lian_llm_model_credential,
|
||||||
BaiLianChatModel)
|
BaiLianChatModel),
|
||||||
|
ModelInfo('qwen-omni-turbo',
|
||||||
|
_('The Qwen Omni series model supports inputting multiple modalities of data, including video, audio, images, and text, and outputting audio and text.'),
|
||||||
|
ModelTypeConst.STT, aliyun_bai_lian_omi_stt_model_credential, AliyunBaiLianOmiSpeechToText),
|
||||||
|
ModelInfo('qwen2.5-omni-7b',
|
||||||
|
_('The Qwen Omni series model supports inputting multiple modalities of data, including video, audio, images, and text, and outputting audio and text.'),
|
||||||
|
ModelTypeConst.STT, aliyun_bai_lian_omi_stt_model_credential, AliyunBaiLianOmiSpeechToText),
|
||||||
]
|
]
|
||||||
|
|
||||||
module_info_vl_list = [
|
module_info_vl_list = [
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,73 @@
|
||||||
|
# coding=utf-8
|
||||||
|
import traceback
|
||||||
|
from typing import Dict, Any
|
||||||
|
|
||||||
|
from common import forms
|
||||||
|
from common.exception.app_exception import AppApiException
|
||||||
|
from common.forms import BaseForm, PasswordInputField, TooltipLabel
|
||||||
|
from models_provider.base_model_provider import BaseModelCredential, ValidCode
|
||||||
|
from django.utils.translation import gettext as _
|
||||||
|
|
||||||
|
class AliyunBaiLianOmiSTTModelParams(BaseForm):
|
||||||
|
CueWord = forms.TextInputField(
|
||||||
|
TooltipLabel(_('CueWord'), _('If not passed, the default value is What is this audio saying? Only answer the audio content')),
|
||||||
|
required=True,
|
||||||
|
default_value='这段音频在说什么,只回答音频的内容',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class AliyunBaiLianOmiSTTModelCredential(BaseForm, BaseModelCredential):
|
||||||
|
api_url = forms.TextInputField(_('API URL'), required=True)
|
||||||
|
api_key = forms.PasswordInputField(_('API Key'), required=True)
|
||||||
|
|
||||||
|
def is_valid(self,
|
||||||
|
model_type: str,
|
||||||
|
model_name: str,
|
||||||
|
model_credential: Dict[str, Any],
|
||||||
|
model_params: Dict[str, Any],
|
||||||
|
provider,
|
||||||
|
raise_exception: bool = False
|
||||||
|
) -> bool:
|
||||||
|
|
||||||
|
model_type_list = provider.get_model_type_list()
|
||||||
|
if not any(mt.get('value') == model_type for mt in model_type_list):
|
||||||
|
raise AppApiException(
|
||||||
|
ValidCode.valid_error.value,
|
||||||
|
_('{model_type} Model type is not supported').format(model_type=model_type)
|
||||||
|
)
|
||||||
|
|
||||||
|
required_keys = ['api_key']
|
||||||
|
for key in required_keys:
|
||||||
|
if key not in model_credential:
|
||||||
|
if raise_exception:
|
||||||
|
raise AppApiException(
|
||||||
|
ValidCode.valid_error.value,
|
||||||
|
_('{key} is required').format(key=key)
|
||||||
|
)
|
||||||
|
return False
|
||||||
|
|
||||||
|
try:
|
||||||
|
model = provider.get_model(model_type, model_name, model_credential)
|
||||||
|
except Exception as e:
|
||||||
|
traceback.print_exc()
|
||||||
|
if isinstance(e, AppApiException):
|
||||||
|
raise e
|
||||||
|
if raise_exception:
|
||||||
|
raise AppApiException(
|
||||||
|
ValidCode.valid_error.value,
|
||||||
|
_('Verification failed, please check whether the parameters are correct: {error}').format(error=str(e))
|
||||||
|
)
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def encryption_dict(self, model: Dict[str, object]) -> Dict[str, object]:
|
||||||
|
|
||||||
|
return {
|
||||||
|
**model,
|
||||||
|
'api_key': super().encryption(model.get('api_key', ''))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def get_model_params_setting_form(self, model_name):
|
||||||
|
|
||||||
|
return AliyunBaiLianOmiSTTModelParams()
|
||||||
|
|
@ -0,0 +1,89 @@
|
||||||
|
import base64
|
||||||
|
import os
|
||||||
|
import traceback
|
||||||
|
from typing import Dict
|
||||||
|
|
||||||
|
from openai import OpenAI
|
||||||
|
|
||||||
|
from common.utils.logger import maxkb_logger
|
||||||
|
from models_provider.base_model_provider import MaxKBBaseModel
|
||||||
|
from models_provider.impl.base_stt import BaseSpeechToText
|
||||||
|
|
||||||
|
|
||||||
|
class AliyunBaiLianOmiSpeechToText(MaxKBBaseModel, BaseSpeechToText):
|
||||||
|
api_key: str
|
||||||
|
api_url: str
|
||||||
|
model: str
|
||||||
|
params: dict
|
||||||
|
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
super().__init__(**kwargs)
|
||||||
|
self.api_key = kwargs.get('api_key')
|
||||||
|
self.model = kwargs.get('model')
|
||||||
|
self.params = kwargs.get('params')
|
||||||
|
self.api_url = kwargs.get('api_url')
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def is_cache_model():
|
||||||
|
return False
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def new_instance(model_type, model_name, model_credential: Dict[str, object], **model_kwargs):
|
||||||
|
return AliyunBaiLianOmiSpeechToText(
|
||||||
|
model=model_name,
|
||||||
|
api_key=model_credential.get('api_key'),
|
||||||
|
api_url=model_credential.get('api_url') ,
|
||||||
|
params= model_kwargs,
|
||||||
|
**model_kwargs
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def check_auth(self):
|
||||||
|
cwd = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
with open(f'{cwd}/iat_mp3_16k.mp3', 'rb') as audio_file:
|
||||||
|
self.speech_to_text(audio_file)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def speech_to_text(self, audio_file):
|
||||||
|
try:
|
||||||
|
client = OpenAI(
|
||||||
|
# 若没有配置环境变量,请用阿里云百炼API Key将下行替换为:api_key="sk-xxx",
|
||||||
|
api_key=self.api_key,
|
||||||
|
base_url=self.api_url,
|
||||||
|
)
|
||||||
|
|
||||||
|
base64_audio = base64.b64encode(audio_file.read()).decode("utf-8")
|
||||||
|
|
||||||
|
completion = client.chat.completions.create(
|
||||||
|
model=self.model,
|
||||||
|
messages=[
|
||||||
|
{
|
||||||
|
"role": "user",
|
||||||
|
"content": [
|
||||||
|
{
|
||||||
|
"type": "input_audio",
|
||||||
|
"input_audio": {
|
||||||
|
"data": f"data:;base64,{base64_audio}",
|
||||||
|
"format": "mp3",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{"type": "text", "text": self.params.get('CueWord')},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
# 设置输出数据的模态,当前支持两种:["text","audio"]、["text"]
|
||||||
|
modalities=["text"],
|
||||||
|
# stream 必须设置为 True,否则会报错
|
||||||
|
stream=True,
|
||||||
|
stream_options={"include_usage": True},
|
||||||
|
)
|
||||||
|
result = []
|
||||||
|
for chunk in completion:
|
||||||
|
if chunk.choices and hasattr(chunk.choices[0].delta, 'content'):
|
||||||
|
content = chunk.choices[0].delta.content
|
||||||
|
result.append(content)
|
||||||
|
return "".join(result)
|
||||||
|
|
||||||
|
except Exception as err:
|
||||||
|
maxkb_logger.error(f":Error: {str(err)}: {traceback.format_exc()}")
|
||||||
|
|
@ -30,8 +30,6 @@ class AliyunBaiLianSpeechToText(MaxKBBaseModel, BaseSpeechToText):
|
||||||
optional_params['max_tokens'] = model_kwargs['max_tokens']
|
optional_params['max_tokens'] = model_kwargs['max_tokens']
|
||||||
if 'temperature' in model_kwargs and model_kwargs['temperature'] is not None:
|
if 'temperature' in model_kwargs and model_kwargs['temperature'] is not None:
|
||||||
optional_params['temperature'] = model_kwargs['temperature']
|
optional_params['temperature'] = model_kwargs['temperature']
|
||||||
if model_name == 'qwen-omni-turbo':
|
|
||||||
optional_params['streaming'] = True
|
|
||||||
return AliyunBaiLianSpeechToText(
|
return AliyunBaiLianSpeechToText(
|
||||||
model=model_name,
|
model=model_name,
|
||||||
api_key=model_credential.get('api_key'),
|
api_key=model_credential.get('api_key'),
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import base64
|
import base64
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
import traceback
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
|
|
||||||
from tencentcloud.asr.v20190614 import asr_client, models
|
from tencentcloud.asr.v20190614 import asr_client, models
|
||||||
|
|
@ -9,6 +10,7 @@ from tencentcloud.common.exception import TencentCloudSDKException
|
||||||
from tencentcloud.common.profile.client_profile import ClientProfile
|
from tencentcloud.common.profile.client_profile import ClientProfile
|
||||||
from tencentcloud.common.profile.http_profile import HttpProfile
|
from tencentcloud.common.profile.http_profile import HttpProfile
|
||||||
|
|
||||||
|
from common.utils.logger import maxkb_logger
|
||||||
from models_provider.base_model_provider import MaxKBBaseModel
|
from models_provider.base_model_provider import MaxKBBaseModel
|
||||||
from models_provider.impl.base_stt import BaseSpeechToText
|
from models_provider.impl.base_stt import BaseSpeechToText
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,16 +40,23 @@ class WenxinLLMModelParams(BaseForm):
|
||||||
class WenxinLLMModelCredential(BaseForm, BaseModelCredential):
|
class WenxinLLMModelCredential(BaseForm, BaseModelCredential):
|
||||||
def is_valid(self, model_type: str, model_name, model_credential: Dict[str, object], model_params, provider,
|
def is_valid(self, model_type: str, model_name, model_credential: Dict[str, object], model_params, provider,
|
||||||
raise_exception=False):
|
raise_exception=False):
|
||||||
model_type_list = provider.get_model_type_list()
|
# 根据api_version检查必需字段
|
||||||
if not any(list(filter(lambda mt: mt.get('value') == model_type, model_type_list))):
|
api_version = model_credential.get('api_version', 'v1')
|
||||||
raise AppApiException(ValidCode.valid_error.value,
|
|
||||||
gettext('{model_type} Model type is not supported').format(model_type=model_type))
|
|
||||||
model = provider.get_model(model_type, model_name, model_credential, **model_params)
|
model = provider.get_model(model_type, model_name, model_credential, **model_params)
|
||||||
model_info = [model.lower() for model in model.client.models()]
|
if api_version == 'v1':
|
||||||
if not model_info.__contains__(model_name.lower()):
|
model_type_list = provider.get_model_type_list()
|
||||||
raise AppApiException(ValidCode.valid_error.value,
|
if not any(list(filter(lambda mt: mt.get('value') == model_type, model_type_list))):
|
||||||
gettext('{model_name} The model does not support').format(model_name=model_name))
|
raise AppApiException(ValidCode.valid_error.value,
|
||||||
for key in ['api_key', 'secret_key']:
|
gettext('{model_type} Model type is not supported').format(model_type=model_type))
|
||||||
|
model_info = [model.lower() for model in model.client.models()]
|
||||||
|
if not model_info.__contains__(model_name.lower()):
|
||||||
|
raise AppApiException(ValidCode.valid_error.value,
|
||||||
|
gettext('{model_name} The model does not support').format(model_name=model_name))
|
||||||
|
required_keys = ['api_key', 'secret_key']
|
||||||
|
if api_version == 'v2':
|
||||||
|
required_keys = ['api_base', 'api_key']
|
||||||
|
|
||||||
|
for key in required_keys:
|
||||||
if key not in model_credential:
|
if key not in model_credential:
|
||||||
if raise_exception:
|
if raise_exception:
|
||||||
raise AppApiException(ValidCode.valid_error.value, gettext('{key} is required').format(key=key))
|
raise AppApiException(ValidCode.valid_error.value, gettext('{key} is required').format(key=key))
|
||||||
|
|
@ -64,19 +71,47 @@ class WenxinLLMModelCredential(BaseForm, BaseModelCredential):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def encryption_dict(self, model_info: Dict[str, object]):
|
def encryption_dict(self, model_info: Dict[str, object]):
|
||||||
return {**model_info, 'secret_key': super().encryption(model_info.get('secret_key', ''))}
|
# 根据api_version加密不同字段
|
||||||
|
api_version = model_info.get('api_version', 'v1')
|
||||||
|
if api_version == 'v1':
|
||||||
|
return {**model_info, 'secret_key': super().encryption(model_info.get('secret_key', ''))}
|
||||||
|
else: # v2
|
||||||
|
return {**model_info, 'api_key': super().encryption(model_info.get('api_key', ''))}
|
||||||
|
|
||||||
def build_model(self, model_info: Dict[str, object]):
|
def build_model(self, model_info: Dict[str, object]):
|
||||||
for key in ['api_key', 'secret_key', 'model']:
|
api_version = model_info.get('api_version', 'v1')
|
||||||
if key not in model_info:
|
# 根据api_version检查必需字段
|
||||||
raise AppApiException(500, gettext('{key} is required').format(key=key))
|
if api_version == 'v1':
|
||||||
self.api_key = model_info.get('api_key')
|
for key in ['api_version', 'api_key', 'secret_key', 'model']:
|
||||||
self.secret_key = model_info.get('secret_key')
|
if key not in model_info:
|
||||||
|
raise AppApiException(500, gettext('{key} is required').format(key=key))
|
||||||
|
self.api_key = model_info.get('api_key')
|
||||||
|
self.secret_key = model_info.get('secret_key')
|
||||||
|
else: # v2
|
||||||
|
for key in ['api_version', 'api_base', 'api_key', 'model', ]:
|
||||||
|
if key not in model_info:
|
||||||
|
raise AppApiException(500, gettext('{key} is required').format(key=key))
|
||||||
|
self.api_base = model_info.get('api_base')
|
||||||
|
self.api_key = model_info.get('api_key')
|
||||||
return self
|
return self
|
||||||
|
|
||||||
api_key = forms.PasswordInputField('API Key', required=True)
|
# 动态字段定义 - 根据api_version显示不同字段
|
||||||
|
api_version = forms.Radio('API Version', required=True, text_field='label', value_field='value',
|
||||||
|
option_list=[
|
||||||
|
{'label': 'v1', 'value': 'v1'},
|
||||||
|
{'label': 'v2', 'value': 'v2'}
|
||||||
|
],
|
||||||
|
default_value='v1',
|
||||||
|
provider='',
|
||||||
|
method='', )
|
||||||
|
|
||||||
secret_key = forms.PasswordInputField("Secret Key", required=True)
|
# v2版本字段
|
||||||
|
api_base = forms.TextInputField("API Base", required=False, relation_show_field_dict={"api_version": ["v2"]})
|
||||||
|
|
||||||
|
# v1版本字段
|
||||||
|
api_key = forms.PasswordInputField('API Key', required=False)
|
||||||
|
secret_key = forms.PasswordInputField("Secret Key", required=False,
|
||||||
|
relation_show_field_dict={"api_version": ["v1"]})
|
||||||
|
|
||||||
def get_model_params_setting_form(self, model_name):
|
def get_model_params_setting_form(self, model_name):
|
||||||
return WenxinLLMModelParams()
|
return WenxinLLMModelParams()
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,10 @@ from langchain_core.messages import (
|
||||||
from langchain_core.outputs import ChatGenerationChunk
|
from langchain_core.outputs import ChatGenerationChunk
|
||||||
|
|
||||||
from models_provider.base_model_provider import MaxKBBaseModel
|
from models_provider.base_model_provider import MaxKBBaseModel
|
||||||
|
from models_provider.impl.base_chat_open_ai import BaseChatOpenAI
|
||||||
|
|
||||||
|
|
||||||
class QianfanChatModel(MaxKBBaseModel, QianfanChatEndpoint):
|
class QianfanChatModelQianfan(MaxKBBaseModel, QianfanChatEndpoint):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def is_cache_model():
|
def is_cache_model():
|
||||||
return False
|
return False
|
||||||
|
|
@ -27,11 +28,11 @@ class QianfanChatModel(MaxKBBaseModel, QianfanChatEndpoint):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def new_instance(model_type, model_name, model_credential: Dict[str, object], **model_kwargs):
|
def new_instance(model_type, model_name, model_credential: Dict[str, object], **model_kwargs):
|
||||||
optional_params = MaxKBBaseModel.filter_optional_params(model_kwargs)
|
optional_params = MaxKBBaseModel.filter_optional_params(model_kwargs)
|
||||||
return QianfanChatModel(model=model_name,
|
return QianfanChatModelQianfan(model=model_name,
|
||||||
qianfan_ak=model_credential.get('api_key'),
|
qianfan_ak=model_credential.get('api_key'),
|
||||||
qianfan_sk=model_credential.get('secret_key'),
|
qianfan_sk=model_credential.get('secret_key'),
|
||||||
streaming=model_kwargs.get('streaming', False),
|
streaming=model_kwargs.get('streaming', False),
|
||||||
init_kwargs=optional_params)
|
init_kwargs=optional_params)
|
||||||
|
|
||||||
usage_metadata: dict = {}
|
usage_metadata: dict = {}
|
||||||
|
|
||||||
|
|
@ -74,3 +75,30 @@ class QianfanChatModel(MaxKBBaseModel, QianfanChatEndpoint):
|
||||||
if run_manager:
|
if run_manager:
|
||||||
run_manager.on_llm_new_token(chunk.text, chunk=chunk)
|
run_manager.on_llm_new_token(chunk.text, chunk=chunk)
|
||||||
yield chunk
|
yield chunk
|
||||||
|
|
||||||
|
|
||||||
|
class QianfanChatModelOpenai(MaxKBBaseModel, BaseChatOpenAI):
|
||||||
|
@staticmethod
|
||||||
|
def is_cache_model():
|
||||||
|
return False
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def new_instance(model_type, model_name, model_credential: Dict[str, object], **model_kwargs):
|
||||||
|
optional_params = MaxKBBaseModel.filter_optional_params(model_kwargs)
|
||||||
|
return QianfanChatModelOpenai(
|
||||||
|
model=model_name,
|
||||||
|
openai_api_base=model_credential.get('api_base'),
|
||||||
|
openai_api_key=model_credential.get('api_key'),
|
||||||
|
extra_body=optional_params
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class QianfanChatModel(MaxKBBaseModel):
|
||||||
|
@staticmethod
|
||||||
|
def new_instance(model_type, model_name, model_credential: Dict[str, object], **model_kwargs):
|
||||||
|
api_version = model_credential.get('api_version', 'v1')
|
||||||
|
|
||||||
|
if api_version == "v1":
|
||||||
|
return QianfanChatModelQianfan.new_instance(model_type, model_name, model_credential, **model_kwargs)
|
||||||
|
elif api_version == "v2":
|
||||||
|
return QianfanChatModelOpenai.new_instance(model_type, model_name, model_credential, **model_kwargs)
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,8 @@ from rest_framework.views import APIView
|
||||||
from common import result
|
from common import result
|
||||||
from common.auth import TokenAuth
|
from common.auth import TokenAuth
|
||||||
from common.auth.authentication import has_permissions
|
from common.auth.authentication import has_permissions
|
||||||
from common.constants.permission_constants import PermissionConstants, RoleConstants, Permission, Group, Operate
|
from common.constants.permission_constants import RoleConstants, Permission, Group, Operate, ViewPermission, \
|
||||||
|
CompareConstants
|
||||||
from common.log.log import log
|
from common.log.log import log
|
||||||
from system_manage.api.user_resource_permission import UserResourcePermissionAPI, EditUserResourcePermissionAPI, \
|
from system_manage.api.user_resource_permission import UserResourcePermissionAPI, EditUserResourcePermissionAPI, \
|
||||||
ResourceUserPermissionAPI, ResourceUserPermissionPageAPI, ResourceUserPermissionEditAPI, \
|
ResourceUserPermissionAPI, ResourceUserPermissionPageAPI, ResourceUserPermissionEditAPI, \
|
||||||
|
|
@ -89,6 +90,10 @@ class WorkSpaceUserResourcePermissionView(APIView):
|
||||||
responses=UserResourcePermissionPageAPI.get_response(),
|
responses=UserResourcePermissionPageAPI.get_response(),
|
||||||
tags=[_('Resources authorization')] # type: ignore
|
tags=[_('Resources authorization')] # type: ignore
|
||||||
)
|
)
|
||||||
|
@has_permissions(
|
||||||
|
lambda r, kwargs: Permission(group=Group(kwargs.get('resource') + '_WORKSPACE_USER_RESOURCE_PERMISSION'),
|
||||||
|
operate=Operate.READ),
|
||||||
|
RoleConstants.ADMIN, RoleConstants.WORKSPACE_MANAGE.get_workspace_role())
|
||||||
def get(self, request: Request, workspace_id: str, user_id: str, resource: str, current_page: str,
|
def get(self, request: Request, workspace_id: str, user_id: str, resource: str, current_page: str,
|
||||||
page_size: str):
|
page_size: str):
|
||||||
return result.success(UserResourcePermissionSerializer(
|
return result.success(UserResourcePermissionSerializer(
|
||||||
|
|
@ -109,6 +114,19 @@ class WorkspaceResourceUserPermissionView(APIView):
|
||||||
responses=ResourceUserPermissionAPI.get_response(),
|
responses=ResourceUserPermissionAPI.get_response(),
|
||||||
tags=[_('Resources authorization')] # type: ignore
|
tags=[_('Resources authorization')] # type: ignore
|
||||||
)
|
)
|
||||||
|
@has_permissions(
|
||||||
|
lambda r, kwargs: Permission(group=Group(kwargs.get('resource')),
|
||||||
|
operate=Operate.AUTH,
|
||||||
|
resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}/ROLE/WORKSPACE_MANAGE"),
|
||||||
|
lambda r, kwargs: Permission(group=Group(kwargs.get('resource')),
|
||||||
|
operate=Operate.AUTH,
|
||||||
|
resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}/{kwargs.get('resource')}/{kwargs.get('target')}"),
|
||||||
|
ViewPermission([RoleConstants.USER.get_workspace_role()],
|
||||||
|
[lambda r, kwargs: Permission(group=Group(kwargs.get('resource')),
|
||||||
|
operate=Operate.SELF,
|
||||||
|
resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}/{kwargs.get('resource')}/{kwargs.get('target')}")],
|
||||||
|
CompareConstants.AND),
|
||||||
|
RoleConstants.WORKSPACE_MANAGE.get_workspace_role())
|
||||||
def get(self, request: Request, workspace_id: str, target: str, resource: str):
|
def get(self, request: Request, workspace_id: str, target: str, resource: str):
|
||||||
return result.success(ResourceUserPermissionSerializer(
|
return result.success(ResourceUserPermissionSerializer(
|
||||||
data={'workspace_id': workspace_id, "target": target, 'auth_target_type': resource,
|
data={'workspace_id': workspace_id, "target": target, 'auth_target_type': resource,
|
||||||
|
|
@ -127,6 +145,22 @@ class WorkspaceResourceUserPermissionView(APIView):
|
||||||
responses=ResourceUserPermissionEditAPI.get_response(),
|
responses=ResourceUserPermissionEditAPI.get_response(),
|
||||||
tags=[_('Resources authorization')] # type: ignore
|
tags=[_('Resources authorization')] # type: ignore
|
||||||
)
|
)
|
||||||
|
@log(menu='System', operate='Edit user authorization status of resource',
|
||||||
|
get_operation_object=lambda r, k: get_user_operation_object(k.get('user_id'))
|
||||||
|
)
|
||||||
|
@has_permissions(
|
||||||
|
lambda r, kwargs: Permission(group=Group(kwargs.get('resource')),
|
||||||
|
operate=Operate.AUTH,
|
||||||
|
resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}/ROLE/WORKSPACE_MANAGE"),
|
||||||
|
lambda r, kwargs: Permission(group=Group(kwargs.get('resource')),
|
||||||
|
operate=Operate.AUTH,
|
||||||
|
resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}/{kwargs.get('resource')}/{kwargs.get('target')}"),
|
||||||
|
ViewPermission([RoleConstants.USER.get_workspace_role()],
|
||||||
|
[lambda r, kwargs: Permission(group=Group(kwargs.get('resource')),
|
||||||
|
operate=Operate.SELF,
|
||||||
|
resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}/{kwargs.get('resource')}/{kwargs.get('target')}")],
|
||||||
|
CompareConstants.AND),
|
||||||
|
RoleConstants.WORKSPACE_MANAGE.get_workspace_role())
|
||||||
def put(self, request: Request, workspace_id: str, target: str, resource: str):
|
def put(self, request: Request, workspace_id: str, target: str, resource: str):
|
||||||
return result.success(ResourceUserPermissionSerializer(
|
return result.success(ResourceUserPermissionSerializer(
|
||||||
data={'workspace_id': workspace_id, "target": target, 'auth_target_type': resource, })
|
data={'workspace_id': workspace_id, "target": target, 'auth_target_type': resource, })
|
||||||
|
|
@ -144,6 +178,19 @@ class WorkspaceResourceUserPermissionView(APIView):
|
||||||
responses=ResourceUserPermissionPageAPI.get_response(),
|
responses=ResourceUserPermissionPageAPI.get_response(),
|
||||||
tags=[_('Resources authorization')] # type: ignore
|
tags=[_('Resources authorization')] # type: ignore
|
||||||
)
|
)
|
||||||
|
@has_permissions(
|
||||||
|
lambda r, kwargs: Permission(group=Group(kwargs.get('resource')),
|
||||||
|
operate=Operate.AUTH,
|
||||||
|
resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}/ROLE/WORKSPACE_MANAGE"),
|
||||||
|
lambda r, kwargs: Permission(group=Group(kwargs.get('resource')),
|
||||||
|
operate=Operate.AUTH,
|
||||||
|
resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}/{kwargs.get('resource')}/{kwargs.get('target')}"),
|
||||||
|
ViewPermission([RoleConstants.USER.get_workspace_role()],
|
||||||
|
[lambda r, kwargs: Permission(group=Group(kwargs.get('resource')),
|
||||||
|
operate=Operate.SELF,
|
||||||
|
resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}/{kwargs.get('resource')}/{kwargs.get('target')}")],
|
||||||
|
CompareConstants.AND),
|
||||||
|
RoleConstants.WORKSPACE_MANAGE.get_workspace_role())
|
||||||
def get(self, request: Request, workspace_id: str, target: str, resource: str, current_page: int,
|
def get(self, request: Request, workspace_id: str, target: str, resource: str, current_page: int,
|
||||||
page_size: int):
|
page_size: int):
|
||||||
return result.success(ResourceUserPermissionSerializer(
|
return result.success(ResourceUserPermissionSerializer(
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
FROM python:3.11-slim-bullseye AS python-stage
|
FROM python:3.11-slim-bookworm AS python-stage
|
||||||
FROM ghcr.io/1panel-dev/maxkb-vector-model:v2.0.2 AS vector-model
|
FROM ghcr.io/1panel-dev/maxkb-vector-model:v2.0.2 AS vector-model
|
||||||
FROM postgres:17.5-bullseye
|
FROM postgres:17.6-bookworm
|
||||||
COPY --from=python-stage /usr/local /usr/local
|
COPY --from=python-stage /usr/local /usr/local
|
||||||
COPY installer/*.sh /usr/bin/
|
COPY installer/*.sh /usr/bin/
|
||||||
COPY installer/init.sql /docker-entrypoint-initdb.d/
|
COPY installer/init.sql /docker-entrypoint-initdb.d/
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ python-docx = "1.2.0"
|
||||||
xlrd = "2.0.2"
|
xlrd = "2.0.2"
|
||||||
xlwt = "1.3.0"
|
xlwt = "1.3.0"
|
||||||
pymupdf = "1.26.3"
|
pymupdf = "1.26.3"
|
||||||
pypdf = "5.7.0"
|
pypdf = "6.0.0"
|
||||||
|
|
||||||
# 音频处理
|
# 音频处理
|
||||||
pydub = "0.25.1"
|
pydub = "0.25.1"
|
||||||
|
|
|
||||||
|
|
@ -1,43 +1,84 @@
|
||||||
import { Permission } from '@/utils/permission/type'
|
|
||||||
import { Result } from '@/request/Result'
|
import { Result } from '@/request/Result'
|
||||||
import { get, put, post, del } from '@/request/index'
|
import { get, put, post, del } from '@/request/index'
|
||||||
import type { pageRequest } from '@/api/type/common'
|
|
||||||
import type { Ref } from 'vue'
|
import type { Ref } from 'vue'
|
||||||
|
import type { pageRequest } from '@/api/type/common'
|
||||||
const prefix = '/workspace'
|
const prefix = '/workspace'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取资源权限
|
* 工作空间下各资源获取资源权限
|
||||||
|
* @query 参数
|
||||||
|
*/
|
||||||
|
const getWorkspaceResourceAuthorization: (
|
||||||
|
workspace_id: string,
|
||||||
|
target: string,
|
||||||
|
resource: string,
|
||||||
|
page: pageRequest,
|
||||||
|
params?: any,
|
||||||
|
loading?: Ref<boolean>,
|
||||||
|
) => Promise<Result<any>> = (workspace_id, target, resource, page, params, loading) => {
|
||||||
|
return get(
|
||||||
|
`${prefix}/${workspace_id}/resource_user_permission/resource/${target}/resource/${resource}/${page.current_page}/${page.page_size}`,
|
||||||
|
params,
|
||||||
|
loading,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 工作空间下各资源修改成员权限
|
||||||
|
* @param 参数 member_id
|
||||||
|
* @param 参数 {
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"user_id": "string",
|
||||||
|
"permission": "NOT_AUTH"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
const putWorkspaceResourceAuthorization: (
|
||||||
|
workspace_id: string,
|
||||||
|
target: string,
|
||||||
|
resource: string,
|
||||||
|
body: any,
|
||||||
|
loading?: Ref<boolean>,
|
||||||
|
) => Promise<Result<any>> = (workspace_id, target, resource, body, loading) => {
|
||||||
|
return put(
|
||||||
|
`${prefix}/${workspace_id}/resource_user_permission/resource/${target}/resource/${resource}`,
|
||||||
|
body,
|
||||||
|
{},
|
||||||
|
loading,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 系统资源授权获取资源权限
|
||||||
* @query 参数
|
* @query 参数
|
||||||
*/
|
*/
|
||||||
const getResourceAuthorization: (
|
const getResourceAuthorization: (
|
||||||
workspace_id: string,
|
workspace_id: string,
|
||||||
user_id: string,
|
user_id: string,
|
||||||
resource: string,
|
resource: string,
|
||||||
|
page: pageRequest,
|
||||||
|
params?: any,
|
||||||
loading?: Ref<boolean>,
|
loading?: Ref<boolean>,
|
||||||
) => Promise<Result<any>> = (workspace_id, user_id, resource, loading) => {
|
) => Promise<Result<any>> = (workspace_id, user_id, resource, page, params, loading) => {
|
||||||
return get(
|
return get(
|
||||||
`${prefix}/${workspace_id}/user_resource_permission/user/${user_id}/resource/${resource}`,
|
`${prefix}/${workspace_id}/user_resource_permission/user/${user_id}/resource/${resource}/${page.current_page}/${page.page_size}`,
|
||||||
undefined,
|
params,
|
||||||
loading,
|
loading,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改成员权限
|
* 系统资源授权修改成员权限
|
||||||
* @param 参数 member_id
|
* @param 参数 member_id
|
||||||
* @param 参数 {
|
* @param 参数 {
|
||||||
"team_resource_permission_list": [
|
[
|
||||||
{
|
{
|
||||||
"auth_target_type": "KNOWLEDGE",
|
"target_id": "string",
|
||||||
"target_id": "string",
|
"permission": "NOT_AUTH"
|
||||||
"auth_type": "ROLE",
|
}
|
||||||
"permission": {
|
]
|
||||||
"VIEW": true,
|
|
||||||
"MANAGE": true,
|
|
||||||
"ROLE": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
const putResourceAuthorization: (
|
const putResourceAuthorization: (
|
||||||
|
|
@ -107,4 +148,6 @@ export default {
|
||||||
getUserList,
|
getUserList,
|
||||||
getUserMember,
|
getUserMember,
|
||||||
getSystemFolder,
|
getSystemFolder,
|
||||||
|
getWorkspaceResourceAuthorization,
|
||||||
|
putWorkspaceResourceAuthorization
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,43 +1,92 @@
|
||||||
<template>
|
<template>
|
||||||
<div ref="aiChatRef" class="ai-chat" :class="type" :style="{
|
<div
|
||||||
height: firsUserInput ? '100%' : undefined,
|
ref="aiChatRef"
|
||||||
paddingBottom: applicationDetails.disclaimer ? '20px' : 0,
|
class="ai-chat"
|
||||||
}">
|
:class="type"
|
||||||
<div v-show="showUserInputContent" :class="firsUserInput ? 'firstUserInput' : 'popperUserInput'">
|
:style="{
|
||||||
<UserForm v-model:api_form_data="api_form_data" v-model:form_data="form_data" :application="applicationDetails"
|
height: firsUserInput ? '100%' : undefined,
|
||||||
:type="type" :first="firsUserInput" @confirm="UserFormConfirm" @cancel="UserFormCancel" ref="userFormRef">
|
paddingBottom: applicationDetails.disclaimer ? '20px' : 0,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
v-show="showUserInputContent"
|
||||||
|
:class="firsUserInput ? 'firstUserInput' : 'popperUserInput'"
|
||||||
|
>
|
||||||
|
<UserForm
|
||||||
|
v-model:api_form_data="api_form_data"
|
||||||
|
v-model:form_data="form_data"
|
||||||
|
:application="applicationDetails"
|
||||||
|
:type="type"
|
||||||
|
:first="firsUserInput"
|
||||||
|
@confirm="UserFormConfirm"
|
||||||
|
@cancel="UserFormCancel"
|
||||||
|
ref="userFormRef"
|
||||||
|
>
|
||||||
</UserForm>
|
</UserForm>
|
||||||
</div>
|
</div>
|
||||||
<template v-if="!(isUserInput || isAPIInput) || !firsUserInput || type === 'log'">
|
<template v-if="!(isUserInput || isAPIInput) || !firsUserInput || type === 'log'">
|
||||||
<el-scrollbar ref="scrollDiv" @scroll="handleScrollTop">
|
<el-scrollbar ref="scrollDiv" @scroll="handleScrollTop">
|
||||||
<div ref="dialogScrollbar" class="ai-chat__content p-16">
|
<div ref="dialogScrollbar" class="ai-chat__content p-16">
|
||||||
<PrologueContent :type="type" :application="applicationDetails" :available="available"
|
<PrologueContent
|
||||||
:send-message="sendMessage"></PrologueContent>
|
:type="type"
|
||||||
|
:application="applicationDetails"
|
||||||
|
:available="available"
|
||||||
|
:send-message="sendMessage"
|
||||||
|
></PrologueContent>
|
||||||
|
|
||||||
<template v-for="(item, index) in chatList" :key="index">
|
<template v-for="(item, index) in chatList" :key="index">
|
||||||
<!-- 问题 -->
|
<!-- 问题 -->
|
||||||
<QuestionContent :type="type" :application="applicationDetails" :chat-record="item"></QuestionContent>
|
<QuestionContent
|
||||||
|
:type="type"
|
||||||
|
:application="applicationDetails"
|
||||||
|
:chat-record="item"
|
||||||
|
></QuestionContent>
|
||||||
<!-- 回答 -->
|
<!-- 回答 -->
|
||||||
<AnswerContent :application="applicationDetails" :loading="loading" v-model:chat-record="chatList[index]"
|
<AnswerContent
|
||||||
:type="type" :send-message="sendMessage" :chat-management="ChatManagement"
|
:application="applicationDetails"
|
||||||
|
:loading="loading"
|
||||||
|
v-model:chat-record="chatList[index]"
|
||||||
|
:type="type"
|
||||||
|
:send-message="sendMessage"
|
||||||
|
:chat-management="ChatManagement"
|
||||||
:executionIsRightPanel="props.executionIsRightPanel"
|
:executionIsRightPanel="props.executionIsRightPanel"
|
||||||
@open-execution-detail="emit('openExecutionDetail', chatList[index])"
|
@open-execution-detail="emit('openExecutionDetail', chatList[index])"
|
||||||
@openParagraph="emit('openParagraph', chatList[index])" @openParagraphDocument="
|
@openParagraph="emit('openParagraph', chatList[index])"
|
||||||
|
@openParagraphDocument="
|
||||||
(val: any) => emit('openParagraphDocument', chatList[index], val)
|
(val: any) => emit('openParagraphDocument', chatList[index], val)
|
||||||
"></AnswerContent>
|
"
|
||||||
|
></AnswerContent>
|
||||||
</template>
|
</template>
|
||||||
<TransitionContent v-if="transcribing" :text="t('chat.transcribing')" :type="type"
|
<TransitionContent
|
||||||
:application="applicationDetails">
|
v-if="transcribing"
|
||||||
|
:text="t('chat.transcribing')"
|
||||||
|
:type="type"
|
||||||
|
:application="applicationDetails"
|
||||||
|
>
|
||||||
</TransitionContent>
|
</TransitionContent>
|
||||||
</div>
|
</div>
|
||||||
</el-scrollbar>
|
</el-scrollbar>
|
||||||
|
|
||||||
<ChatInputOperate :app-id="appId" :application-details="applicationDetails" :is-mobile="isMobile" :type="type"
|
<ChatInputOperate
|
||||||
:send-message="sendMessage" :open-chat-id="openChatId" :validate="validate" :chat-management="ChatManagement"
|
:app-id="appId"
|
||||||
v-model:chat-id="chartOpenId" v-model:loading="loading" v-model:show-user-input="showUserInput"
|
:application-details="applicationDetails"
|
||||||
v-if="type !== 'log'">
|
:is-mobile="isMobile"
|
||||||
|
:type="type"
|
||||||
|
:send-message="sendMessage"
|
||||||
|
:open-chat-id="openChatId"
|
||||||
|
:validate="validate"
|
||||||
|
:chat-management="ChatManagement"
|
||||||
|
v-model:chat-id="chartOpenId"
|
||||||
|
v-model:loading="loading"
|
||||||
|
v-model:show-user-input="showUserInput"
|
||||||
|
v-if="type !== 'log'"
|
||||||
|
>
|
||||||
<template #userInput>
|
<template #userInput>
|
||||||
<el-button v-if="isUserInput || isAPIInput" class="user-input-button mb-8" @click="toggleUserInput">
|
<el-button
|
||||||
|
v-if="isUserInput || isAPIInput"
|
||||||
|
class="user-input-button mb-8"
|
||||||
|
@click="toggleUserInput"
|
||||||
|
>
|
||||||
<AppIcon iconName="app-edit" :size="16" class="mr-4"></AppIcon>
|
<AppIcon iconName="app-edit" :size="16" class="mr-4"></AppIcon>
|
||||||
<span class="ellipsis">
|
<span class="ellipsis">
|
||||||
{{ userInputTitle || $t('chat.userInput') }}
|
{{ userInputTitle || $t('chat.userInput') }}
|
||||||
|
|
@ -51,11 +100,21 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { type Ref, ref, nextTick, computed, watch, reactive, onMounted, onBeforeUnmount } from 'vue'
|
import {
|
||||||
|
type Ref,
|
||||||
|
ref,
|
||||||
|
nextTick,
|
||||||
|
computed,
|
||||||
|
watch,
|
||||||
|
reactive,
|
||||||
|
onMounted,
|
||||||
|
onBeforeUnmount,
|
||||||
|
provide,
|
||||||
|
} from 'vue'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
import applicationApi from '@/api/application/application'
|
import applicationApi from '@/api/application/application'
|
||||||
import chatAPI from '@/api/chat/chat'
|
import chatAPI from '@/api/chat/chat'
|
||||||
import SystemResourceManagementApplicationAPI from "@/api/system-resource-management/application.ts"
|
import SystemResourceManagementApplicationAPI from '@/api/system-resource-management/application.ts'
|
||||||
import syetrmResourceManagementChatLogApi from '@/api/system-resource-management/chat-log'
|
import syetrmResourceManagementChatLogApi from '@/api/system-resource-management/chat-log'
|
||||||
import chatLogApi from '@/api/application/chat-log'
|
import chatLogApi from '@/api/application/chat-log'
|
||||||
import { ChatManagement, type chatType } from '@/api/type/application'
|
import { ChatManagement, type chatType } from '@/api/type/application'
|
||||||
|
|
@ -71,6 +130,11 @@ import UserForm from '@/components/ai-chat/component/user-form/index.vue'
|
||||||
import Control from '@/components/ai-chat/component/control/index.vue'
|
import Control from '@/components/ai-chat/component/control/index.vue'
|
||||||
import { t } from '@/locales'
|
import { t } from '@/locales'
|
||||||
import bus from '@/bus'
|
import bus from '@/bus'
|
||||||
|
provide('upload', (file: any, loading?: Ref<boolean>) => {
|
||||||
|
return props.type === 'debug-ai-chat'
|
||||||
|
? applicationApi.postUploadFile(file, 'TEMPORARY_120_MINUTE', 'TEMPORARY_120_MINUTE', loading)
|
||||||
|
: chatAPI.postUploadFile(file, chartOpenId.value, 'CHAT', loading)
|
||||||
|
})
|
||||||
const transcribing = ref<boolean>(false)
|
const transcribing = ref<boolean>(false)
|
||||||
defineOptions({ name: 'AiChat' })
|
defineOptions({ name: 'AiChat' })
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
|
@ -300,17 +364,25 @@ const getChatRecordDetailsAPI = (row: any) => {
|
||||||
if (row.record_id) {
|
if (row.record_id) {
|
||||||
if (props.type === 'debug-ai-chat') {
|
if (props.type === 'debug-ai-chat') {
|
||||||
if (route.path.includes('resource-management')) {
|
if (route.path.includes('resource-management')) {
|
||||||
return syetrmResourceManagementChatLogApi
|
return syetrmResourceManagementChatLogApi.getChatRecordDetails(
|
||||||
.getChatRecordDetails(id || props.appId, row.chat_id, row.record_id, loading)
|
id || props.appId,
|
||||||
|
row.chat_id,
|
||||||
|
row.record_id,
|
||||||
|
loading,
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
return chatLogApi
|
return chatLogApi.getChatRecordDetails(
|
||||||
.getChatRecordDetails(id || props.appId, row.chat_id, row.record_id, loading)
|
id || props.appId,
|
||||||
|
row.chat_id,
|
||||||
|
row.record_id,
|
||||||
|
loading,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return chatAPI.getChatRecord(row.chat_id, row.record_id, loading)
|
return chatAPI.getChatRecord(row.chat_id, row.record_id, loading)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Promise.reject("404")
|
return Promise.reject('404')
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 获取对话详情
|
* 获取对话详情
|
||||||
|
|
@ -325,7 +397,6 @@ function getSourceDetail(row: any) {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 对话
|
* 对话
|
||||||
|
|
|
||||||
|
|
@ -2,43 +2,51 @@ import { t } from '@/locales'
|
||||||
const input_type_list = [
|
const input_type_list = [
|
||||||
{
|
{
|
||||||
label: t('dynamicsForm.input_type_list.TextInput'),
|
label: t('dynamicsForm.input_type_list.TextInput'),
|
||||||
value: 'TextInput'
|
value: 'TextInput',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('dynamicsForm.input_type_list.PasswordInput'),
|
label: t('dynamicsForm.input_type_list.PasswordInput'),
|
||||||
value: 'PasswordInput'
|
value: 'PasswordInput',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('dynamicsForm.input_type_list.Slider'),
|
label: t('dynamicsForm.input_type_list.Slider'),
|
||||||
value: 'Slider'
|
value: 'Slider',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('dynamicsForm.input_type_list.SwitchInput'),
|
label: t('dynamicsForm.input_type_list.SwitchInput'),
|
||||||
value: 'SwitchInput'
|
value: 'SwitchInput',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('dynamicsForm.input_type_list.SingleSelect'),
|
label: t('dynamicsForm.input_type_list.SingleSelect'),
|
||||||
value: 'SingleSelect'
|
value: 'SingleSelect',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('dynamicsForm.input_type_list.MultiSelect'),
|
label: t('dynamicsForm.input_type_list.MultiSelect'),
|
||||||
value: 'MultiSelect'
|
value: 'MultiSelect',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('dynamicsForm.input_type_list.DatePicker'),
|
label: t('dynamicsForm.input_type_list.DatePicker'),
|
||||||
value: 'DatePicker'
|
value: 'DatePicker',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('dynamicsForm.input_type_list.JsonInput'),
|
label: t('dynamicsForm.input_type_list.JsonInput'),
|
||||||
value: 'JsonInput'
|
value: 'JsonInput',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('dynamicsForm.input_type_list.RadioCard'),
|
label: t('dynamicsForm.input_type_list.RadioCard'),
|
||||||
value: 'RadioCard'
|
value: 'RadioCard',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('dynamicsForm.input_type_list.RadioRow'),
|
label: t('dynamicsForm.input_type_list.RadioRow'),
|
||||||
value: 'RadioRow'
|
value: 'RadioRow',
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
label: t('dynamicsForm.input_type_list.UploadInput'),
|
||||||
|
value: 'UploadInput',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('dynamicsForm.input_type_list.TextareaInput'),
|
||||||
|
value: 'TextareaInput',
|
||||||
|
},
|
||||||
]
|
]
|
||||||
export { input_type_list }
|
export { input_type_list }
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,51 @@
|
||||||
<template>
|
<template>
|
||||||
<el-form-item>
|
<el-form-item v-if="getModel">
|
||||||
|
<template #label>
|
||||||
|
<div class="flex-between">
|
||||||
|
{{ $t('dynamicsForm.AssignmentMethod.label', '赋值方式') }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<el-row style="width: 100%" :gutter="10">
|
||||||
|
<el-radio-group v-model="formValue.assignment_method">
|
||||||
|
<el-radio :value="item.value" size="large" v-for="item in assignment_method_option_list"
|
||||||
|
>{{ item.label }}
|
||||||
|
<el-popover
|
||||||
|
width="300px"
|
||||||
|
v-if="item.value == 'ref_variables'"
|
||||||
|
class="box-item"
|
||||||
|
placement="top-start"
|
||||||
|
>
|
||||||
|
{{ $t('dynamicsForm.AssignmentMethod.ref_variables.popover') }}:<br />
|
||||||
|
[<br />
|
||||||
|
{<br />
|
||||||
|
"label": "xx",<br />
|
||||||
|
"value": "xx",<br />
|
||||||
|
"default": false<br />
|
||||||
|
}<br />
|
||||||
|
]<br />
|
||||||
|
label: {{ $t('dynamicsForm.AssignmentMethod.ref_variables.popover_label') }}
|
||||||
|
{{ $t('common.required') }}<br />
|
||||||
|
value: {{ $t('dynamicsForm.AssignmentMethod.ref_variables.popover_value') }}
|
||||||
|
{{ $t('common.required') }}<br />
|
||||||
|
default: {{ $t('dynamicsForm.AssignmentMethod.ref_variables.popover_default') }}
|
||||||
|
<template #reference>
|
||||||
|
<el-icon><InfoFilled /></el-icon>
|
||||||
|
</template>
|
||||||
|
</el-popover>
|
||||||
|
</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-row>
|
||||||
|
</el-form-item>
|
||||||
|
<NodeCascader
|
||||||
|
v-if="formValue.assignment_method == 'ref_variables'"
|
||||||
|
ref="nodeCascaderRef"
|
||||||
|
:nodeModel="model"
|
||||||
|
class="w-full"
|
||||||
|
:placeholder="$t('views.applicationWorkflow.variable.placeholder')"
|
||||||
|
v-model="formValue.option_list"
|
||||||
|
/>
|
||||||
|
<el-form-item v-if="formValue.assignment_method == 'custom'">
|
||||||
<template #label>
|
<template #label>
|
||||||
<div class="flex-between">
|
<div class="flex-between">
|
||||||
{{ $t('dynamicsForm.Select.label') }}
|
{{ $t('dynamicsForm.Select.label') }}
|
||||||
|
|
@ -51,6 +97,7 @@
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item
|
<el-form-item
|
||||||
|
v-if="formValue.assignment_method == 'custom'"
|
||||||
class="defaultValueItem"
|
class="defaultValueItem"
|
||||||
:label="$t('dynamicsForm.default.label')"
|
:label="$t('dynamicsForm.default.label')"
|
||||||
:required="formValue.required"
|
:required="formValue.required"
|
||||||
|
|
@ -92,8 +139,34 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, onMounted } from 'vue'
|
import { computed, onMounted, inject } from 'vue'
|
||||||
|
import NodeCascader from '@/workflow/common/NodeCascader.vue'
|
||||||
|
import { t } from '@/locales'
|
||||||
|
const getModel = inject('getModel') as any
|
||||||
|
|
||||||
|
const assignment_method_option_list = computed(() => {
|
||||||
|
const option_list = [
|
||||||
|
{
|
||||||
|
label: t('dynamicsForm.AssignmentMethod.custom.label', '自定义'),
|
||||||
|
value: 'custom',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
if (getModel) {
|
||||||
|
option_list.push({
|
||||||
|
label: t('dynamicsForm.AssignmentMethod.ref_variables.label', '引用变量'),
|
||||||
|
value: 'ref_variables',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return option_list
|
||||||
|
})
|
||||||
|
|
||||||
|
const model = computed(() => {
|
||||||
|
if (getModel) {
|
||||||
|
return getModel()
|
||||||
|
} else {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
})
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
modelValue: any
|
modelValue: any
|
||||||
}>()
|
}>()
|
||||||
|
|
@ -128,17 +201,20 @@ const getData = () => {
|
||||||
text_field: 'label',
|
text_field: 'label',
|
||||||
value_field: 'value',
|
value_field: 'value',
|
||||||
option_list: formValue.value.option_list,
|
option_list: formValue.value.option_list,
|
||||||
|
assignment_method: formValue.value.assignment_method || 'custom',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const rander = (form_data: any) => {
|
const rander = (form_data: any) => {
|
||||||
formValue.value.option_list = form_data.option_list || []
|
formValue.value.option_list = form_data.option_list || []
|
||||||
formValue.value.default_value = form_data.default_value
|
formValue.value.default_value = form_data.default_value
|
||||||
|
formValue.value.assignment_method = form_data.assignment_method || 'custom'
|
||||||
}
|
}
|
||||||
|
|
||||||
defineExpose({ getData, rander })
|
defineExpose({ getData, rander })
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
formValue.value.option_list = []
|
formValue.value.option_list = []
|
||||||
formValue.value.default_value = ''
|
formValue.value.default_value = ''
|
||||||
|
formValue.value.assignment_method = 'custom'
|
||||||
if (formValue.value.show_default_value === undefined) {
|
if (formValue.value.show_default_value === undefined) {
|
||||||
formValue.value.show_default_value = true
|
formValue.value.show_default_value = true
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,51 @@
|
||||||
<template>
|
<template>
|
||||||
<el-form-item>
|
<el-form-item v-if="getModel">
|
||||||
|
<template #label>
|
||||||
|
<div class="flex-between">
|
||||||
|
{{ $t('dynamicsForm.AssignmentMethod.label', '赋值方式') }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<el-row style="width: 100%" :gutter="10">
|
||||||
|
<el-radio-group v-model="formValue.assignment_method">
|
||||||
|
<el-radio :value="item.value" size="large" v-for="item in assignment_method_option_list"
|
||||||
|
>{{ item.label }}
|
||||||
|
<el-popover
|
||||||
|
width="300px"
|
||||||
|
v-if="item.value == 'ref_variables'"
|
||||||
|
class="box-item"
|
||||||
|
placement="top-start"
|
||||||
|
>
|
||||||
|
{{ $t('dynamicsForm.AssignmentMethod.ref_variables.popover') }}:<br />
|
||||||
|
[<br />
|
||||||
|
{<br />
|
||||||
|
"label": "xx",<br />
|
||||||
|
"value": "xx",<br />
|
||||||
|
"default": false<br />
|
||||||
|
}<br />
|
||||||
|
]<br />
|
||||||
|
label: {{ $t('dynamicsForm.AssignmentMethod.ref_variables.popover_label') }}
|
||||||
|
{{ $t('common.required') }}<br />
|
||||||
|
value: {{ $t('dynamicsForm.AssignmentMethod.ref_variables.popover_value') }}
|
||||||
|
{{ $t('common.required') }}<br />
|
||||||
|
default:{{ $t('dynamicsForm.AssignmentMethod.ref_variables.popover_default') }}
|
||||||
|
<template #reference>
|
||||||
|
<el-icon><InfoFilled /></el-icon>
|
||||||
|
</template>
|
||||||
|
</el-popover>
|
||||||
|
</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-row>
|
||||||
|
</el-form-item>
|
||||||
|
<NodeCascader
|
||||||
|
v-if="formValue.assignment_method == 'ref_variables'"
|
||||||
|
ref="nodeCascaderRef"
|
||||||
|
:nodeModel="model"
|
||||||
|
class="w-full"
|
||||||
|
:placeholder="$t('views.applicationWorkflow.variable.placeholder')"
|
||||||
|
v-model="formValue.option_list"
|
||||||
|
/>
|
||||||
|
<el-form-item v-if="formValue.assignment_method === 'custom'">
|
||||||
<template #label>
|
<template #label>
|
||||||
<div class="flex-between">
|
<div class="flex-between">
|
||||||
{{ $t('dynamicsForm.Select.label') }}
|
{{ $t('dynamicsForm.Select.label') }}
|
||||||
|
|
@ -51,7 +97,9 @@
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item
|
<el-form-item
|
||||||
|
v-if="formValue.assignment_method === 'custom'"
|
||||||
class="defaultValueItem"
|
class="defaultValueItem"
|
||||||
:label="$t('dynamicsForm.default.label')"
|
:label="$t('dynamicsForm.default.label')"
|
||||||
:required="formValue.required"
|
:required="formValue.required"
|
||||||
|
|
@ -83,8 +131,35 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, onMounted } from 'vue'
|
import { computed, onMounted, inject, ref } from 'vue'
|
||||||
import RadioCard from '@/components/dynamics-form/items/radio/RadioCard.vue'
|
import RadioCard from '@/components/dynamics-form/items/radio/RadioCard.vue'
|
||||||
|
import NodeCascader from '@/workflow/common/NodeCascader.vue'
|
||||||
|
import { t } from '@/locales'
|
||||||
|
const getModel = inject('getModel') as any
|
||||||
|
|
||||||
|
const assignment_method_option_list = computed(() => {
|
||||||
|
const option_list = [
|
||||||
|
{
|
||||||
|
label: t('dynamicsForm.AssignmentMethod.custom.label', '自定义'),
|
||||||
|
value: 'custom',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
if (getModel) {
|
||||||
|
option_list.push({
|
||||||
|
label: t('dynamicsForm.AssignmentMethod.ref_variables.label', '引用变量'),
|
||||||
|
value: 'ref_variables',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return option_list
|
||||||
|
})
|
||||||
|
|
||||||
|
const model = computed(() => {
|
||||||
|
if (getModel) {
|
||||||
|
return getModel()
|
||||||
|
} else {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
})
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
modelValue: any
|
modelValue: any
|
||||||
}>()
|
}>()
|
||||||
|
|
@ -121,17 +196,20 @@ const getData = () => {
|
||||||
text_field: 'label',
|
text_field: 'label',
|
||||||
value_field: 'value',
|
value_field: 'value',
|
||||||
option_list: formValue.value.option_list,
|
option_list: formValue.value.option_list,
|
||||||
|
assignment_method: formValue.value.assignment_method || 'custom',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const rander = (form_data: any) => {
|
const rander = (form_data: any) => {
|
||||||
formValue.value.option_list = form_data.option_list || []
|
formValue.value.option_list = form_data.option_list || []
|
||||||
formValue.value.default_value = form_data.default_value
|
formValue.value.default_value = form_data.default_value
|
||||||
|
formValue.value.assignment_method = form_data.assignment_method || 'custom'
|
||||||
}
|
}
|
||||||
|
|
||||||
defineExpose({ getData, rander })
|
defineExpose({ getData, rander })
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
formValue.value.option_list = []
|
formValue.value.option_list = []
|
||||||
formValue.value.default_value = ''
|
formValue.value.default_value = ''
|
||||||
|
formValue.value.assignment_method = 'custom'
|
||||||
if (formValue.value.show_default_value === undefined) {
|
if (formValue.value.show_default_value === undefined) {
|
||||||
formValue.value.show_default_value = true
|
formValue.value.show_default_value = true
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,50 @@
|
||||||
<template>
|
<template>
|
||||||
<el-form-item>
|
<el-form-item v-if="getModel">
|
||||||
|
<template #label>
|
||||||
|
<div class="flex-between">
|
||||||
|
{{ $t('dynamicsForm.AssignmentMethod.label', '赋值方式') }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<el-row style="width: 100%" :gutter="10">
|
||||||
|
<el-radio-group v-model="formValue.assignment_method">
|
||||||
|
<el-radio :value="item.value" size="large" v-for="item in assignment_method_option_list"
|
||||||
|
>{{ item.label }}
|
||||||
|
<el-popover
|
||||||
|
width="300px"
|
||||||
|
v-if="item.value == 'ref_variables'"
|
||||||
|
class="box-item"
|
||||||
|
placement="top-start"
|
||||||
|
>
|
||||||
|
{{ $t('dynamicsForm.AssignmentMethod.ref_variables.popover') }}:<br />
|
||||||
|
[<br />
|
||||||
|
{<br />
|
||||||
|
"label": "xx",<br />
|
||||||
|
"value": "xx",<br />
|
||||||
|
"default": false<br />
|
||||||
|
}<br />
|
||||||
|
]<br />
|
||||||
|
label: {{ $t('dynamicsForm.AssignmentMethod.ref_variables.popover_label') }}
|
||||||
|
{{ $t('common.required') }}<br />
|
||||||
|
value: {{ $t('dynamicsForm.AssignmentMethod.ref_variables.popover_value') }}
|
||||||
|
{{ $t('common.required') }}<br />
|
||||||
|
default: {{ $t('dynamicsForm.AssignmentMethod.ref_variables.popover_default') }}
|
||||||
|
<template #reference>
|
||||||
|
<el-icon><InfoFilled /></el-icon>
|
||||||
|
</template> </el-popover
|
||||||
|
></el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-row>
|
||||||
|
</el-form-item>
|
||||||
|
<NodeCascader
|
||||||
|
v-if="formValue.assignment_method == 'ref_variables'"
|
||||||
|
ref="nodeCascaderRef"
|
||||||
|
:nodeModel="model"
|
||||||
|
class="w-full"
|
||||||
|
:placeholder="$t('views.applicationWorkflow.variable.placeholder')"
|
||||||
|
v-model="formValue.option_list"
|
||||||
|
/>
|
||||||
|
<el-form-item v-if="formValue.assignment_method == 'custom'">
|
||||||
<template #label>
|
<template #label>
|
||||||
<div class="flex-between">
|
<div class="flex-between">
|
||||||
{{ $t('dynamicsForm.Select.label') }}
|
{{ $t('dynamicsForm.Select.label') }}
|
||||||
|
|
@ -52,6 +97,7 @@
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item
|
<el-form-item
|
||||||
|
v-if="formValue.assignment_method == 'custom'"
|
||||||
class="defaultValueItem"
|
class="defaultValueItem"
|
||||||
:required="formValue.required"
|
:required="formValue.required"
|
||||||
prop="default_value"
|
prop="default_value"
|
||||||
|
|
@ -85,8 +131,34 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, onMounted } from 'vue'
|
import { computed, onMounted, inject } from 'vue'
|
||||||
|
import NodeCascader from '@/workflow/common/NodeCascader.vue'
|
||||||
|
import { t } from '@/locales'
|
||||||
|
const getModel = inject('getModel') as any
|
||||||
|
|
||||||
|
const assignment_method_option_list = computed(() => {
|
||||||
|
const option_list = [
|
||||||
|
{
|
||||||
|
label: t('dynamicsForm.AssignmentMethod.custom.label', '自定义'),
|
||||||
|
value: 'custom',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
if (getModel) {
|
||||||
|
option_list.push({
|
||||||
|
label: t('dynamicsForm.AssignmentMethod.ref_variables.label', '引用变量'),
|
||||||
|
value: 'ref_variables',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return option_list
|
||||||
|
})
|
||||||
|
|
||||||
|
const model = computed(() => {
|
||||||
|
if (getModel) {
|
||||||
|
return getModel()
|
||||||
|
} else {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
})
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
modelValue: any
|
modelValue: any
|
||||||
}>()
|
}>()
|
||||||
|
|
@ -121,18 +193,21 @@ const getData = () => {
|
||||||
text_field: 'label',
|
text_field: 'label',
|
||||||
value_field: 'value',
|
value_field: 'value',
|
||||||
option_list: formValue.value.option_list,
|
option_list: formValue.value.option_list,
|
||||||
|
assignment_method: formValue.value.assignment_method || 'custom',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const rander = (form_data: any) => {
|
const rander = (form_data: any) => {
|
||||||
formValue.value.option_list = form_data.option_list || []
|
formValue.value.option_list = form_data.option_list || []
|
||||||
formValue.value.default_value = form_data.default_value
|
formValue.value.default_value = form_data.default_value
|
||||||
formValue.value.show_default_value = form_data.show_default_value
|
formValue.value.show_default_value = form_data.show_default_value
|
||||||
|
formValue.value.assignment_method = form_data.assignment_method || 'custom'
|
||||||
}
|
}
|
||||||
|
|
||||||
defineExpose({ getData, rander })
|
defineExpose({ getData, rander })
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
formValue.value.option_list = []
|
formValue.value.option_list = []
|
||||||
formValue.value.default_value = ''
|
formValue.value.default_value = ''
|
||||||
|
formValue.value.assignment_method = 'custom'
|
||||||
if (formValue.value.show_default_value === undefined) {
|
if (formValue.value.show_default_value === undefined) {
|
||||||
formValue.value.show_default_value = true
|
formValue.value.show_default_value = true
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,195 @@
|
||||||
|
<template>
|
||||||
|
<el-form-item :label="$t('dynamicsForm.TextInput.length.label')" required>
|
||||||
|
<el-row class="w-full">
|
||||||
|
<el-col :span="11">
|
||||||
|
<el-form-item
|
||||||
|
:rules="[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: $t('dynamicsForm.TextInput.length.minRequired'),
|
||||||
|
trigger: 'change',
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
prop="minlength"
|
||||||
|
>
|
||||||
|
<el-input-number
|
||||||
|
style="width: 100%"
|
||||||
|
:min="1"
|
||||||
|
:step="1"
|
||||||
|
step-strictly
|
||||||
|
v-model="formValue.minlength"
|
||||||
|
controls-position="right"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="2" class="text-center">
|
||||||
|
<span>-</span>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="11">
|
||||||
|
<el-form-item
|
||||||
|
:rules="[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: $t('dynamicsForm.TextInput.length.maxRequired'),
|
||||||
|
trigger: 'change',
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
prop="maxlength"
|
||||||
|
>
|
||||||
|
<el-input-number
|
||||||
|
style="width: 100%"
|
||||||
|
:min="formValue.minlength > formValue.maxlength ? formValue.minlength : 1"
|
||||||
|
step-strictly
|
||||||
|
:step="1"
|
||||||
|
v-model="formValue.maxlength"
|
||||||
|
controls-position="right"
|
||||||
|
/></el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item
|
||||||
|
class="defaultValueItem"
|
||||||
|
:required="formValue.required"
|
||||||
|
prop="default_value"
|
||||||
|
:label="$t('dynamicsForm.default.label')"
|
||||||
|
:rules="
|
||||||
|
formValue.required
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: `${$t('dynamicsForm.default.label')}${$t('dynamicsForm.default.requiredMessage')}`,
|
||||||
|
},
|
||||||
|
...rules,
|
||||||
|
]
|
||||||
|
: rules
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<div class="defaultValueCheckbox">
|
||||||
|
<el-checkbox
|
||||||
|
v-model="formValue.show_default_value"
|
||||||
|
:label="$t('dynamicsForm.default.show')"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-input
|
||||||
|
v-model="formValue.default_value"
|
||||||
|
:maxlength="formValue.maxlength"
|
||||||
|
:minlength="formValue.minlength"
|
||||||
|
:placeholder="$t('dynamicsForm.default.placeholder')"
|
||||||
|
show-word-limit
|
||||||
|
:autosize="{ minRows: 3, maxRows: 3 }"
|
||||||
|
type="textarea"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { computed, onMounted, watch } from 'vue'
|
||||||
|
import { t } from '@/locales'
|
||||||
|
const props = defineProps<{
|
||||||
|
modelValue: any
|
||||||
|
}>()
|
||||||
|
const emit = defineEmits(['update:modelValue'])
|
||||||
|
const formValue = computed({
|
||||||
|
set: (item) => {
|
||||||
|
emit('update:modelValue', item)
|
||||||
|
},
|
||||||
|
get: () => {
|
||||||
|
return props.modelValue
|
||||||
|
},
|
||||||
|
})
|
||||||
|
watch(
|
||||||
|
() => formValue.value.minlength,
|
||||||
|
() => {
|
||||||
|
if (formValue.value.minlength > formValue.value.maxlength) {
|
||||||
|
formValue.value.maxlength = formValue.value.minlength
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
const getData = () => {
|
||||||
|
return {
|
||||||
|
input_type: 'TextareaInput',
|
||||||
|
attrs: {
|
||||||
|
maxlength: formValue.value.maxlength,
|
||||||
|
minlength: formValue.value.minlength,
|
||||||
|
'show-word-limit': true,
|
||||||
|
autosize: { minRows: 3, maxRows: 3 },
|
||||||
|
},
|
||||||
|
default_value: formValue.value.default_value,
|
||||||
|
show_default_value: formValue.value.show_default_value,
|
||||||
|
props_info: {
|
||||||
|
rules: formValue.value.required
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: `${formValue.value.label} ${t('dynamicsForm.default.requiredMessage')}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
min: formValue.value.minlength,
|
||||||
|
max: formValue.value.maxlength,
|
||||||
|
message: `${formValue.value.label}${t('dynamicsForm.TextInput.length.requiredMessage1')} ${formValue.value.minlength} ${t('dynamicsForm.TextInput.length.requiredMessage2')} ${formValue.value.maxlength} ${t('dynamicsForm.TextInput.length.requiredMessage3')}`,
|
||||||
|
trigger: 'blur',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: [
|
||||||
|
{
|
||||||
|
min: formValue.value.minlength,
|
||||||
|
max: formValue.value.maxlength,
|
||||||
|
message: `${formValue.value.label}${t('dynamicsForm.TextInput.length.requiredMessage1')} ${formValue.value.minlength} ${t('dynamicsForm.TextInput.length.requiredMessage2')} ${formValue.value.maxlength} ${t('dynamicsForm.TextInput.length.requiredMessage3')}`,
|
||||||
|
trigger: 'blur',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const rander = (form_data: any) => {
|
||||||
|
const attrs = form_data.attrs || {}
|
||||||
|
formValue.value.minlength = attrs.minlength
|
||||||
|
formValue.value.maxlength = attrs.maxlength
|
||||||
|
formValue.value.default_value = form_data.default_value
|
||||||
|
formValue.value.show_default_value = form_data.show_default_value
|
||||||
|
}
|
||||||
|
const rangeRules = [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
validator: (rule: any, value: any, callback: any) => {
|
||||||
|
if (!formValue.value.minlength) {
|
||||||
|
callback(new Error(t('dynamicsForm.TextInput.length.requiredMessage4')))
|
||||||
|
}
|
||||||
|
if (!formValue.value.maxlength) {
|
||||||
|
callback(new Error(t('dynamicsForm.TextInput.length.requiredMessage4')))
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
},
|
||||||
|
message: `${formValue.value.label} ${t('dynamicsForm.default.requiredMessage')}`,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
const rules = computed(() => [
|
||||||
|
{
|
||||||
|
min: formValue.value.minlength,
|
||||||
|
max: formValue.value.maxlength,
|
||||||
|
message: `${t('dynamicsForm.TextInput.length.requiredMessage1')} ${formValue.value.minlength} ${t('dynamicsForm.TextInput.length.requiredMessage2')} ${formValue.value.maxlength} ${t('dynamicsForm.TextInput.length.requiredMessage3')}`,
|
||||||
|
trigger: 'blur',
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
defineExpose({ getData, rander })
|
||||||
|
onMounted(() => {
|
||||||
|
formValue.value.minlength = 0
|
||||||
|
formValue.value.maxlength = 200
|
||||||
|
formValue.value.default_value = ''
|
||||||
|
if (formValue.value.show_default_value === undefined) {
|
||||||
|
formValue.value.show_default_value = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.defaultValueItem {
|
||||||
|
position: relative;
|
||||||
|
.defaultValueCheckbox {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: -35px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,153 @@
|
||||||
|
<template>
|
||||||
|
<el-form-item :label="$t('dynamicsForm.UploadInput.limit.label')" required prop="limit">
|
||||||
|
<el-input-number
|
||||||
|
style="width: 100%"
|
||||||
|
v-model="formValue.limit"
|
||||||
|
:rules="[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: $t('dynamicsForm.UploadInput.limit.required'),
|
||||||
|
trigger: 'change',
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
:min="0"
|
||||||
|
controls-position="right"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item
|
||||||
|
:label="$t('dynamicsForm.UploadInput.max_file_size.label')"
|
||||||
|
required
|
||||||
|
prop="max_file_size"
|
||||||
|
:rules="[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: $t('dynamicsForm.UploadInput.max_file_size.required'),
|
||||||
|
trigger: 'change',
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<el-input-number
|
||||||
|
style="width: 100%"
|
||||||
|
v-model="formValue.max_file_size"
|
||||||
|
:min="0"
|
||||||
|
controls-position="right"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item
|
||||||
|
:label="$t('dynamicsForm.UploadInput.accept.label')"
|
||||||
|
required
|
||||||
|
prop="accept"
|
||||||
|
:rules="[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: $t('dynamicsForm.UploadInput.accept.required'),
|
||||||
|
trigger: 'change',
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<div class="gap-2" style="display: flex">
|
||||||
|
<el-tag
|
||||||
|
v-for="tag in formValue.accept"
|
||||||
|
:key="tag"
|
||||||
|
closable
|
||||||
|
:disable-transitions="false"
|
||||||
|
@close="handleClose(tag)"
|
||||||
|
>
|
||||||
|
{{ tag }}
|
||||||
|
</el-tag>
|
||||||
|
<el-input
|
||||||
|
v-if="inputVisible"
|
||||||
|
ref="InputRef"
|
||||||
|
v-model="inputValue"
|
||||||
|
class="w-20"
|
||||||
|
size="small"
|
||||||
|
@keyup.enter="handleInputConfirm"
|
||||||
|
@blur="handleInputConfirm"
|
||||||
|
/>
|
||||||
|
<el-button v-else class="button-new-tag" size="small" @click="showInput">
|
||||||
|
+ {{ $t('common.fileUpload.addExtensions') }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { computed, onMounted, ref, nextTick } from 'vue'
|
||||||
|
import { ElMessage, type InputInstance } from 'element-plus'
|
||||||
|
import { t } from '@/locales'
|
||||||
|
const props = defineProps<{
|
||||||
|
modelValue: any
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const inputValue = ref('')
|
||||||
|
|
||||||
|
const inputVisible = ref(false)
|
||||||
|
const InputRef = ref<InputInstance>()
|
||||||
|
const handleClose = (tag: string) => {
|
||||||
|
formValue.value.accept.splice(formValue.value.accept.indexOf(tag), 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
const showInput = () => {
|
||||||
|
inputVisible.value = true
|
||||||
|
nextTick(() => {
|
||||||
|
InputRef.value!.input!.focus()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleInputConfirm = () => {
|
||||||
|
if (formValue.value.accept.find((item: string) => item === inputValue.value)) {
|
||||||
|
ElMessage.warning(t('common.fileUpload.existingExtensionsTip'))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (inputValue.value) {
|
||||||
|
formValue.value.accept.push(inputValue.value)
|
||||||
|
}
|
||||||
|
inputVisible.value = false
|
||||||
|
inputValue.value = ''
|
||||||
|
}
|
||||||
|
const emit = defineEmits(['update:modelValue'])
|
||||||
|
const formValue = computed({
|
||||||
|
set: (item) => {
|
||||||
|
emit('update:modelValue', item)
|
||||||
|
},
|
||||||
|
get: () => {
|
||||||
|
return props.modelValue
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const rander = (form_data: any) => {
|
||||||
|
formValue.value.default_value = []
|
||||||
|
formValue.value.limit = form_data.attrs.limit || 3
|
||||||
|
formValue.value.max_file_size = form_data.max_file_size || 10
|
||||||
|
formValue.value.accept = form_data.attrs.accept
|
||||||
|
? form_data.attrs.accept.split(',').map((item: string) => item.substring(1))
|
||||||
|
: ['jpg']
|
||||||
|
}
|
||||||
|
const getData = () => {
|
||||||
|
return {
|
||||||
|
input_type: 'UploadInput',
|
||||||
|
attrs: {
|
||||||
|
accept: formValue.value.accept.map((item: any) => '.' + item).join(','),
|
||||||
|
limit: formValue.value.limit,
|
||||||
|
},
|
||||||
|
max_file_size: formValue.value.max_file_size,
|
||||||
|
default_value: [],
|
||||||
|
show_default_value: formValue.value.show_default_value,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
defineExpose({ getData, rander })
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
formValue.value.default_value = []
|
||||||
|
formValue.value.limit = 3
|
||||||
|
formValue.value.max_file_size = 10
|
||||||
|
formValue.value.accept = ['jpg']
|
||||||
|
if (formValue.value.show_default_value === undefined) {
|
||||||
|
formValue.value.show_default_value = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.gap-2 {
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
<template>
|
||||||
|
<el-input v-bind="$attrs" type="textarea"></el-input>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts"></script>
|
||||||
|
<style lang="scss"></style>
|
||||||
|
|
@ -10,11 +10,11 @@
|
||||||
style="--el-card-padding: 12px 16px"
|
style="--el-card-padding: 12px 16px"
|
||||||
:class="[
|
:class="[
|
||||||
inputDisabled ? 'is-disabled' : '',
|
inputDisabled ? 'is-disabled' : '',
|
||||||
modelValue == item[valueField] ? 'active' : ''
|
modelValue == item[valueField] ? 'active' : '',
|
||||||
]"
|
]"
|
||||||
@click="inputDisabled ? () => {} : selected(item[valueField])"
|
@click="inputDisabled ? () => {} : selected(item[valueField])"
|
||||||
|
:innerHTML="item[textField]"
|
||||||
>
|
>
|
||||||
{{ item[textField] }}
|
|
||||||
</el-card>
|
</el-card>
|
||||||
</el-col>
|
</el-col>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,123 @@
|
||||||
|
<template>
|
||||||
|
<el-upload
|
||||||
|
style="width: 80%"
|
||||||
|
v-loading="loading"
|
||||||
|
action="#"
|
||||||
|
v-bind="$attrs"
|
||||||
|
:auto-upload="false"
|
||||||
|
:on-change="(file: any, fileList: any) => uploadFile(file, fileList)"
|
||||||
|
v-model:file-list="model_value"
|
||||||
|
multiple
|
||||||
|
>
|
||||||
|
<el-button type="primary">{{ $t('chat.uploadFile.label') }}</el-button>
|
||||||
|
<template #file="{ file, index }"
|
||||||
|
><el-card style="--el-card-padding: 0" shadow="never">
|
||||||
|
<div
|
||||||
|
:class="[inputDisabled ? 'is-disabled' : '']"
|
||||||
|
style="
|
||||||
|
padding: 0 8px 0 8px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
align-content: center;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<el-tooltip class="box-item" effect="dark" :content="file.name" placement="top-start">
|
||||||
|
<div style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis; width: 40%">
|
||||||
|
{{ file.name }}
|
||||||
|
</div></el-tooltip
|
||||||
|
>
|
||||||
|
|
||||||
|
<div>{{ formatSize(file.size) }}</div>
|
||||||
|
<el-icon @click="deleteFile(file)" style="cursor: pointer"><DeleteFilled /></el-icon>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
</template>
|
||||||
|
</el-upload>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { computed, inject, ref, useAttrs } from 'vue'
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
import type { FormField } from '@/components/dynamics-form/type'
|
||||||
|
import { t } from '@/locales'
|
||||||
|
import { useFormDisabled } from 'element-plus'
|
||||||
|
const inputDisabled = useFormDisabled()
|
||||||
|
const attrs = useAttrs() as any
|
||||||
|
const upload = inject('upload') as any
|
||||||
|
const props = withDefaults(defineProps<{ modelValue?: any; formField: FormField }>(), {
|
||||||
|
modelValue: () => [],
|
||||||
|
})
|
||||||
|
const emit = defineEmits(['update:modelValue'])
|
||||||
|
function formatSize(sizeInBytes: number) {
|
||||||
|
const units = ['B', 'KB', 'MB', 'GB', 'TB']
|
||||||
|
let size = sizeInBytes
|
||||||
|
let unitIndex = 0
|
||||||
|
|
||||||
|
while (size >= 1024 && unitIndex < units.length - 1) {
|
||||||
|
size /= 1024
|
||||||
|
unitIndex++
|
||||||
|
}
|
||||||
|
|
||||||
|
return size.toFixed(2) + ' ' + units[unitIndex]
|
||||||
|
}
|
||||||
|
|
||||||
|
const deleteFile = (file: any) => {
|
||||||
|
if (inputDisabled) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fileArray.value = fileArray.value.filter((f: any) => f.uid != file.uid)
|
||||||
|
emit('update:modelValue', fileArray.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
const model_value = computed({
|
||||||
|
get: () => {
|
||||||
|
if (!model_value) {
|
||||||
|
emit('update:modelValue', [])
|
||||||
|
}
|
||||||
|
return props.modelValue
|
||||||
|
},
|
||||||
|
set: (v: Array<any>) => {
|
||||||
|
emit('update:modelValue', v)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
const fileArray = ref<any>([])
|
||||||
|
|
||||||
|
const loading = ref<boolean>(false)
|
||||||
|
|
||||||
|
const uploadFile = async (file: any, fileList: Array<any>) => {
|
||||||
|
fileList.splice(fileList.indexOf(file), 1)
|
||||||
|
if (fileArray.value.find((f: any) => f.name === file.name)) {
|
||||||
|
ElMessage.warning(t('chat.uploadFile.fileRepeat'))
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const max_file_size = (props.formField as any).max_file_size
|
||||||
|
if (file.size / 1024 / 1024 > max_file_size) {
|
||||||
|
ElMessage.warning(t('chat.uploadFile.sizeLimit') + max_file_size + 'MB')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fileList.length > attrs.limit) {
|
||||||
|
ElMessage.warning(
|
||||||
|
t('chat.uploadFile.limitMessage1') + attrs.limit + t('chat.uploadFile.limitMessage2'),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
upload(file.raw, loading).then((ok: any) => {
|
||||||
|
const split_path = ok.data.split('/')
|
||||||
|
const file_id = split_path[split_path.length - 1]
|
||||||
|
fileArray.value?.push({ name: file.name, file_id, size: file.size })
|
||||||
|
emit('update:modelValue', fileArray.value)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="scss">
|
||||||
|
.is-disabled {
|
||||||
|
background-color: var(--el-fill-color-light);
|
||||||
|
color: var(--el-text-color-placeholder);
|
||||||
|
cursor: not-allowed;
|
||||||
|
&:hover {
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,291 @@
|
||||||
|
<template>
|
||||||
|
<el-drawer
|
||||||
|
v-model="drawerVisible"
|
||||||
|
:title="$t('views.system.resourceAuthorization.title')"
|
||||||
|
size="60%"
|
||||||
|
:append-to-body="true"
|
||||||
|
:modal="false"
|
||||||
|
>
|
||||||
|
<div class="flex-between mb-16">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
:disabled="multipleSelection.length === 0"
|
||||||
|
@click="openMulConfigureDialog"
|
||||||
|
>{{ $t('views.system.resourceAuthorization.setting.configure') }}</el-button
|
||||||
|
>
|
||||||
|
|
||||||
|
<div class="flex-between complex-search">
|
||||||
|
<el-select
|
||||||
|
class="complex-search__left"
|
||||||
|
v-model="searchType"
|
||||||
|
style="width: 100px"
|
||||||
|
@change="search_type_change"
|
||||||
|
>
|
||||||
|
<el-option :label="$t('views.userManage.userForm.nick_name.label')" value="nick_name" />
|
||||||
|
<el-option :label="$t('views.login.loginForm.username.label')" value="username" />
|
||||||
|
<el-option
|
||||||
|
:label="$t('views.model.modelForm.permissionType.label')"
|
||||||
|
value="publish_status"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
<el-input
|
||||||
|
v-if="searchType === 'nick_name'"
|
||||||
|
v-model="searchForm.nick_name"
|
||||||
|
@change="searchHandle"
|
||||||
|
:placeholder="$t('common.search')"
|
||||||
|
style="width: 220px"
|
||||||
|
clearable
|
||||||
|
/>
|
||||||
|
<el-input
|
||||||
|
v-if="searchType === 'username'"
|
||||||
|
v-model="searchForm.username"
|
||||||
|
@change="searchHandle"
|
||||||
|
:placeholder="$t('common.search')"
|
||||||
|
style="width: 220px"
|
||||||
|
clearable
|
||||||
|
/>
|
||||||
|
|
||||||
|
<el-select
|
||||||
|
v-else-if="searchType === 'publish_status'"
|
||||||
|
v-model="searchForm.publish_status"
|
||||||
|
@change="searchHandle"
|
||||||
|
filterable
|
||||||
|
clearable
|
||||||
|
multiple
|
||||||
|
collapse-tags
|
||||||
|
collapse-tags-tooltip
|
||||||
|
style="width: 220px"
|
||||||
|
>
|
||||||
|
<template v-for="(item, index) in permissionOptions" :key="index">
|
||||||
|
<el-option :label="item.label" :value="item.value" />
|
||||||
|
</template>
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<app-table
|
||||||
|
ref="multipleTableRef"
|
||||||
|
class="mt-16"
|
||||||
|
:data="permissionData"
|
||||||
|
:pagination-config="paginationConfig"
|
||||||
|
@sizeChange="handleSizeChange"
|
||||||
|
@changePage="getPermissionList"
|
||||||
|
@selection-change="handleSelectionChange"
|
||||||
|
:maxTableHeight="200"
|
||||||
|
:row-key="(row: any) => row.id"
|
||||||
|
v-loading="loading"
|
||||||
|
>
|
||||||
|
<el-table-column type="selection" width="55" :reserve-selection="true" />
|
||||||
|
<el-table-column
|
||||||
|
prop="nick_name"
|
||||||
|
:label="$t('views.userManage.userForm.nick_name.label')"
|
||||||
|
min-width="120"
|
||||||
|
show-overflow-tooltip
|
||||||
|
/>
|
||||||
|
<el-table-column
|
||||||
|
prop="username"
|
||||||
|
min-width="120"
|
||||||
|
show-overflow-tooltip
|
||||||
|
:label="$t('views.login.loginForm.username.label')"
|
||||||
|
/>
|
||||||
|
<!-- <el-table-column prop="role_name" :label="$t('views.role.member.role')" width="210">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-popover :width="400">
|
||||||
|
<template #reference>
|
||||||
|
<TagGroup
|
||||||
|
class="cursor"
|
||||||
|
style="width: fit-content"
|
||||||
|
:tags="row.role_name"
|
||||||
|
tooltipDisabled
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template #default>
|
||||||
|
<el-table :data="row.role_workspace">
|
||||||
|
<el-table-column prop="role" :label="$t('views.role.member.role')">
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="workspace" :label="$t('views.workspace.title')">
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</template>
|
||||||
|
</el-popover>
|
||||||
|
</template>
|
||||||
|
</el-table-column> -->
|
||||||
|
<el-table-column :label="$t('common.operation')" align="left" width="340">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-radio-group
|
||||||
|
v-model="row.permission"
|
||||||
|
@change="(val: any) => permissionsHandle(val, row)"
|
||||||
|
>
|
||||||
|
<template v-for="(item, index) in permissionOptions" :key="index">
|
||||||
|
<el-radio :value="item.value" class="mr-16">{{ item.label }}</el-radio>
|
||||||
|
</template>
|
||||||
|
</el-radio-group>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</app-table>
|
||||||
|
|
||||||
|
<!-- 批量配置 弹出层 -->
|
||||||
|
<el-dialog
|
||||||
|
v-model="dialogVisible"
|
||||||
|
:title="$t('views.system.resourceAuthorization.setting.configure')"
|
||||||
|
destroy-on-close
|
||||||
|
@close="closeDialog"
|
||||||
|
>
|
||||||
|
<el-radio-group v-model="radioPermission" class="radio-block">
|
||||||
|
<template v-for="(item, index) in permissionOptions" :key="index">
|
||||||
|
<el-radio :value="item.value" class="mr-16">
|
||||||
|
<p class="color-text-primary lighter">{{ item.label }}</p>
|
||||||
|
<el-text class="color-secondary lighter">{{ item.desc }}</el-text>
|
||||||
|
</el-radio>
|
||||||
|
</template>
|
||||||
|
</el-radio-group>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer mt-24">
|
||||||
|
<el-button @click="closeDialog"> {{ $t('common.cancel') }}</el-button>
|
||||||
|
<el-button type="primary" @click="submitDialog"> {{ $t('common.confirm') }}</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</el-drawer>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, onMounted, watch, computed, reactive } from 'vue'
|
||||||
|
import { permissionOptions } from '@/views/system/resource-authorization/constant'
|
||||||
|
import AuthorizationApi from '@/api/system/resource-authorization'
|
||||||
|
import { MsgSuccess, MsgConfirm } from '@/utils/message'
|
||||||
|
import { t } from '@/locales'
|
||||||
|
import useStore from '@/stores'
|
||||||
|
const { user } = useStore()
|
||||||
|
const props = defineProps<{
|
||||||
|
type: string
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const drawerVisible = ref(false)
|
||||||
|
const multipleTableRef = ref()
|
||||||
|
|
||||||
|
watch(drawerVisible, (bool) => {
|
||||||
|
if (!bool) {
|
||||||
|
targetId.value = ''
|
||||||
|
searchType.value = 'nick_name'
|
||||||
|
searchForm.value = { nick_name: '', username: '', permission: undefined }
|
||||||
|
permissionData.value = []
|
||||||
|
paginationConfig.current_page = 1
|
||||||
|
paginationConfig.total = 0
|
||||||
|
multipleSelection.value = []
|
||||||
|
multipleTableRef.value?.clearSelection()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const loading = ref(false)
|
||||||
|
const targetId = ref('')
|
||||||
|
const permissionData = ref<any[]>([])
|
||||||
|
const searchType = ref('nick_name')
|
||||||
|
const searchForm = ref<any>({
|
||||||
|
nick_name: '',
|
||||||
|
username: '',
|
||||||
|
permission: undefined,
|
||||||
|
})
|
||||||
|
|
||||||
|
const search_type_change = () => {
|
||||||
|
searchForm.value = { nick_name: '', username: '', permission: undefined }
|
||||||
|
}
|
||||||
|
|
||||||
|
const paginationConfig = reactive({
|
||||||
|
current_page: 1,
|
||||||
|
page_size: 20,
|
||||||
|
total: 0,
|
||||||
|
})
|
||||||
|
|
||||||
|
function handleSizeChange() {
|
||||||
|
paginationConfig.current_page = 1
|
||||||
|
getPermissionList()
|
||||||
|
}
|
||||||
|
function searchHandle() {
|
||||||
|
paginationConfig.current_page = 1
|
||||||
|
getPermissionList()
|
||||||
|
}
|
||||||
|
|
||||||
|
const multipleSelection = ref<any[]>([])
|
||||||
|
|
||||||
|
const handleSelectionChange = (val: any[]) => {
|
||||||
|
multipleSelection.value = val
|
||||||
|
}
|
||||||
|
|
||||||
|
const dialogVisible = ref(false)
|
||||||
|
const radioPermission = ref('')
|
||||||
|
function openMulConfigureDialog() {
|
||||||
|
if (multipleSelection.value.length === 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
dialogVisible.value = true
|
||||||
|
}
|
||||||
|
function submitDialog() {
|
||||||
|
if (multipleSelection.value.length === 0 || !radioPermission.value) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const obj = multipleSelection.value.map((item) => ({
|
||||||
|
user_id: item.id,
|
||||||
|
permission: radioPermission.value,
|
||||||
|
}))
|
||||||
|
submitPermissions(obj)
|
||||||
|
closeDialog()
|
||||||
|
}
|
||||||
|
function closeDialog() {
|
||||||
|
dialogVisible.value = false
|
||||||
|
radioPermission.value = ''
|
||||||
|
multipleSelection.value = []
|
||||||
|
multipleTableRef.value?.clearSelection()
|
||||||
|
}
|
||||||
|
|
||||||
|
function permissionsHandle(val: any, row: any) {
|
||||||
|
const obj = [
|
||||||
|
{
|
||||||
|
user_id: row.id,
|
||||||
|
permission: val,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
submitPermissions(obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
function submitPermissions(obj: any) {
|
||||||
|
const workspaceId = user.getWorkspaceId() || 'default'
|
||||||
|
AuthorizationApi.putWorkspaceResourceAuthorization(
|
||||||
|
workspaceId,
|
||||||
|
targetId.value,
|
||||||
|
props.type,
|
||||||
|
obj,
|
||||||
|
loading,
|
||||||
|
).then(() => {
|
||||||
|
MsgSuccess(t('common.submitSuccess'))
|
||||||
|
getPermissionList()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const getPermissionList = () => {
|
||||||
|
const workspaceId = user.getWorkspaceId() || 'default'
|
||||||
|
const params: any = {}
|
||||||
|
if (searchForm.value[searchType.value]) {
|
||||||
|
params[searchType.value] = searchForm.value[searchType.value]
|
||||||
|
}
|
||||||
|
AuthorizationApi.getWorkspaceResourceAuthorization(
|
||||||
|
workspaceId,
|
||||||
|
targetId.value,
|
||||||
|
props.type,
|
||||||
|
paginationConfig,
|
||||||
|
params,
|
||||||
|
loading,
|
||||||
|
).then((res) => {
|
||||||
|
permissionData.value = res.data.records || []
|
||||||
|
paginationConfig.total = res.data.total || 0
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const open = (id: string) => {
|
||||||
|
targetId.value = id
|
||||||
|
drawerVisible.value = true
|
||||||
|
getPermissionList()
|
||||||
|
}
|
||||||
|
defineExpose({
|
||||||
|
open,
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped></style>
|
||||||
|
|
@ -19,4 +19,5 @@ export enum SourceTypeEnum {
|
||||||
KNOWLEDGE = 'KNOWLEDGE',
|
KNOWLEDGE = 'KNOWLEDGE',
|
||||||
APPLICATION = 'APPLICATION',
|
APPLICATION = 'APPLICATION',
|
||||||
TOOL = 'TOOL',
|
TOOL = 'TOOL',
|
||||||
|
MODEL = 'MODEL',
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,7 @@ export enum AuthorizationEnum {
|
||||||
MANAGE = 'MANAGE',
|
MANAGE = 'MANAGE',
|
||||||
VIEW = 'VIEW',
|
VIEW = 'VIEW',
|
||||||
ROLE = 'ROLE',
|
ROLE = 'ROLE',
|
||||||
KNOWLEDGE = 'KNOWLEDGE',
|
NOT_AUTH = 'NOT_AUTH',
|
||||||
APPLICATION = 'APPLICATION',
|
|
||||||
MODEL = 'MODEL',
|
|
||||||
TOOL = 'TOOL',
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum RoleTypeEnum {
|
export enum RoleTypeEnum {
|
||||||
|
|
|
||||||
|
|
@ -9,46 +9,48 @@ export default {
|
||||||
DatePicker: 'Date Picker',
|
DatePicker: 'Date Picker',
|
||||||
JsonInput: 'JSON',
|
JsonInput: 'JSON',
|
||||||
RadioCard: 'Radio Card',
|
RadioCard: 'Radio Card',
|
||||||
RadioRow: 'Radio Row'
|
RadioRow: 'Radio Row',
|
||||||
|
UploadInput: 'File upload',
|
||||||
|
TextareaInput: 'Multiline Input',
|
||||||
},
|
},
|
||||||
default: {
|
default: {
|
||||||
label: 'Default',
|
label: 'Default',
|
||||||
placeholder: 'Please enter a default',
|
placeholder: 'Please enter a default',
|
||||||
requiredMessage: ' is a required property',
|
requiredMessage: ' is a required property',
|
||||||
show: 'Show Default'
|
show: 'Show Default',
|
||||||
},
|
},
|
||||||
tip: {
|
tip: {
|
||||||
requiredMessage: 'cannot be empty',
|
requiredMessage: 'cannot be empty',
|
||||||
jsonMessage: 'Incorrect JSON format'
|
jsonMessage: 'Incorrect JSON format',
|
||||||
},
|
},
|
||||||
searchBar: {
|
searchBar: {
|
||||||
placeholder: 'Please enter keywords to search'
|
placeholder: 'Please enter keywords to search',
|
||||||
},
|
},
|
||||||
paramForm: {
|
paramForm: {
|
||||||
field: {
|
field: {
|
||||||
label: 'Parameter',
|
label: 'Parameter',
|
||||||
placeholder: 'Please enter a parameter',
|
placeholder: 'Please enter a parameter',
|
||||||
requiredMessage: 'Parameter is a required property',
|
requiredMessage: 'Parameter is a required property',
|
||||||
requiredMessage2: 'Only letters, numbers, and underscores are allowed'
|
requiredMessage2: 'Only letters, numbers, and underscores are allowed',
|
||||||
},
|
},
|
||||||
name: {
|
name: {
|
||||||
label: 'Name',
|
label: 'Name',
|
||||||
placeholder: 'Please enter a name',
|
placeholder: 'Please enter a name',
|
||||||
requiredMessage: 'Name is a required property'
|
requiredMessage: 'Name is a required property',
|
||||||
},
|
},
|
||||||
tooltip: {
|
tooltip: {
|
||||||
label: 'Tooltip',
|
label: 'Tooltip',
|
||||||
placeholder: 'Please enter a tooltip'
|
placeholder: 'Please enter a tooltip',
|
||||||
},
|
},
|
||||||
required: {
|
required: {
|
||||||
label: 'Required',
|
label: 'Required',
|
||||||
requiredMessage: 'Required is a required property'
|
requiredMessage: 'Required is a required property',
|
||||||
},
|
},
|
||||||
input_type: {
|
input_type: {
|
||||||
label: 'Type',
|
label: 'Type',
|
||||||
placeholder: 'Please select a type',
|
placeholder: 'Please select a type',
|
||||||
requiredMessage: 'Type is a required property'
|
requiredMessage: 'Type is a required property',
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
DatePicker: {
|
DatePicker: {
|
||||||
placeholder: 'Select Date',
|
placeholder: 'Select Date',
|
||||||
|
|
@ -58,35 +60,35 @@ export default {
|
||||||
datetime: 'Date Time',
|
datetime: 'Date Time',
|
||||||
dataType: {
|
dataType: {
|
||||||
label: 'Date Type',
|
label: 'Date Type',
|
||||||
placeholder: 'Please select a date type'
|
placeholder: 'Please select a date type',
|
||||||
},
|
},
|
||||||
format: {
|
format: {
|
||||||
label: 'Format',
|
label: 'Format',
|
||||||
placeholder: 'Please select a format'
|
placeholder: 'Please select a format',
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
Select: {
|
Select: {
|
||||||
label: 'Option Value',
|
label: 'Option Value',
|
||||||
placeholder: 'Please enter an option value'
|
placeholder: 'Please enter an option value',
|
||||||
},
|
},
|
||||||
tag: {
|
tag: {
|
||||||
label: 'Tag',
|
label: 'Tag',
|
||||||
placeholder: 'Please enter an option label'
|
placeholder: 'Please enter an option label',
|
||||||
},
|
},
|
||||||
Slider: {
|
Slider: {
|
||||||
showInput: {
|
showInput: {
|
||||||
label: 'Show Input Box'
|
label: 'Show Input Box',
|
||||||
},
|
},
|
||||||
valueRange: {
|
valueRange: {
|
||||||
label: 'Value Range',
|
label: 'Value Range',
|
||||||
minRequired: 'Minimum value is required',
|
minRequired: 'Minimum value is required',
|
||||||
maxRequired: 'Maximum value is required'
|
maxRequired: 'Maximum value is required',
|
||||||
},
|
},
|
||||||
step: {
|
step: {
|
||||||
label: 'Step Value',
|
label: 'Step Value',
|
||||||
requiredMessage1: 'Step value is required',
|
requiredMessage1: 'Step value is required',
|
||||||
requiredMessage2: 'Step value cannot be 0'
|
requiredMessage2: 'Step value cannot be 0',
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
TextInput: {
|
TextInput: {
|
||||||
length: {
|
length: {
|
||||||
|
|
@ -96,7 +98,34 @@ export default {
|
||||||
requiredMessage1: 'Length must be between',
|
requiredMessage1: 'Length must be between',
|
||||||
requiredMessage2: 'and',
|
requiredMessage2: 'and',
|
||||||
requiredMessage3: 'characters',
|
requiredMessage3: 'characters',
|
||||||
requiredMessage4: 'Text length is a required parameter'
|
requiredMessage4: 'Text length is a required parameter',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
|
UploadInput: {
|
||||||
|
limit: {
|
||||||
|
label: 'Maximum number of files per upload',
|
||||||
|
required: 'Maximum number of files is required',
|
||||||
|
},
|
||||||
|
max_file_size: {
|
||||||
|
label: 'Maximum file size (MB)',
|
||||||
|
required: 'Maximum file size is required',
|
||||||
|
},
|
||||||
|
accept: {
|
||||||
|
label: 'File type',
|
||||||
|
required: 'File type is required',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
AssignmentMethod: {
|
||||||
|
label: 'Assignment Method',
|
||||||
|
custom: {
|
||||||
|
label: 'Custom',
|
||||||
|
},
|
||||||
|
ref_variables: {
|
||||||
|
label: 'Reference Variables',
|
||||||
|
popover: 'Variable values must comply with',
|
||||||
|
popover_label: 'Label',
|
||||||
|
popover_value: 'Value',
|
||||||
|
popover_default: 'Is Default',
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -212,7 +212,7 @@ export default {
|
||||||
},
|
},
|
||||||
wecomBotSetting: {
|
wecomBotSetting: {
|
||||||
title: 'WeCom Bot Configuration',
|
title: 'WeCom Bot Configuration',
|
||||||
urlInfo: '-Security and Management-Management Tools-Intelligent Bots-API Mode',
|
urlInfo: '-Management Tools-Smart Bot-Create Bot-API Mode Create "URL"',
|
||||||
},
|
},
|
||||||
larkSetting: {
|
larkSetting: {
|
||||||
title: 'Lark Configuration',
|
title: 'Lark Configuration',
|
||||||
|
|
|
||||||
|
|
@ -158,6 +158,9 @@ export default {
|
||||||
placeholder: 'Directly return segment content',
|
placeholder: 'Directly return segment content',
|
||||||
requiredMessage: 'Please enter similarity value',
|
requiredMessage: 'Please enter similarity value',
|
||||||
},
|
},
|
||||||
|
allow_download: {
|
||||||
|
label: 'Allow download in knowledge base source',
|
||||||
|
}
|
||||||
},
|
},
|
||||||
hitHandlingMethod: {
|
hitHandlingMethod: {
|
||||||
optimization: 'Model optimization',
|
optimization: 'Model optimization',
|
||||||
|
|
|
||||||
|
|
@ -109,18 +109,20 @@ export default {
|
||||||
enableSSL: 'Enable SSL (if the SMTP port is 465, you usually need to enable SSL)',
|
enableSSL: 'Enable SSL (if the SMTP port is 465, you usually need to enable SSL)',
|
||||||
enableTLS: 'Enable TLS (if the SMTP port is 587, you usually need to enable TLS)',
|
enableTLS: 'Enable TLS (if the SMTP port is 587, you usually need to enable TLS)',
|
||||||
},
|
},
|
||||||
|
|
||||||
resourceAuthorization: {
|
resourceAuthorization: {
|
||||||
title: 'Resource Authorization',
|
title: 'Resource Authorization',
|
||||||
member: 'Member',
|
member: 'Member',
|
||||||
permissionSetting: 'Permission Setting',
|
permissionSetting: 'Permission Setting',
|
||||||
setting: {
|
setting: {
|
||||||
management: 'management',
|
management: 'management',
|
||||||
|
managementDesc: 'Can delete or modify this resource',
|
||||||
check: 'check',
|
check: 'check',
|
||||||
authorization: 'authorization',
|
checkDesc: 'Can only view the resource',
|
||||||
},
|
role: 'User Role',
|
||||||
priority: {
|
roleDesc: 'Authorize users based on their roles to access this resource',
|
||||||
label: 'Resource permission priority',
|
notAuthorized: 'Not Authorized',
|
||||||
role: 'Role',
|
configure: 'Configure Permission',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
resource_management: {
|
resource_management: {
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,7 @@ export default {
|
||||||
imageMessage: '请解析图片内容',
|
imageMessage: '请解析图片内容',
|
||||||
fileMessage: '请解析文件内容',
|
fileMessage: '请解析文件内容',
|
||||||
errorMessage: '上传失败',
|
errorMessage: '上传失败',
|
||||||
|
fileRepeat: '文件已存在',
|
||||||
},
|
},
|
||||||
executionDetails: {
|
executionDetails: {
|
||||||
title: '执行详情',
|
title: '执行详情',
|
||||||
|
|
|
||||||
|
|
@ -9,46 +9,48 @@ export default {
|
||||||
DatePicker: '日期',
|
DatePicker: '日期',
|
||||||
JsonInput: 'JSON文本框',
|
JsonInput: 'JSON文本框',
|
||||||
RadioCard: '选项卡',
|
RadioCard: '选项卡',
|
||||||
RadioRow: '单行选项卡'
|
RadioRow: '单行选项卡',
|
||||||
|
UploadInput: '文件上传',
|
||||||
|
TextareaInput: '多行文本框',
|
||||||
},
|
},
|
||||||
default: {
|
default: {
|
||||||
label: '默认值',
|
label: '默认值',
|
||||||
placeholder: '请输入默认值',
|
placeholder: '请输入默认值',
|
||||||
requiredMessage: '为必填属性',
|
requiredMessage: '为必填属性',
|
||||||
show: '显示默认值'
|
show: '显示默认值',
|
||||||
},
|
},
|
||||||
tip: {
|
tip: {
|
||||||
requiredMessage: '不能为空',
|
requiredMessage: '不能为空',
|
||||||
jsonMessage: 'JSON格式不正确'
|
jsonMessage: 'JSON格式不正确',
|
||||||
},
|
},
|
||||||
searchBar: {
|
searchBar: {
|
||||||
placeholder: '请输入关键字搜索'
|
placeholder: '请输入关键字搜索',
|
||||||
},
|
},
|
||||||
paramForm: {
|
paramForm: {
|
||||||
field: {
|
field: {
|
||||||
label: '参数',
|
label: '参数',
|
||||||
placeholder: '请输入参数',
|
placeholder: '请输入参数',
|
||||||
requiredMessage: '参数 为必填属性',
|
requiredMessage: '参数 为必填属性',
|
||||||
requiredMessage2: '只能输入字母数字和下划线'
|
requiredMessage2: '只能输入字母数字和下划线',
|
||||||
},
|
},
|
||||||
name: {
|
name: {
|
||||||
label: '显示名称',
|
label: '显示名称',
|
||||||
placeholder: '请输入显示名称',
|
placeholder: '请输入显示名称',
|
||||||
requiredMessage: '显示名称 为必填属性'
|
requiredMessage: '显示名称 为必填属性',
|
||||||
},
|
},
|
||||||
tooltip: {
|
tooltip: {
|
||||||
label: '参数提示说明',
|
label: '参数提示说明',
|
||||||
placeholder: '请输入参数提示说明'
|
placeholder: '请输入参数提示说明',
|
||||||
},
|
},
|
||||||
required: {
|
required: {
|
||||||
label: '是否必填',
|
label: '是否必填',
|
||||||
requiredMessage: '是否必填 为必填属性'
|
requiredMessage: '是否必填 为必填属性',
|
||||||
},
|
},
|
||||||
input_type: {
|
input_type: {
|
||||||
label: '组件类型',
|
label: '组件类型',
|
||||||
placeholder: '请选择组件类型',
|
placeholder: '请选择组件类型',
|
||||||
requiredMessage: '组建类型 为必填属性'
|
requiredMessage: '组建类型 为必填属性',
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
DatePicker: {
|
DatePicker: {
|
||||||
placeholder: '选择日期',
|
placeholder: '选择日期',
|
||||||
|
|
@ -58,35 +60,35 @@ export default {
|
||||||
datetime: '日期时间',
|
datetime: '日期时间',
|
||||||
dataType: {
|
dataType: {
|
||||||
label: '时间类型',
|
label: '时间类型',
|
||||||
placeholder: '请选择时间类型'
|
placeholder: '请选择时间类型',
|
||||||
},
|
},
|
||||||
format: {
|
format: {
|
||||||
label: '格式',
|
label: '格式',
|
||||||
placeholder: '请选择格式'
|
placeholder: '请选择格式',
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
Select: {
|
Select: {
|
||||||
label: '选项值',
|
label: '选项值',
|
||||||
placeholder: '请输入选项值'
|
placeholder: '请输入选项值',
|
||||||
},
|
},
|
||||||
tag: {
|
tag: {
|
||||||
label: '标签',
|
label: '标签',
|
||||||
placeholder: '请输入选项标签'
|
placeholder: '请输入选项标签',
|
||||||
},
|
},
|
||||||
Slider: {
|
Slider: {
|
||||||
showInput: {
|
showInput: {
|
||||||
label: '是否带输入框'
|
label: '是否带输入框',
|
||||||
},
|
},
|
||||||
valueRange: {
|
valueRange: {
|
||||||
label: '取值范围',
|
label: '取值范围',
|
||||||
minRequired: '最小值必填',
|
minRequired: '最小值必填',
|
||||||
maxRequired: '最大值必填'
|
maxRequired: '最大值必填',
|
||||||
},
|
},
|
||||||
step: {
|
step: {
|
||||||
label: '步长值',
|
label: '步长值',
|
||||||
requiredMessage1: '步长值必填',
|
requiredMessage1: '步长值必填',
|
||||||
requiredMessage2: '步长不能为0'
|
requiredMessage2: '步长不能为0',
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
TextInput: {
|
TextInput: {
|
||||||
length: {
|
length: {
|
||||||
|
|
@ -96,7 +98,35 @@ export default {
|
||||||
requiredMessage1: '长度在',
|
requiredMessage1: '长度在',
|
||||||
requiredMessage2: '到',
|
requiredMessage2: '到',
|
||||||
requiredMessage3: '个字符',
|
requiredMessage3: '个字符',
|
||||||
requiredMessage4: '文本长度为必填参数'
|
requiredMessage4: '文本长度为必填参数',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
|
UploadInput: {
|
||||||
|
limit: {
|
||||||
|
label: '单次上传最多文件数',
|
||||||
|
required: '单次上传最多文件数必填',
|
||||||
|
},
|
||||||
|
max_file_size: {
|
||||||
|
label: '每个文件最大(MB)',
|
||||||
|
required: '每个文件最大(MB)必填',
|
||||||
|
},
|
||||||
|
accept: {
|
||||||
|
label: '文件类型',
|
||||||
|
required: '文件类型必填',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
AssignmentMethod: {
|
||||||
|
label: '赋值方式',
|
||||||
|
|
||||||
|
custom: {
|
||||||
|
label: '自定义',
|
||||||
|
},
|
||||||
|
ref_variables: {
|
||||||
|
label: '引用变量 ',
|
||||||
|
popover: '变量的值必须符合',
|
||||||
|
popover_label: '标签',
|
||||||
|
popover_value: '值',
|
||||||
|
popover_default: '是否为默认值',
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -179,8 +179,8 @@ export default {
|
||||||
urlInfo: '-应用管理-自建-创建的应用-接收消息-设置 API 接收的 "URL" 中',
|
urlInfo: '-应用管理-自建-创建的应用-接收消息-设置 API 接收的 "URL" 中',
|
||||||
},
|
},
|
||||||
wecomBotSetting: {
|
wecomBotSetting: {
|
||||||
title: '企业微信应用配置',
|
title: '企业微信智能机器人配置',
|
||||||
urlInfo: '-安全与管理-管理工具-智能机器人- API 模式创建的 "URL" 中',
|
urlInfo: '-管理工具-智能机器人-创建机器人-API模式创建的 "URL" 中',
|
||||||
},
|
},
|
||||||
dingtalkSetting: {
|
dingtalkSetting: {
|
||||||
title: '钉钉应用配置',
|
title: '钉钉应用配置',
|
||||||
|
|
|
||||||
|
|
@ -151,6 +151,9 @@ export default {
|
||||||
placeholder: '直接返回分段内容',
|
placeholder: '直接返回分段内容',
|
||||||
requiredMessage: '请输入相似度',
|
requiredMessage: '请输入相似度',
|
||||||
},
|
},
|
||||||
|
allow_download: {
|
||||||
|
label: '允许在知识库来源中下载',
|
||||||
|
}
|
||||||
},
|
},
|
||||||
hitHandlingMethod: {
|
hitHandlingMethod: {
|
||||||
optimization: '模型优化',
|
optimization: '模型优化',
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
import role from './role'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
title: '系统管理',
|
title: '系统管理',
|
||||||
subTitle: '系统设置',
|
subTitle: '系统设置',
|
||||||
|
|
@ -115,12 +117,13 @@ export default {
|
||||||
permissionSetting: '资源权限配置',
|
permissionSetting: '资源权限配置',
|
||||||
setting: {
|
setting: {
|
||||||
management: '管理',
|
management: '管理',
|
||||||
|
managementDesc: '可对该资源进行删改操作',
|
||||||
check: '查看',
|
check: '查看',
|
||||||
authorization: '授权',
|
checkDesc: '仅能查看使用该资源',
|
||||||
},
|
role: '按用户角色',
|
||||||
priority: {
|
roleDesc: '根据用户角色中的权限授权用户对该资源的操作权限',
|
||||||
label: '资源权限优先级',
|
notAuthorized: '不授权',
|
||||||
role: '按角色',
|
configure: '配置权限',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
resource_management: {
|
resource_management: {
|
||||||
|
|
|
||||||
|
|
@ -9,46 +9,48 @@ export default {
|
||||||
DatePicker: '日期選擇器',
|
DatePicker: '日期選擇器',
|
||||||
JsonInput: 'JSON文字框',
|
JsonInput: 'JSON文字框',
|
||||||
RadioCard: '選項卡',
|
RadioCard: '選項卡',
|
||||||
RadioRow: '單行選項卡'
|
RadioRow: '單行選項卡',
|
||||||
|
UploadInput: '文件上傳',
|
||||||
|
TextareaInput: '多行文字方塊',
|
||||||
},
|
},
|
||||||
default: {
|
default: {
|
||||||
label: '預設值',
|
label: '預設值',
|
||||||
placeholder: '請輸入預設值',
|
placeholder: '請輸入預設值',
|
||||||
requiredMessage: '為必填屬性',
|
requiredMessage: '為必填屬性',
|
||||||
show: '顯示預設值'
|
show: '顯示預設值',
|
||||||
},
|
},
|
||||||
tip: {
|
tip: {
|
||||||
requiredMessage: '不能為空',
|
requiredMessage: '不能為空',
|
||||||
jsonMessage: 'JSON格式不正確'
|
jsonMessage: 'JSON格式不正確',
|
||||||
},
|
},
|
||||||
searchBar: {
|
searchBar: {
|
||||||
placeholder: '請輸入關鍵字搜索'
|
placeholder: '請輸入關鍵字搜索',
|
||||||
},
|
},
|
||||||
paramForm: {
|
paramForm: {
|
||||||
field: {
|
field: {
|
||||||
label: '參數',
|
label: '參數',
|
||||||
placeholder: '請輸入參數',
|
placeholder: '請輸入參數',
|
||||||
requiredMessage: '參數 為必填屬性',
|
requiredMessage: '參數 為必填屬性',
|
||||||
requiredMessage2: '只能輸入字母、數字和底線'
|
requiredMessage2: '只能輸入字母、數字和底線',
|
||||||
},
|
},
|
||||||
name: {
|
name: {
|
||||||
label: '顯示名稱',
|
label: '顯示名稱',
|
||||||
placeholder: '請輸入顯示名稱',
|
placeholder: '請輸入顯示名稱',
|
||||||
requiredMessage: '顯示名稱 為必填屬性'
|
requiredMessage: '顯示名稱 為必填屬性',
|
||||||
},
|
},
|
||||||
tooltip: {
|
tooltip: {
|
||||||
label: '參數提示說明',
|
label: '參數提示說明',
|
||||||
placeholder: '請輸入參數提示說明'
|
placeholder: '請輸入參數提示說明',
|
||||||
},
|
},
|
||||||
required: {
|
required: {
|
||||||
label: '是否必填',
|
label: '是否必填',
|
||||||
requiredMessage: '是否必填 為必填屬性'
|
requiredMessage: '是否必填 為必填屬性',
|
||||||
},
|
},
|
||||||
input_type: {
|
input_type: {
|
||||||
label: '組件類型',
|
label: '組件類型',
|
||||||
placeholder: '請選擇組件類型',
|
placeholder: '請選擇組件類型',
|
||||||
requiredMessage: '組件類型 為必填屬性'
|
requiredMessage: '組件類型 為必填屬性',
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
DatePicker: {
|
DatePicker: {
|
||||||
placeholder: '選擇日期',
|
placeholder: '選擇日期',
|
||||||
|
|
@ -58,35 +60,35 @@ export default {
|
||||||
datetime: '日期時間',
|
datetime: '日期時間',
|
||||||
dataType: {
|
dataType: {
|
||||||
label: '時間類型',
|
label: '時間類型',
|
||||||
placeholder: '請選擇時間類型'
|
placeholder: '請選擇時間類型',
|
||||||
},
|
},
|
||||||
format: {
|
format: {
|
||||||
label: '格式',
|
label: '格式',
|
||||||
placeholder: '請選擇格式'
|
placeholder: '請選擇格式',
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
Select: {
|
Select: {
|
||||||
label: '選項值',
|
label: '選項值',
|
||||||
placeholder: '請輸入選項值'
|
placeholder: '請輸入選項值',
|
||||||
},
|
},
|
||||||
tag: {
|
tag: {
|
||||||
label: '標籤',
|
label: '標籤',
|
||||||
placeholder: '請輸入選項標籤'
|
placeholder: '請輸入選項標籤',
|
||||||
},
|
},
|
||||||
Slider: {
|
Slider: {
|
||||||
showInput: {
|
showInput: {
|
||||||
label: '是否帶輸入框'
|
label: '是否帶輸入框',
|
||||||
},
|
},
|
||||||
valueRange: {
|
valueRange: {
|
||||||
label: '取值範圍',
|
label: '取值範圍',
|
||||||
minRequired: '最小值必填',
|
minRequired: '最小值必填',
|
||||||
maxRequired: '最大值必填'
|
maxRequired: '最大值必填',
|
||||||
},
|
},
|
||||||
step: {
|
step: {
|
||||||
label: '步長值',
|
label: '步長值',
|
||||||
requiredMessage1: '步長值必填',
|
requiredMessage1: '步長值必填',
|
||||||
requiredMessage2: '步長不能為0'
|
requiredMessage2: '步長不能為0',
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
TextInput: {
|
TextInput: {
|
||||||
length: {
|
length: {
|
||||||
|
|
@ -96,7 +98,34 @@ export default {
|
||||||
requiredMessage1: '長度在',
|
requiredMessage1: '長度在',
|
||||||
requiredMessage2: '到',
|
requiredMessage2: '到',
|
||||||
requiredMessage3: '個字元',
|
requiredMessage3: '個字元',
|
||||||
requiredMessage4: '文字長度為必填參數'
|
requiredMessage4: '文字長度為必填參數',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
|
UploadInput: {
|
||||||
|
limit: {
|
||||||
|
label: '單次上傳最多文件數',
|
||||||
|
required: '單次上傳最多文件數必填',
|
||||||
|
},
|
||||||
|
max_file_size: {
|
||||||
|
label: '每個文件最大(MB)',
|
||||||
|
required: '每個文件最大必填',
|
||||||
|
},
|
||||||
|
accept: {
|
||||||
|
label: '文件類型',
|
||||||
|
required: '文件類型必填',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
AssignmentMethod: {
|
||||||
|
label: '賦值方式',
|
||||||
|
custom: {
|
||||||
|
label: '自定義',
|
||||||
|
},
|
||||||
|
ref_variables: {
|
||||||
|
label: '參考變量',
|
||||||
|
popover: '變量的值必須符合',
|
||||||
|
popover_label: '標籤',
|
||||||
|
popover_value: '值',
|
||||||
|
popover_default: '是否為預設值',
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -204,9 +204,9 @@ export default {
|
||||||
verificationTokenPlaceholder: '請輸入Verification Token',
|
verificationTokenPlaceholder: '請輸入Verification Token',
|
||||||
urlInfo: '-事件與回呼-事件配置-配置訂閱方式的 "請求位址" 中',
|
urlInfo: '-事件與回呼-事件配置-配置訂閱方式的 "請求位址" 中',
|
||||||
},
|
},
|
||||||
wecomBotSetting: {
|
wecomBotSetting: {
|
||||||
title: '企業微信機器人配置',
|
title: '企業微信智能機器人配置',
|
||||||
urlInfo: '-安全與管理-管理工具-智能機器人- API 模式建立的 "URL" 中',
|
urlInfo: '-管理工具-智能机器人-创建机器人-API模式创建的 "URL" 中',
|
||||||
},
|
},
|
||||||
slackSetting: {
|
slackSetting: {
|
||||||
title: 'Slack 應用配置',
|
title: 'Slack 應用配置',
|
||||||
|
|
|
||||||
|
|
@ -154,6 +154,9 @@ export default {
|
||||||
placeholder: '直接返回分段内容',
|
placeholder: '直接返回分段内容',
|
||||||
requiredMessage: '请输入相似度',
|
requiredMessage: '请输入相似度',
|
||||||
},
|
},
|
||||||
|
allow_download: {
|
||||||
|
label: '允許在知識庫來源下載',
|
||||||
|
}
|
||||||
},
|
},
|
||||||
hitHandlingMethod: {
|
hitHandlingMethod: {
|
||||||
optimization: '模型優化',
|
optimization: '模型優化',
|
||||||
|
|
|
||||||
|
|
@ -109,18 +109,20 @@ export default {
|
||||||
enableSSL: '啟用 SSL(如果 SMTP 端口是 465,通常需要啟用 SSL)',
|
enableSSL: '啟用 SSL(如果 SMTP 端口是 465,通常需要啟用 SSL)',
|
||||||
enableTLS: '啟用 TLS(如果 SMTP 端口是 587,通常需要啟用 TLS)',
|
enableTLS: '啟用 TLS(如果 SMTP 端口是 587,通常需要啟用 TLS)',
|
||||||
},
|
},
|
||||||
|
|
||||||
resourceAuthorization: {
|
resourceAuthorization: {
|
||||||
title: '資源授权',
|
title: '資源授權',
|
||||||
member: '成員',
|
member: '成員',
|
||||||
permissionSetting: '資源权限配置',
|
permissionSetting: '資源權限配置',
|
||||||
setting: {
|
setting: {
|
||||||
management: '管理',
|
management: '管理',
|
||||||
|
managementDesc: '可對該資源進行刪改操作',
|
||||||
check: '查看',
|
check: '查看',
|
||||||
authorization: '授权',
|
checkDesc: '僅能查看使用該資源',
|
||||||
},
|
role: '按用戶角色',
|
||||||
priority: {
|
roleDesc: '根據用戶角色中的權限授權用戶對該資源的操作權限',
|
||||||
label: '資源权限优先级',
|
notAuthorized: '不授權',
|
||||||
role: '按角色',
|
configure: '配置權限',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
resource_management: {
|
resource_management: {
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@ const systemManage = {
|
||||||
'OR'
|
'OR'
|
||||||
),
|
),
|
||||||
folderDelete: () => false,
|
folderDelete: () => false,
|
||||||
|
auth: () => false,
|
||||||
overview_embed: () =>
|
overview_embed: () =>
|
||||||
hasPermission(
|
hasPermission(
|
||||||
[
|
[
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,16 @@ const workspace = {
|
||||||
],
|
],
|
||||||
'OR'
|
'OR'
|
||||||
),
|
),
|
||||||
|
auth: (source_id:string) =>
|
||||||
|
hasPermission(
|
||||||
|
[
|
||||||
|
new ComplexPermission([RoleConst.USER],[PermissionConst.APPLICATION.getApplicationWorkspaceResourcePermission(source_id)],[],'AND'),
|
||||||
|
RoleConst.WORKSPACE_MANAGE.getWorkspaceRole,
|
||||||
|
PermissionConst.APPLICATION_RESOURCE_AUTHORIZATION.getWorkspacePermissionWorkspaceManageRole,
|
||||||
|
PermissionConst.APPLICATION_RESOURCE_AUTHORIZATION.getApplicationWorkspaceResourcePermission(source_id)
|
||||||
|
],
|
||||||
|
'OR'
|
||||||
|
),
|
||||||
folderEdit: () =>
|
folderEdit: () =>
|
||||||
hasPermission(
|
hasPermission(
|
||||||
[
|
[
|
||||||
|
|
|
||||||
|
|
@ -151,6 +151,7 @@ const systemManage = {
|
||||||
],'OR'
|
],'OR'
|
||||||
),
|
),
|
||||||
|
|
||||||
|
auth: () => false,
|
||||||
folderCreate: () => false,
|
folderCreate: () => false,
|
||||||
folderEdit: () => false,
|
folderEdit: () => false,
|
||||||
folderDelete: () => false,
|
folderDelete: () => false,
|
||||||
|
|
|
||||||
|
|
@ -182,6 +182,7 @@ const share = {
|
||||||
],
|
],
|
||||||
'OR'
|
'OR'
|
||||||
),
|
),
|
||||||
|
auth: () => false,
|
||||||
folderCreate: () => false,
|
folderCreate: () => false,
|
||||||
folderEdit: () => false,
|
folderEdit: () => false,
|
||||||
folderDelete: () => false,
|
folderDelete: () => false,
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ const workspaceShare = {
|
||||||
edit: () => false,
|
edit: () => false,
|
||||||
export: () => false,
|
export: () => false,
|
||||||
delete: () => false,
|
delete: () => false,
|
||||||
|
auth: () => false,
|
||||||
|
|
||||||
doc_read: () => false,
|
doc_read: () => false,
|
||||||
doc_create: () => false,
|
doc_create: () => false,
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,16 @@ const workspace = {
|
||||||
],
|
],
|
||||||
'OR',
|
'OR',
|
||||||
),
|
),
|
||||||
|
auth: (source_id:string) =>
|
||||||
|
hasPermission(
|
||||||
|
[
|
||||||
|
new ComplexPermission([RoleConst.USER],[PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)],[],'AND'),
|
||||||
|
RoleConst.WORKSPACE_MANAGE.getWorkspaceRole,
|
||||||
|
PermissionConst.KNOWLEDGE_RESOURCE_AUTHORIZATION.getKnowledgeWorkspaceResourcePermission(source_id),
|
||||||
|
PermissionConst.KNOWLEDGE_RESOURCE_AUTHORIZATION.getWorkspacePermissionWorkspaceManageRole,
|
||||||
|
],
|
||||||
|
'OR',
|
||||||
|
),
|
||||||
folderEdit: () =>
|
folderEdit: () =>
|
||||||
hasPermission(
|
hasPermission(
|
||||||
[
|
[
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ const systemManage = {
|
||||||
delete: () =>
|
delete: () =>
|
||||||
hasPermission([RoleConst.ADMIN, PermissionConst.RESOURCE_MODEL_DELETE], 'OR'),
|
hasPermission([RoleConst.ADMIN, PermissionConst.RESOURCE_MODEL_DELETE], 'OR'),
|
||||||
|
|
||||||
|
auth: () => false,
|
||||||
folderCreate: () => false,
|
folderCreate: () => false,
|
||||||
folderEdit: () => false,
|
folderEdit: () => false,
|
||||||
folderDelete: () => false,
|
folderDelete: () => false,
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ const share = {
|
||||||
],
|
],
|
||||||
'OR',
|
'OR',
|
||||||
),
|
),
|
||||||
|
auth: () => false,
|
||||||
folderCreate: () => false,
|
folderCreate: () => false,
|
||||||
folderEdit: () => false,
|
folderEdit: () => false,
|
||||||
folderDelete: () => false,
|
folderDelete: () => false,
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,16 @@ const workspace = {
|
||||||
],
|
],
|
||||||
'OR'
|
'OR'
|
||||||
),
|
),
|
||||||
|
auth: (source_id:string) =>
|
||||||
|
hasPermission(
|
||||||
|
[
|
||||||
|
new ComplexPermission([RoleConst.USER],[PermissionConst.MODEL.getModelWorkspaceResourcePermission(source_id)],[],'AND'),
|
||||||
|
RoleConst.WORKSPACE_MANAGE.getWorkspaceRole,
|
||||||
|
PermissionConst.MODEL_RESOURCE_AUTHORIZATION.getModelWorkspaceResourcePermission(source_id),
|
||||||
|
PermissionConst.MODEL_RESOURCE_AUTHORIZATION.getWorkspacePermissionWorkspaceManageRole
|
||||||
|
],
|
||||||
|
'OR'
|
||||||
|
),
|
||||||
folderEdit: () =>
|
folderEdit: () =>
|
||||||
hasPermission(
|
hasPermission(
|
||||||
[
|
[
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,7 @@ const systemManage = {
|
||||||
'OR',
|
'OR',
|
||||||
),
|
),
|
||||||
|
|
||||||
|
auth: () => false,
|
||||||
folderCreate: () => false,
|
folderCreate: () => false,
|
||||||
folderEdit: () => false,
|
folderEdit: () => false,
|
||||||
folderDelete: () => false,
|
folderDelete: () => false,
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,7 @@ const share = {
|
||||||
'OR',
|
'OR',
|
||||||
),
|
),
|
||||||
|
|
||||||
|
auth: () => false,
|
||||||
folderCreate: () => false,
|
folderCreate: () => false,
|
||||||
folderEdit: () => false,
|
folderEdit: () => false,
|
||||||
folderDelete: () => false,
|
folderDelete: () => false,
|
||||||
|
|
|
||||||
|
|
@ -110,6 +110,16 @@ const workspace = {
|
||||||
],
|
],
|
||||||
'OR'
|
'OR'
|
||||||
),
|
),
|
||||||
|
auth: (source_id:string) =>
|
||||||
|
hasPermission(
|
||||||
|
[
|
||||||
|
new ComplexPermission([RoleConst.USER],[PermissionConst.TOOL.getToolWorkspaceResourcePermission(source_id)],[],'AND'),
|
||||||
|
RoleConst.WORKSPACE_MANAGE.getWorkspaceRole,
|
||||||
|
PermissionConst.TOOL_RESOURCE_AUTHORIZATION.getToolWorkspaceResourcePermission(source_id),
|
||||||
|
PermissionConst.TOOL_RESOURCE_AUTHORIZATION.getWorkspacePermissionWorkspaceManageRole
|
||||||
|
],
|
||||||
|
'OR'
|
||||||
|
),
|
||||||
debug: () =>
|
debug: () =>
|
||||||
hasPermission(
|
hasPermission(
|
||||||
[
|
[
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ div:focus {
|
||||||
}
|
}
|
||||||
|
|
||||||
ul {
|
ul {
|
||||||
list-style: none;
|
list-style: circle;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -296,6 +296,19 @@ const PermissionConst = {
|
||||||
CHANGE_PASSWORD: new Permission('OTHER:READ+CREATE'),
|
CHANGE_PASSWORD: new Permission('OTHER:READ+CREATE'),
|
||||||
SYSTEM_API_KEY_EDIT: new Permission('OTHER:READ+DELETE'),
|
SYSTEM_API_KEY_EDIT: new Permission('OTHER:READ+DELETE'),
|
||||||
|
|
||||||
|
APPLICATION_RESOURCE_AUTHORIZATION: new Permission(
|
||||||
|
'APPLICATION:READ+AUTH',
|
||||||
|
),
|
||||||
|
KNOWLEDGE_RESOURCE_AUTHORIZATION: new Permission(
|
||||||
|
'KNOWLEDGE:READ+AUTH',
|
||||||
|
),
|
||||||
|
TOOL_RESOURCE_AUTHORIZATION: new Permission(
|
||||||
|
'TOOL:READ+AUTH',
|
||||||
|
),
|
||||||
|
MODEL_RESOURCE_AUTHORIZATION: new Permission(
|
||||||
|
'MODEL:READ+AUTH',
|
||||||
|
),
|
||||||
|
|
||||||
APPLICATION_WORKSPACE_USER_RESOURCE_PERMISSION_READ: new Permission(
|
APPLICATION_WORKSPACE_USER_RESOURCE_PERMISSION_READ: new Permission(
|
||||||
'APPLICATION_WORKSPACE_USER_RESOURCE_PERMISSION:READ',
|
'APPLICATION_WORKSPACE_USER_RESOURCE_PERMISSION:READ',
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -84,6 +84,16 @@
|
||||||
}}</a
|
}}</a
|
||||||
>{{ $t('views.application.applicationAccess.larkSetting.urlInfo') }}
|
>{{ $t('views.application.applicationAccess.larkSetting.urlInfo') }}
|
||||||
</el-text>
|
</el-text>
|
||||||
|
<el-text type="info" v-if="configType === 'wecomBot'">
|
||||||
|
{{ $t('views.application.applicationAccess.copyUrl') }}
|
||||||
|
<a
|
||||||
|
class="color-primary"
|
||||||
|
href="https://work.weixin.qq.com/wework_admin/frame#/manageTools"
|
||||||
|
target="_blank"
|
||||||
|
>{{ $t('views.application.applicationAccess.wecomPlatform') }}</a
|
||||||
|
>{{ $t('views.application.applicationAccess.wecomBotSetting.urlInfo') }}
|
||||||
|
</el-text>
|
||||||
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,8 @@
|
||||||
<template #left>
|
<template #left>
|
||||||
<h4 class="p-12-16 pb-0 mt-12">{{ $t('views.application.title') }}</h4>
|
<h4 class="p-12-16 pb-0 mt-12">{{ $t('views.application.title') }}</h4>
|
||||||
<div class="p-8">
|
<div class="p-8">
|
||||||
<folder-tree
|
<folder-tree :source="SourceTypeEnum.APPLICATION" :data="folderList" :currentNodeKey="folder.currentFolder?.id"
|
||||||
:source="SourceTypeEnum.APPLICATION"
|
@handleNodeClick="folderClickHandle" @refreshTree="refreshFolder" />
|
||||||
:data="folderList"
|
|
||||||
:currentNodeKey="folder.currentFolder?.id"
|
|
||||||
@handleNodeClick="folderClickHandle"
|
|
||||||
@refreshTree="refreshFolder"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<ContentContainer>
|
<ContentContainer>
|
||||||
|
|
@ -19,44 +14,22 @@
|
||||||
<template #search>
|
<template #search>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<div class="flex-between complex-search">
|
<div class="flex-between complex-search">
|
||||||
<el-select
|
<el-select class="complex-search__left" v-model="search_type" style="width: 120px"
|
||||||
class="complex-search__left"
|
@change="search_type_change">
|
||||||
v-model="search_type"
|
|
||||||
style="width: 120px"
|
|
||||||
@change="search_type_change"
|
|
||||||
>
|
|
||||||
<el-option :label="$t('common.creator')" value="create_user" />
|
<el-option :label="$t('common.creator')" value="create_user" />
|
||||||
|
|
||||||
<el-option :label="$t('common.name')" value="name" />
|
<el-option :label="$t('common.name')" value="name" />
|
||||||
|
|
||||||
<el-option :label="$t('common.publishStatus')" value="publish_status" />
|
<el-option :label="$t('common.publishStatus')" value="publish_status" />
|
||||||
</el-select>
|
</el-select>
|
||||||
<el-input
|
<el-input v-if="search_type === 'name'" v-model="search_form.name" @change="searchHandle"
|
||||||
v-if="search_type === 'name'"
|
:placeholder="$t('common.searchBar.placeholder')" style="width: 220px" clearable />
|
||||||
v-model="search_form.name"
|
<el-select v-else-if="search_type === 'create_user'" v-model="search_form.create_user"
|
||||||
@change="searchHandle"
|
@change="searchHandle" filterable clearable style="width: 220px">
|
||||||
:placeholder="$t('common.searchBar.placeholder')"
|
|
||||||
style="width: 220px"
|
|
||||||
clearable
|
|
||||||
/>
|
|
||||||
<el-select
|
|
||||||
v-else-if="search_type === 'create_user'"
|
|
||||||
v-model="search_form.create_user"
|
|
||||||
@change="searchHandle"
|
|
||||||
filterable
|
|
||||||
clearable
|
|
||||||
style="width: 220px"
|
|
||||||
>
|
|
||||||
<el-option v-for="u in user_options" :key="u.id" :value="u.id" :label="u.nick_name" />
|
<el-option v-for="u in user_options" :key="u.id" :value="u.id" :label="u.nick_name" />
|
||||||
</el-select>
|
</el-select>
|
||||||
<el-select
|
<el-select v-else-if="search_type === 'publish_status'" v-model="search_form.publish_status"
|
||||||
v-else-if="search_type === 'publish_status'"
|
@change="searchHandle" filterable clearable style="width: 220px">
|
||||||
v-model="search_form.publish_status"
|
|
||||||
@change="searchHandle"
|
|
||||||
filterable
|
|
||||||
clearable
|
|
||||||
style="width: 220px"
|
|
||||||
>
|
|
||||||
<el-option :label="$t('common.published')" value="published" />
|
<el-option :label="$t('common.published')" value="published" />
|
||||||
<el-option :label="$t('common.unpublished')" value="unpublished" />
|
<el-option :label="$t('common.unpublished')" value="unpublished" />
|
||||||
</el-select>
|
</el-select>
|
||||||
|
|
@ -73,16 +46,11 @@
|
||||||
<el-dropdown-item @click="openCreateDialog('SIMPLE')">
|
<el-dropdown-item @click="openCreateDialog('SIMPLE')">
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<el-avatar shape="square" class="avatar-blue mt-4" :size="36">
|
<el-avatar shape="square" class="avatar-blue mt-4" :size="36">
|
||||||
<img
|
<img src="@/assets/application/icon_simple_application.svg" style="width: 65%" alt="" />
|
||||||
src="@/assets/application/icon_simple_application.svg"
|
|
||||||
style="width: 65%"
|
|
||||||
alt=""
|
|
||||||
/>
|
|
||||||
</el-avatar>
|
</el-avatar>
|
||||||
<div class="pre-wrap ml-8">
|
<div class="pre-wrap ml-8">
|
||||||
<div class="lighter">{{ $t('views.application.simple') }}</div>
|
<div class="lighter">{{ $t('views.application.simple') }}</div>
|
||||||
<el-text type="info" size="small"
|
<el-text type="info" size="small">{{ $t('views.application.simplePlaceholder') }}
|
||||||
>{{ $t('views.application.simplePlaceholder') }}
|
|
||||||
</el-text>
|
</el-text>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -90,31 +58,18 @@
|
||||||
<el-dropdown-item @click="openCreateDialog('WORK_FLOW')">
|
<el-dropdown-item @click="openCreateDialog('WORK_FLOW')">
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<el-avatar shape="square" class="avatar-purple mt-4" :size="36">
|
<el-avatar shape="square" class="avatar-purple mt-4" :size="36">
|
||||||
<img
|
<img src="@/assets/application/icon_workflow_application.svg" style="width: 65%" alt="" />
|
||||||
src="@/assets/application/icon_workflow_application.svg"
|
|
||||||
style="width: 65%"
|
|
||||||
alt=""
|
|
||||||
/>
|
|
||||||
</el-avatar>
|
</el-avatar>
|
||||||
<div class="pre-wrap ml-8">
|
<div class="pre-wrap ml-8">
|
||||||
<div class="lighter">{{ $t('views.application.workflow') }}</div>
|
<div class="lighter">{{ $t('views.application.workflow') }}</div>
|
||||||
<el-text type="info" size="small"
|
<el-text type="info" size="small">{{ $t('views.application.workflowPlaceholder') }}
|
||||||
>{{ $t('views.application.workflowPlaceholder') }}
|
|
||||||
</el-text>
|
</el-text>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
<el-upload
|
<el-upload class="import-button" ref="elUploadRef" :file-list="[]" action="#" multiple
|
||||||
class="import-button"
|
:auto-upload="false" :show-file-list="false" :limit="1"
|
||||||
ref="elUploadRef"
|
:on-change="(file: any, fileList: any) => importApplication(file)">
|
||||||
:file-list="[]"
|
|
||||||
action="#"
|
|
||||||
multiple
|
|
||||||
:auto-upload="false"
|
|
||||||
:show-file-list="false"
|
|
||||||
:limit="1"
|
|
||||||
:on-change="(file: any, fileList: any) => importApplication(file)"
|
|
||||||
>
|
|
||||||
<el-dropdown-item>
|
<el-dropdown-item>
|
||||||
<div class="flex align-center w-full">
|
<div class="flex align-center w-full">
|
||||||
<el-avatar shape="square" class="mt-4" :size="36" style="background: none">
|
<el-avatar shape="square" class="mt-4" :size="36" style="background: none">
|
||||||
|
|
@ -141,35 +96,16 @@
|
||||||
</el-dropdown>
|
</el-dropdown>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<div
|
<div v-loading.fullscreen.lock="paginationConfig.current_page === 1 && loading"
|
||||||
v-loading.fullscreen.lock="paginationConfig.current_page === 1 && loading"
|
style="max-height: calc(100vh - 120px)">
|
||||||
style="max-height: calc(100vh - 120px)"
|
<InfiniteScroll :size="applicationList.length" :total="paginationConfig.total"
|
||||||
>
|
:page_size="paginationConfig.page_size" v-model:current_page="paginationConfig.current_page" @load="getList"
|
||||||
<InfiniteScroll
|
:loading="loading">
|
||||||
:size="applicationList.length"
|
|
||||||
:total="paginationConfig.total"
|
|
||||||
:page_size="paginationConfig.page_size"
|
|
||||||
v-model:current_page="paginationConfig.current_page"
|
|
||||||
@load="getList"
|
|
||||||
:loading="loading"
|
|
||||||
>
|
|
||||||
<el-row v-if="applicationList.length > 0" :gutter="15" class="w-full">
|
<el-row v-if="applicationList.length > 0" :gutter="15" class="w-full">
|
||||||
<template v-for="(item, index) in applicationList" :key="index">
|
<template v-for="(item, index) in applicationList" :key="index">
|
||||||
<el-col
|
<el-col v-if="item.resource_type === 'folder'" :xs="24" :sm="12" :md="12" :lg="8" :xl="6" class="mb-16">
|
||||||
v-if="item.resource_type === 'folder'"
|
<CardBox :title="item.name" :description="item.desc || $t('components.noDesc')" class="cursor"
|
||||||
:xs="24"
|
@click="clickFolder(item)">
|
||||||
:sm="12"
|
|
||||||
:md="12"
|
|
||||||
:lg="8"
|
|
||||||
:xl="6"
|
|
||||||
class="mb-16"
|
|
||||||
>
|
|
||||||
<CardBox
|
|
||||||
:title="item.name"
|
|
||||||
:description="item.desc || $t('components.noDesc')"
|
|
||||||
class="cursor"
|
|
||||||
@click="clickFolder(item)"
|
|
||||||
>
|
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<el-avatar shape="square" :size="32" style="background: none">
|
<el-avatar shape="square" :size="32" style="background: none">
|
||||||
<AppIcon iconName="app-folder" style="font-size: 32px"></AppIcon>
|
<AppIcon iconName="app-folder" style="font-size: 32px"></AppIcon>
|
||||||
|
|
@ -183,12 +119,7 @@
|
||||||
</CardBox>
|
</CardBox>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col v-else :xs="24" :sm="12" :md="12" :lg="8" :xl="6" class="mb-16">
|
<el-col v-else :xs="24" :sm="12" :md="12" :lg="8" :xl="6" class="mb-16">
|
||||||
<CardBox
|
<CardBox :title="item.name" :description="item.desc" class="cursor" @click="goApp(item)">
|
||||||
:title="item.name"
|
|
||||||
:description="item.desc"
|
|
||||||
class="cursor"
|
|
||||||
@click="goApp(item)"
|
|
||||||
>
|
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<el-avatar shape="square" :size="32" style="background: none">
|
<el-avatar shape="square" :size="32" style="background: none">
|
||||||
<img :src="resetUrl(item?.icon, resetUrl('./favicon.ico'))" alt="" />
|
<img :src="resetUrl(item?.icon, resetUrl('./favicon.ico'))" alt="" />
|
||||||
|
|
@ -242,40 +173,33 @@
|
||||||
<AppIcon iconName="app-create-chat" class="color-secondary"></AppIcon>
|
<AppIcon iconName="app-create-chat" class="color-secondary"></AppIcon>
|
||||||
{{ $t('views.application.operation.toChat') }}
|
{{ $t('views.application.operation.toChat') }}
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
<el-dropdown-item
|
<el-dropdown-item @click.stop="settingApplication(item)"
|
||||||
@click.stop="settingApplication(item)"
|
v-if="permissionPrecise.edit(item.id)">
|
||||||
v-if="permissionPrecise.edit(item.id)"
|
|
||||||
>
|
|
||||||
<AppIcon iconName="app-setting" class="color-secondary"></AppIcon>
|
<AppIcon iconName="app-setting" class="color-secondary"></AppIcon>
|
||||||
{{ $t('common.setting') }}
|
{{ $t('common.setting') }}
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
<el-dropdown-item
|
|
||||||
@click.stop="openMoveToDialog(item)"
|
<el-dropdown-item @click.stop="openAuthorization(item)"
|
||||||
v-if="permissionPrecise.edit(item.id) && apiType === 'workspace'"
|
v-if="permissionPrecise.auth(item.id)">
|
||||||
>
|
<AppIcon iconName="app-resource-authorization" class="color-secondary"></AppIcon>
|
||||||
|
{{ $t('views.system.resourceAuthorization.title') }}
|
||||||
|
</el-dropdown-item>
|
||||||
|
<el-dropdown-item @click.stop="openMoveToDialog(item)"
|
||||||
|
v-if="permissionPrecise.edit(item.id) && apiType === 'workspace'">
|
||||||
<AppIcon iconName="app-migrate" class="color-secondary"></AppIcon>
|
<AppIcon iconName="app-migrate" class="color-secondary"></AppIcon>
|
||||||
{{ $t('common.moveTo') }}
|
{{ $t('common.moveTo') }}
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
<el-dropdown-item
|
<el-dropdown-item @click="copyApplication(item)" v-if="permissionPrecise.create()">
|
||||||
@click="copyApplication(item)"
|
|
||||||
v-if="permissionPrecise.create()"
|
|
||||||
>
|
|
||||||
<AppIcon iconName="app-copy" class="color-secondary"></AppIcon>
|
<AppIcon iconName="app-copy" class="color-secondary"></AppIcon>
|
||||||
{{ $t('common.copy') }}
|
{{ $t('common.copy') }}
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
<el-dropdown-item
|
<el-dropdown-item divided @click.stop="exportApplication(item)"
|
||||||
divided
|
v-if="permissionPrecise.export(item.id)">
|
||||||
@click.stop="exportApplication(item)"
|
|
||||||
v-if="permissionPrecise.export(item.id)"
|
|
||||||
>
|
|
||||||
<AppIcon iconName="app-export" class="color-secondary"></AppIcon>
|
<AppIcon iconName="app-export" class="color-secondary"></AppIcon>
|
||||||
{{ $t('common.export') }}
|
{{ $t('common.export') }}
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
<el-dropdown-item
|
<el-dropdown-item divided @click.stop="deleteApplication(item)"
|
||||||
divided
|
v-if="permissionPrecise.delete(item.id)">
|
||||||
@click.stop="deleteApplication(item)"
|
|
||||||
v-if="permissionPrecise.delete(item.id)"
|
|
||||||
>
|
|
||||||
<AppIcon iconName="app-delete" class="color-secondary"></AppIcon>
|
<AppIcon iconName="app-delete" class="color-secondary"></AppIcon>
|
||||||
{{ $t('common.delete') }}
|
{{ $t('common.delete') }}
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
|
|
@ -295,12 +219,9 @@
|
||||||
<CreateApplicationDialog ref="CreateApplicationDialogRef" />
|
<CreateApplicationDialog ref="CreateApplicationDialogRef" />
|
||||||
<CopyApplicationDialog ref="CopyApplicationDialogRef" />
|
<CopyApplicationDialog ref="CopyApplicationDialogRef" />
|
||||||
<CreateFolderDialog ref="CreateFolderDialogRef" @refresh="refreshFolder" />
|
<CreateFolderDialog ref="CreateFolderDialogRef" @refresh="refreshFolder" />
|
||||||
<MoveToDialog
|
<MoveToDialog ref="MoveToDialogRef" :source="SourceTypeEnum.APPLICATION" @refresh="refreshApplicationList"
|
||||||
ref="MoveToDialogRef"
|
v-if="apiType === 'workspace'" />
|
||||||
:source="SourceTypeEnum.APPLICATION"
|
<ResourceAuthorizationDrawer :type="SourceTypeEnum.APPLICATION" ref="ResourceAuthorizationDrawerRef" />
|
||||||
@refresh="refreshApplicationList"
|
|
||||||
v-if="apiType === 'workspace'"
|
|
||||||
/>
|
|
||||||
</LayoutContainer>
|
</LayoutContainer>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -310,6 +231,7 @@ import CreateApplicationDialog from '@/views/application/component/CreateApplica
|
||||||
import CreateFolderDialog from '@/components/folder-tree/CreateFolderDialog.vue'
|
import CreateFolderDialog from '@/components/folder-tree/CreateFolderDialog.vue'
|
||||||
import CopyApplicationDialog from '@/views/application/component/CopyApplicationDialog.vue'
|
import CopyApplicationDialog from '@/views/application/component/CopyApplicationDialog.vue'
|
||||||
import MoveToDialog from '@/components/folder-tree/MoveToDialog.vue'
|
import MoveToDialog from '@/components/folder-tree/MoveToDialog.vue'
|
||||||
|
import ResourceAuthorizationDrawer from '@/components/resource-authorization-drawer/index.vue'
|
||||||
import ApplicationApi from '@/api/application/application'
|
import ApplicationApi from '@/api/application/application'
|
||||||
import { MsgSuccess, MsgConfirm, MsgError } from '@/utils/message'
|
import { MsgSuccess, MsgConfirm, MsgError } from '@/utils/message'
|
||||||
import useStore from '@/stores'
|
import useStore from '@/stores'
|
||||||
|
|
@ -318,7 +240,7 @@ import { useRouter, useRoute } from 'vue-router'
|
||||||
import { isWorkFlow } from '@/utils/application'
|
import { isWorkFlow } from '@/utils/application'
|
||||||
import { resetUrl } from '@/utils/common'
|
import { resetUrl } from '@/utils/common'
|
||||||
import { dateFormat } from '@/utils/time'
|
import { dateFormat } from '@/utils/time'
|
||||||
import { SourceTypeEnum, ValidType, ValidCount } from '@/enums/common'
|
import { SourceTypeEnum } from '@/enums/common'
|
||||||
import permissionMap from '@/permission'
|
import permissionMap from '@/permission'
|
||||||
import WorkspaceApi from '@/api/workspace/workspace'
|
import WorkspaceApi from '@/api/workspace/workspace'
|
||||||
import { hasPermission } from '@/utils/permission'
|
import { hasPermission } from '@/utils/permission'
|
||||||
|
|
@ -358,6 +280,11 @@ const folderList = ref<any[]>([])
|
||||||
const applicationList = ref<any[]>([])
|
const applicationList = ref<any[]>([])
|
||||||
const CopyApplicationDialogRef = ref()
|
const CopyApplicationDialogRef = ref()
|
||||||
|
|
||||||
|
const ResourceAuthorizationDrawerRef = ref()
|
||||||
|
function openAuthorization(item: any) {
|
||||||
|
ResourceAuthorizationDrawerRef.value.open(item.id)
|
||||||
|
}
|
||||||
|
|
||||||
const MoveToDialogRef = ref()
|
const MoveToDialogRef = ref()
|
||||||
|
|
||||||
function openMoveToDialog(data: any) {
|
function openMoveToDialog(data: any) {
|
||||||
|
|
@ -517,20 +444,20 @@ function toChat(row: any) {
|
||||||
.map((v: any) => {
|
.map((v: any) => {
|
||||||
apiInputParams.value = v.properties.api_input_field_list
|
apiInputParams.value = v.properties.api_input_field_list
|
||||||
? v.properties.api_input_field_list.map((v: any) => {
|
? v.properties.api_input_field_list.map((v: any) => {
|
||||||
return {
|
return {
|
||||||
name: v.variable,
|
name: v.variable,
|
||||||
value: v.default_value,
|
value: v.default_value,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
: v.properties.input_field_list
|
: v.properties.input_field_list
|
||||||
? v.properties.input_field_list
|
? v.properties.input_field_list
|
||||||
.filter((v: any) => v.assignment_method === 'api_input')
|
.filter((v: any) => v.assignment_method === 'api_input')
|
||||||
.map((v: any) => {
|
.map((v: any) => {
|
||||||
return {
|
return {
|
||||||
name: v.variable,
|
name: v.variable,
|
||||||
value: v.default_value,
|
value: v.default_value,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
: []
|
: []
|
||||||
})
|
})
|
||||||
const apiParams = mapToUrlParams(apiInputParams.value)
|
const apiParams = mapToUrlParams(apiInputParams.value)
|
||||||
|
|
@ -588,7 +515,7 @@ function deleteApplication(row: any) {
|
||||||
MsgSuccess(t('common.deleteSuccess'))
|
MsgSuccess(t('common.deleteSuccess'))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.catch(() => {})
|
.catch(() => { })
|
||||||
}
|
}
|
||||||
|
|
||||||
const exportApplication = (application: any) => {
|
const exportApplication = (application: any) => {
|
||||||
|
|
|
||||||
|
|
@ -359,12 +359,12 @@ const nextChatRecord = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const pre_disable = computed(() => {
|
const pre_disable = computed(() => {
|
||||||
let index = tableIndexMap.value[currentChatId.value] - 1
|
const index = tableIndexMap.value[currentChatId.value] - 1
|
||||||
return index < 0 && paginationConfig.current_page <= 1
|
return index < 0 && paginationConfig.current_page <= 1
|
||||||
})
|
})
|
||||||
|
|
||||||
const next_disable = computed(() => {
|
const next_disable = computed(() => {
|
||||||
let index = tableIndexMap.value[currentChatId.value] + 1
|
const index = tableIndexMap.value[currentChatId.value] + 1
|
||||||
return (
|
return (
|
||||||
index >= tableData.value.length &&
|
index >= tableData.value.length &&
|
||||||
index + (paginationConfig.current_page - 1) * paginationConfig.page_size >=
|
index + (paginationConfig.current_page - 1) * paginationConfig.page_size >=
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
>
|
>
|
||||||
<el-button class="collapse cursor" circle @click="show = !show">
|
<el-button class="collapse cursor" circle @click="show = !show">
|
||||||
<el-icon>
|
<el-icon>
|
||||||
<component :is="!show ? 'ArrowRightBold' : 'ArrowLeftBold'" />
|
<component :is="!show ? 'ArrowRightBold' : 'ArrowLeftBold'"/>
|
||||||
</el-icon>
|
</el-icon>
|
||||||
</el-button>
|
</el-button>
|
||||||
<HistoryPanel
|
<HistoryPanel
|
||||||
|
|
@ -32,12 +32,12 @@
|
||||||
chatUser.chat_profile.authentication_type === 'password'
|
chatUser.chat_profile.authentication_type === 'password'
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<img src="@/assets/user-icon.svg" style="width: 54%" alt="" />
|
<img src="@/assets/user-icon.svg" style="width: 54%" alt=""/>
|
||||||
</el-avatar>
|
</el-avatar>
|
||||||
<el-dropdown v-else trigger="click" type="primary" class="w-full">
|
<el-dropdown v-else trigger="click" type="primary" class="w-full">
|
||||||
<div class="flex align-center">
|
<div class="flex align-center">
|
||||||
<el-avatar :size="32">
|
<el-avatar :size="32">
|
||||||
<img src="@/assets/user-icon.svg" style="width: 54%" alt="" />
|
<img src="@/assets/user-icon.svg" style="width: 54%" alt=""/>
|
||||||
</el-avatar>
|
</el-avatar>
|
||||||
<span class="ml-8 color-text-primary">{{ chatUser.chatUserProfile?.nick_name }}</span>
|
<span class="ml-8 color-text-primary">{{ chatUser.chatUserProfile?.nick_name }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -47,7 +47,7 @@
|
||||||
<div class="flex align-center p-8">
|
<div class="flex align-center p-8">
|
||||||
<div class="mr-8 flex align-center">
|
<div class="mr-8 flex align-center">
|
||||||
<el-avatar :size="40">
|
<el-avatar :size="40">
|
||||||
<img src="@/assets/user-icon.svg" style="width: 54%" alt="" />
|
<img src="@/assets/user-icon.svg" style="width: 54%" alt=""/>
|
||||||
</el-avatar>
|
</el-avatar>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
|
@ -72,7 +72,7 @@
|
||||||
style="padding-top: 8px; padding-bottom: 8px"
|
style="padding-top: 8px; padding-bottom: 8px"
|
||||||
@click="logout"
|
@click="logout"
|
||||||
>
|
>
|
||||||
<AppIcon iconName="app-export" class="color-secondary" />
|
<AppIcon iconName="app-export" class="color-secondary"/>
|
||||||
{{ $t('layout.logout') }}
|
{{ $t('layout.logout') }}
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
</el-dropdown-menu>
|
</el-dropdown-menu>
|
||||||
|
|
@ -91,15 +91,16 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, computed, defineModel } from 'vue'
|
import {ref, computed, defineModel} from 'vue'
|
||||||
import useStore from '@/stores'
|
import useStore from '@/stores'
|
||||||
import HistoryPanel from '@/views/chat/component/HistoryPanel.vue'
|
import HistoryPanel from '@/views/chat/component/HistoryPanel.vue'
|
||||||
import ResetPassword from '@/layout/layout-header/avatar/ResetPassword.vue'
|
import ResetPassword from '@/layout/layout-header/avatar/ResetPassword.vue'
|
||||||
import type { ResetCurrentUserPasswordRequest } from '@/api/type/user'
|
import type {ResetCurrentUserPasswordRequest} from '@/api/type/user'
|
||||||
import chatAPI from '@/api/chat/chat'
|
import chatAPI from '@/api/chat/chat'
|
||||||
import { useRouter } from 'vue-router'
|
import {useRoute, useRouter} from 'vue-router'
|
||||||
const router = useRouter()
|
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
const route = useRoute()
|
||||||
const show = defineModel<boolean>('show')
|
const show = defineModel<boolean>('show')
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
|
|
@ -111,7 +112,7 @@ const props = defineProps<{
|
||||||
|
|
||||||
const emit = defineEmits(['newChat', 'clickLog', 'deleteLog', 'refreshFieldTitle', 'clearChat'])
|
const emit = defineEmits(['newChat', 'clickLog', 'deleteLog', 'refreshFieldTitle', 'clearChat'])
|
||||||
|
|
||||||
const { chatUser } = useStore()
|
const {chatUser} = useStore()
|
||||||
|
|
||||||
const clearChat = () => {
|
const clearChat = () => {
|
||||||
emit('clearChat')
|
emit('clearChat')
|
||||||
|
|
@ -128,6 +129,7 @@ const handleClickList = (item: any) => {
|
||||||
const deleteChatLog = (row: any) => {
|
const deleteChatLog = (row: any) => {
|
||||||
emit('deleteLog', row)
|
emit('deleteLog', row)
|
||||||
}
|
}
|
||||||
|
|
||||||
function refreshFieldTitle(chatId: string, abstract: string) {
|
function refreshFieldTitle(chatId: string, abstract: string) {
|
||||||
emit('refreshFieldTitle', chatId, abstract)
|
emit('refreshFieldTitle', chatId, abstract)
|
||||||
}
|
}
|
||||||
|
|
@ -139,13 +141,18 @@ const openResetPassword = () => {
|
||||||
|
|
||||||
const handleResetPassword = (param: ResetCurrentUserPasswordRequest) => {
|
const handleResetPassword = (param: ResetCurrentUserPasswordRequest) => {
|
||||||
chatAPI.resetCurrentPassword(param).then(() => {
|
chatAPI.resetCurrentPassword(param).then(() => {
|
||||||
router.push({ name: 'login' })
|
router.push({name: 'login'})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const logout = () => {
|
const logout = () => {
|
||||||
chatUser.logout().then(() => {
|
chatUser.logout().then(() => {
|
||||||
router.push({ name: 'login' })
|
router.push({
|
||||||
|
name: 'login',
|
||||||
|
params: {accessToken: chatUser.accessToken},
|
||||||
|
query: route.query,
|
||||||
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,11 @@
|
||||||
/><span>{{ $t('views.document.form.similarity.placeholder') }}</span>
|
/><span>{{ $t('views.document.form.similarity.placeholder') }}</span>
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item prop="allow_download">
|
||||||
|
<el-checkbox v-model="form.allow_download">
|
||||||
|
{{ $t('views.document.form.allow_download.label') }}
|
||||||
|
</el-checkbox>
|
||||||
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<span class="dialog-footer">
|
<span class="dialog-footer">
|
||||||
|
|
@ -127,6 +132,7 @@ const form = ref<any>({
|
||||||
selector: '',
|
selector: '',
|
||||||
hit_handling_method: 'optimization',
|
hit_handling_method: 'optimization',
|
||||||
directly_return_similarity: 0.9,
|
directly_return_similarity: 0.9,
|
||||||
|
allow_download: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
// 文档设置
|
// 文档设置
|
||||||
|
|
@ -162,6 +168,7 @@ watch(dialogVisible, (bool) => {
|
||||||
selector: '',
|
selector: '',
|
||||||
hit_handling_method: 'optimization',
|
hit_handling_method: 'optimization',
|
||||||
directly_return_similarity: 0.9,
|
directly_return_similarity: 0.9,
|
||||||
|
allow_download: false,
|
||||||
}
|
}
|
||||||
isImport.value = false
|
isImport.value = false
|
||||||
documentType.value = ''
|
documentType.value = ''
|
||||||
|
|
@ -200,6 +207,7 @@ const submit = async (formEl: FormInstance | undefined) => {
|
||||||
const obj = {
|
const obj = {
|
||||||
source_url_list: form.value.source_url.split('\n'),
|
source_url_list: form.value.source_url.split('\n'),
|
||||||
selector: form.value.selector,
|
selector: form.value.selector,
|
||||||
|
allow_download: form.value.allow_download,
|
||||||
}
|
}
|
||||||
loadSharedApi({ type: 'document', systemType: apiType.value })
|
loadSharedApi({ type: 'document', systemType: apiType.value })
|
||||||
.postWebDocument(id, obj, loading)
|
.postWebDocument(id, obj, loading)
|
||||||
|
|
@ -219,6 +227,7 @@ const submit = async (formEl: FormInstance | undefined) => {
|
||||||
...{
|
...{
|
||||||
source_url: form.value.source_url,
|
source_url: form.value.source_url,
|
||||||
selector: form.value.selector,
|
selector: form.value.selector,
|
||||||
|
allow_download: form.value.allow_download,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -51,10 +51,11 @@
|
||||||
>{{ $t('views.document.generateQuestion.title') }}
|
>{{ $t('views.document.generateQuestion.title') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
@click="openknowledgeDialog()"
|
@click="openBatchEditDocument"
|
||||||
:disabled="multipleSelection.length === 0"
|
:disabled="multipleSelection.length === 0"
|
||||||
v-if="permissionPrecise.doc_migrate(id)"
|
v-if="permissionPrecise.doc_edit(id)"
|
||||||
>{{ $t('views.document.setting.migration') }}
|
>
|
||||||
|
{{ $t('common.setting') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-dropdown v-if="MoreFilledPermission0(id)">
|
<el-dropdown v-if="MoreFilledPermission0(id)">
|
||||||
<el-button class="ml-12 mr-12">
|
<el-button class="ml-12 mr-12">
|
||||||
|
|
@ -63,11 +64,11 @@
|
||||||
<template #dropdown>
|
<template #dropdown>
|
||||||
<el-dropdown-menu>
|
<el-dropdown-menu>
|
||||||
<el-dropdown-item
|
<el-dropdown-item
|
||||||
@click="openBatchEditDocument"
|
@click="openknowledgeDialog()"
|
||||||
:disabled="multipleSelection.length === 0"
|
:disabled="multipleSelection.length === 0"
|
||||||
v-if="permissionPrecise.doc_edit(id)"
|
v-if="permissionPrecise.doc_migrate(id)"
|
||||||
>
|
>
|
||||||
{{ $t('common.setting') }}
|
{{ $t('views.document.setting.migration') }}
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
<el-dropdown-item
|
<el-dropdown-item
|
||||||
divided
|
divided
|
||||||
|
|
@ -434,16 +435,12 @@
|
||||||
"
|
"
|
||||||
@click="cancelTask(row, TaskType.GENERATE_PROBLEM)"
|
@click="cancelTask(row, TaskType.GENERATE_PROBLEM)"
|
||||||
>
|
>
|
||||||
<AppIcon
|
<el-icon class="color-secondary"><Close /></el-icon>
|
||||||
iconName="app-generate-question"
|
|
||||||
class="color-secondary"
|
|
||||||
></AppIcon>
|
|
||||||
{{ $t('views.document.setting.cancelGenerateQuestion') }}
|
{{ $t('views.document.setting.cancelGenerateQuestion') }}
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
<el-dropdown-item
|
<el-dropdown-item
|
||||||
v-else
|
|
||||||
@click="openGenerateDialog(row)"
|
@click="openGenerateDialog(row)"
|
||||||
v-if="permissionPrecise.doc_generate(id)"
|
v-else-if="permissionPrecise.doc_generate(id)"
|
||||||
>
|
>
|
||||||
<AppIcon
|
<AppIcon
|
||||||
iconName="app-generate-question"
|
iconName="app-generate-question"
|
||||||
|
|
@ -494,18 +491,6 @@
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="knowledgeDetail?.type === 1 || knowledgeDetail?.type === 2">
|
<template v-if="knowledgeDetail?.type === 1 || knowledgeDetail?.type === 2">
|
||||||
<el-tooltip
|
|
||||||
effect="dark"
|
|
||||||
:content="$t('views.knowledge.setting.sync')"
|
|
||||||
placement="top"
|
|
||||||
v-if="permissionPrecise.sync(id)"
|
|
||||||
>
|
|
||||||
<span class="mr-4">
|
|
||||||
<el-button type="primary" text @click.stop="syncDocument(row)">
|
|
||||||
<AppIcon iconName="app-sync"></AppIcon>
|
|
||||||
</el-button>
|
|
||||||
</span>
|
|
||||||
</el-tooltip>
|
|
||||||
<el-tooltip
|
<el-tooltip
|
||||||
effect="dark"
|
effect="dark"
|
||||||
:content="$t('views.document.setting.cancelVectorization')"
|
:content="$t('views.document.setting.cancelVectorization')"
|
||||||
|
|
@ -538,6 +523,18 @@
|
||||||
</el-button>
|
</el-button>
|
||||||
</span>
|
</span>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
<el-tooltip
|
||||||
|
effect="dark"
|
||||||
|
:content="$t('common.setting')"
|
||||||
|
placement="top"
|
||||||
|
v-if="permissionPrecise.doc_edit(id)"
|
||||||
|
>
|
||||||
|
<span class="mr-4">
|
||||||
|
<el-button type="primary" text @click.stop="settingDoc(row)">
|
||||||
|
<AppIcon iconName="app-setting"></AppIcon>
|
||||||
|
</el-button>
|
||||||
|
</span>
|
||||||
|
</el-tooltip>
|
||||||
<span @click.stop>
|
<span @click.stop>
|
||||||
<el-dropdown trigger="click" v-if="MoreFilledPermission2(id)">
|
<el-dropdown trigger="click" v-if="MoreFilledPermission2(id)">
|
||||||
<el-button text type="primary">
|
<el-button text type="primary">
|
||||||
|
|
@ -546,11 +543,11 @@
|
||||||
<template #dropdown>
|
<template #dropdown>
|
||||||
<el-dropdown-menu>
|
<el-dropdown-menu>
|
||||||
<el-dropdown-item
|
<el-dropdown-item
|
||||||
@click="settingDoc(row)"
|
@click="syncDocument(row)"
|
||||||
v-if="permissionPrecise.doc_edit(id)"
|
v-if="permissionPrecise.sync(id)"
|
||||||
>
|
>
|
||||||
<AppIcon iconName="app-setting"></AppIcon>
|
<AppIcon iconName="app-sync" class="color-secondary"></AppIcon>
|
||||||
{{ $t('common.setting') }}</el-dropdown-item
|
{{ $t('views.knowledge.setting.sync') }}</el-dropdown-item
|
||||||
>
|
>
|
||||||
<el-dropdown-item
|
<el-dropdown-item
|
||||||
v-if="
|
v-if="
|
||||||
|
|
@ -561,43 +558,45 @@
|
||||||
"
|
"
|
||||||
@click="cancelTask(row, TaskType.GENERATE_PROBLEM)"
|
@click="cancelTask(row, TaskType.GENERATE_PROBLEM)"
|
||||||
>
|
>
|
||||||
<AppIcon iconName="app-generate-question"></AppIcon>
|
<el-icon class="color-secondary"><Close /></el-icon>
|
||||||
{{ $t('views.document.setting.cancelGenerateQuestion') }}
|
{{ $t('views.document.setting.cancelGenerateQuestion') }}
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
<el-dropdown-item
|
<el-dropdown-item
|
||||||
v-else
|
|
||||||
@click="openGenerateDialog(row)"
|
@click="openGenerateDialog(row)"
|
||||||
v-if="permissionPrecise.doc_generate(id)"
|
v-else-if="permissionPrecise.doc_generate(id)"
|
||||||
>
|
>
|
||||||
<AppIcon iconName="app-generate-question"></AppIcon>
|
<AppIcon
|
||||||
|
iconName="app-generate-question"
|
||||||
|
class="color-secondary"
|
||||||
|
></AppIcon>
|
||||||
{{ $t('views.document.generateQuestion.title') }}
|
{{ $t('views.document.generateQuestion.title') }}
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
<el-dropdown-item
|
<el-dropdown-item
|
||||||
@click="openknowledgeDialog(row)"
|
@click="openknowledgeDialog(row)"
|
||||||
v-if="permissionPrecise.doc_migrate(id)"
|
v-if="permissionPrecise.doc_migrate(id)"
|
||||||
>
|
>
|
||||||
<AppIcon iconName="app-migrate"></AppIcon>
|
<AppIcon iconName="app-migrate" class="color-secondary"></AppIcon>
|
||||||
{{ $t('views.document.setting.migration') }}
|
{{ $t('views.document.setting.migration') }}
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
<el-dropdown-item
|
<el-dropdown-item
|
||||||
@click="exportDocument(row)"
|
@click="exportDocument(row)"
|
||||||
v-if="permissionPrecise.doc_export(id)"
|
v-if="permissionPrecise.doc_export(id)"
|
||||||
>
|
>
|
||||||
<AppIcon iconName="app-export"></AppIcon>
|
<AppIcon iconName="app-export" class="color-secondary"></AppIcon>
|
||||||
{{ $t('views.document.setting.export') }} Excel
|
{{ $t('views.document.setting.export') }} Excel
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
<el-dropdown-item
|
<el-dropdown-item
|
||||||
@click="exportDocumentZip(row)"
|
@click="exportDocumentZip(row)"
|
||||||
v-if="permissionPrecise.doc_export(id)"
|
v-if="permissionPrecise.doc_export(id)"
|
||||||
>
|
>
|
||||||
<AppIcon iconName="app-export"></AppIcon>
|
<AppIcon iconName="app-export" class="color-secondary"></AppIcon>
|
||||||
{{ $t('views.document.setting.export') }} Zip
|
{{ $t('views.document.setting.export') }} Zip
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
<el-dropdown-item
|
<el-dropdown-item
|
||||||
@click.stop="deleteDocument(row)"
|
@click.stop="deleteDocument(row)"
|
||||||
v-if="permissionPrecise.doc_delete(id)"
|
v-if="permissionPrecise.doc_delete(id)"
|
||||||
>
|
>
|
||||||
<AppIcon iconName="app-delete"></AppIcon>
|
<AppIcon iconName="app-delete" class="color-secondary"></AppIcon>
|
||||||
{{ $t('common.delete') }}
|
{{ $t('common.delete') }}
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
</el-dropdown-menu>
|
</el-dropdown-menu>
|
||||||
|
|
@ -712,7 +711,7 @@ const permissionPrecise = computed(() => {
|
||||||
|
|
||||||
const MoreFilledPermission0 = (id: string) => {
|
const MoreFilledPermission0 = (id: string) => {
|
||||||
return (
|
return (
|
||||||
permissionPrecise.value.doc_edit(id) ||
|
permissionPrecise.value.doc_migrate(id) ||
|
||||||
(knowledgeDetail?.value.type === 1 && permissionPrecise.value.doc_sync(id)) ||
|
(knowledgeDetail?.value.type === 1 && permissionPrecise.value.doc_sync(id)) ||
|
||||||
(knowledgeDetail?.value.type === 2 && permissionPrecise.value.doc_sync(id)) ||
|
(knowledgeDetail?.value.type === 2 && permissionPrecise.value.doc_sync(id)) ||
|
||||||
permissionPrecise.value.doc_delete(id)
|
permissionPrecise.value.doc_delete(id)
|
||||||
|
|
@ -731,7 +730,7 @@ const MoreFilledPermission1 = (id: string) => {
|
||||||
|
|
||||||
const MoreFilledPermission2 = (id: string) => {
|
const MoreFilledPermission2 = (id: string) => {
|
||||||
return (
|
return (
|
||||||
permissionPrecise.value.doc_edit(id) ||
|
permissionPrecise.value.sync(id) ||
|
||||||
permissionPrecise.value.doc_generate(id) ||
|
permissionPrecise.value.doc_generate(id) ||
|
||||||
permissionPrecise.value.doc_migrate(id) ||
|
permissionPrecise.value.doc_migrate(id) ||
|
||||||
permissionPrecise.value.doc_export(id) ||
|
permissionPrecise.value.doc_export(id) ||
|
||||||
|
|
|
||||||
|
|
@ -47,11 +47,10 @@ import { groupBy } from 'lodash'
|
||||||
import type { knowledgeData } from '@/api/type/knowledge'
|
import type { knowledgeData } from '@/api/type/knowledge'
|
||||||
import { t } from '@/locales'
|
import { t } from '@/locales'
|
||||||
import { loadSharedApi } from '@/utils/dynamics-api/shared-api'
|
import { loadSharedApi } from '@/utils/dynamics-api/shared-api'
|
||||||
import modelResourceApi from '@/api/system-resource-management/model'
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
data?: {
|
data?: {
|
||||||
type: Object
|
type: object
|
||||||
default: () => {}
|
default: () => null
|
||||||
}
|
}
|
||||||
apiType: 'systemShare' | 'workspace' | 'systemManage'
|
apiType: 'systemShare' | 'workspace' | 'systemManage'
|
||||||
}>()
|
}>()
|
||||||
|
|
|
||||||
|
|
@ -258,7 +258,16 @@
|
||||||
<AppIcon iconName="app-lock" class="color-secondary"></AppIcon>
|
<AppIcon iconName="app-lock" class="color-secondary"></AppIcon>
|
||||||
{{ $t('views.shared.authorized_workspace') }}</el-dropdown-item
|
{{ $t('views.shared.authorized_workspace') }}</el-dropdown-item
|
||||||
>
|
>
|
||||||
|
<el-dropdown-item
|
||||||
|
@click.stop="openAuthorization(item)"
|
||||||
|
v-if="apiType === 'workspace' && permissionPrecise.auth(item.id)"
|
||||||
|
>
|
||||||
|
<AppIcon
|
||||||
|
iconName="app-resource-authorization"
|
||||||
|
class="color-secondary"
|
||||||
|
></AppIcon>
|
||||||
|
{{ $t('views.system.resourceAuthorization.title') }}
|
||||||
|
</el-dropdown-item>
|
||||||
<el-dropdown-item
|
<el-dropdown-item
|
||||||
@click.stop="openMoveToDialog(item)"
|
@click.stop="openMoveToDialog(item)"
|
||||||
v-if="permissionPrecise.edit(item.id) && apiType === 'workspace'"
|
v-if="permissionPrecise.edit(item.id) && apiType === 'workspace'"
|
||||||
|
|
@ -328,6 +337,11 @@
|
||||||
@refresh="refreshKnowledgeList"
|
@refresh="refreshKnowledgeList"
|
||||||
v-if="apiType === 'workspace'"
|
v-if="apiType === 'workspace'"
|
||||||
/>
|
/>
|
||||||
|
<ResourceAuthorizationDrawer
|
||||||
|
:type="SourceTypeEnum.KNOWLEDGE"
|
||||||
|
ref="ResourceAuthorizationDrawerRef"
|
||||||
|
v-if="apiType === 'workspace'"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
|
@ -342,6 +356,7 @@ import CreateFolderDialog from '@/components/folder-tree/CreateFolderDialog.vue'
|
||||||
import MoveToDialog from '@/components/folder-tree/MoveToDialog.vue'
|
import MoveToDialog from '@/components/folder-tree/MoveToDialog.vue'
|
||||||
import GenerateRelatedDialog from '@/components/generate-related-dialog/index.vue'
|
import GenerateRelatedDialog from '@/components/generate-related-dialog/index.vue'
|
||||||
import AuthorizedWorkspace from '@/views/system-shared/AuthorizedWorkspaceDialog.vue'
|
import AuthorizedWorkspace from '@/views/system-shared/AuthorizedWorkspaceDialog.vue'
|
||||||
|
import ResourceAuthorizationDrawer from '@/components/resource-authorization-drawer/index.vue'
|
||||||
import { MsgSuccess, MsgConfirm } from '@/utils/message'
|
import { MsgSuccess, MsgConfirm } from '@/utils/message'
|
||||||
import useStore from '@/stores'
|
import useStore from '@/stores'
|
||||||
import { numberFormat } from '@/utils/common'
|
import { numberFormat } from '@/utils/common'
|
||||||
|
|
@ -407,6 +422,11 @@ const paginationConfig = reactive({
|
||||||
total: 0,
|
total: 0,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const ResourceAuthorizationDrawerRef = ref()
|
||||||
|
function openAuthorization(item: any) {
|
||||||
|
ResourceAuthorizationDrawerRef.value.open(item.id)
|
||||||
|
}
|
||||||
|
|
||||||
const MoveToDialogRef = ref()
|
const MoveToDialogRef = ref()
|
||||||
function openMoveToDialog(data: any) {
|
function openMoveToDialog(data: any) {
|
||||||
// 仅2个参数就行
|
// 仅2个参数就行
|
||||||
|
|
|
||||||
|
|
@ -100,6 +100,10 @@
|
||||||
<AppIcon iconName="app-setting" class="color-secondary"></AppIcon>
|
<AppIcon iconName="app-setting" class="color-secondary"></AppIcon>
|
||||||
{{ $t('views.model.modelForm.title.paramSetting') }}
|
{{ $t('views.model.modelForm.title.paramSetting') }}
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
|
<el-dropdown-item @click.stop="openAuthorization(model)" v-if="apiType === 'workspace' && permissionPrecise.auth(model.id)">
|
||||||
|
<AppIcon iconName="app-resource-authorization" class="color-secondary"></AppIcon>
|
||||||
|
{{ $t('views.system.resourceAuthorization.title') }}
|
||||||
|
</el-dropdown-item>
|
||||||
<el-dropdown-item
|
<el-dropdown-item
|
||||||
divided
|
divided
|
||||||
text
|
text
|
||||||
|
|
@ -119,6 +123,11 @@
|
||||||
ref="AuthorizedWorkspaceDialogRef"
|
ref="AuthorizedWorkspaceDialogRef"
|
||||||
v-if="isSystemShare"
|
v-if="isSystemShare"
|
||||||
></AuthorizedWorkspace>
|
></AuthorizedWorkspace>
|
||||||
|
<ResourceAuthorizationDrawer
|
||||||
|
:type="SourceTypeEnum.MODEL"
|
||||||
|
ref="ResourceAuthorizationDrawerRef"
|
||||||
|
v-if="apiType === 'workspace'"
|
||||||
|
/>
|
||||||
</card-box>
|
</card-box>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
|
@ -130,6 +139,8 @@ import { MsgConfirm, MsgSuccess } from '@/utils/message'
|
||||||
import { modelType } from '@/enums/model'
|
import { modelType } from '@/enums/model'
|
||||||
import ParamSettingDialog from './ParamSettingDialog.vue'
|
import ParamSettingDialog from './ParamSettingDialog.vue'
|
||||||
import AuthorizedWorkspace from '@/views/system-shared/AuthorizedWorkspaceDialog.vue'
|
import AuthorizedWorkspace from '@/views/system-shared/AuthorizedWorkspaceDialog.vue'
|
||||||
|
import ResourceAuthorizationDrawer from '@/components/resource-authorization-drawer/index.vue'
|
||||||
|
import { SourceTypeEnum } from '@/enums/common'
|
||||||
import { t } from '@/locales'
|
import { t } from '@/locales'
|
||||||
import permissionMap from '@/permission'
|
import permissionMap from '@/permission'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
|
|
@ -146,10 +157,8 @@ const props = defineProps<{
|
||||||
apiType: 'systemShare' | 'workspace' | 'systemManage'
|
apiType: 'systemShare' | 'workspace' | 'systemManage'
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const apiType = props.apiType
|
|
||||||
|
|
||||||
const isSystemShare = computed(() => {
|
const isSystemShare = computed(() => {
|
||||||
return apiType === 'systemShare'
|
return props.apiType === 'systemShare'
|
||||||
})
|
})
|
||||||
|
|
||||||
const permissionPrecise = computed(() => {
|
const permissionPrecise = computed(() => {
|
||||||
|
|
@ -162,6 +171,11 @@ const MoreFilledPermission = (id: any) => {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ResourceAuthorizationDrawerRef = ref()
|
||||||
|
function openAuthorization(item: any) {
|
||||||
|
ResourceAuthorizationDrawerRef.value.open(item.id)
|
||||||
|
}
|
||||||
|
|
||||||
const downModel = ref<Model>()
|
const downModel = ref<Model>()
|
||||||
|
|
||||||
const currentModel = computed(() => {
|
const currentModel = computed(() => {
|
||||||
|
|
|
||||||
|
|
@ -178,6 +178,7 @@
|
||||||
import { ref, onMounted, watch, computed } from 'vue'
|
import { ref, onMounted, watch, computed } from 'vue'
|
||||||
import type { Provider } from '@/api/type/model'
|
import type { Provider } from '@/api/type/model'
|
||||||
import { AuthorizationEnum } from '@/enums/system'
|
import { AuthorizationEnum } from '@/enums/system'
|
||||||
|
import { SourceTypeEnum } from '@/enums/common'
|
||||||
import { isAppIcon, resetUrl } from '@/utils/common'
|
import { isAppIcon, resetUrl } from '@/utils/common'
|
||||||
import { EditionConst } from '@/utils/permission/data'
|
import { EditionConst } from '@/utils/permission/data'
|
||||||
import { hasPermission } from '@/utils/permission/index'
|
import { hasPermission } from '@/utils/permission/index'
|
||||||
|
|
@ -202,10 +203,10 @@ const radioRole = computed({
|
||||||
emit('update:isRole', v)
|
emit('update:isRole', v)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
const isKnowledge = computed(() => props.type === AuthorizationEnum.KNOWLEDGE)
|
const isKnowledge = computed(() => props.type === SourceTypeEnum.KNOWLEDGE)
|
||||||
const isApplication = computed(() => props.type === AuthorizationEnum.APPLICATION)
|
const isApplication = computed(() => props.type === SourceTypeEnum.APPLICATION)
|
||||||
const isTool = computed(() => props.type === AuthorizationEnum.TOOL)
|
const isTool = computed(() => props.type === SourceTypeEnum.TOOL)
|
||||||
const isModel = computed(() => props.type === AuthorizationEnum.MODEL)
|
const isModel = computed(() => props.type === SourceTypeEnum.MODEL)
|
||||||
const defaultExpandKeys = computed(() => (props.data?.length > 0 ? [props.data[0]?.id] : []))
|
const defaultExpandKeys = computed(() => (props.data?.length > 0 ? [props.data[0]?.id] : []))
|
||||||
const dfsPermission = (arr: any = [], Name: string | number, e: boolean, idArr: any[]) => {
|
const dfsPermission = (arr: any = [], Name: string | number, e: boolean, idArr: any[]) => {
|
||||||
arr.map((item: any) => {
|
arr.map((item: any) => {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,308 @@
|
||||||
|
<template>
|
||||||
|
<div class="permission-setting p-24 flex">
|
||||||
|
<div class="resource-authorization__table">
|
||||||
|
<h4 class="mb-16">{{ $t('views.system.resourceAuthorization.permissionSetting') }}</h4>
|
||||||
|
<div class="flex-between mb-16">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
v-if="
|
||||||
|
hasPermission(permissionObj[(route.meta?.resource as string) || 'APPLICATION'], 'OR')
|
||||||
|
"
|
||||||
|
:disabled="multipleSelection.length === 0"
|
||||||
|
@click="openMulConfigureDialog"
|
||||||
|
>{{ $t('views.system.resourceAuthorization.setting.configure') }}</el-button
|
||||||
|
>
|
||||||
|
|
||||||
|
<div class="flex-between complex-search">
|
||||||
|
<el-select
|
||||||
|
class="complex-search__left"
|
||||||
|
v-model="searchType"
|
||||||
|
style="width: 80px"
|
||||||
|
@change="search_type_change"
|
||||||
|
>
|
||||||
|
<el-option :label="$t('common.name')" value="name" />
|
||||||
|
<el-option
|
||||||
|
:label="$t('views.model.modelForm.permissionType.label')"
|
||||||
|
value="permission"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
<el-input
|
||||||
|
v-if="searchType === 'name'"
|
||||||
|
v-model="searchForm.name"
|
||||||
|
@change="searchHandle"
|
||||||
|
:placeholder="$t('common.searchBar.placeholder')"
|
||||||
|
style="width: 220px"
|
||||||
|
clearable
|
||||||
|
/>
|
||||||
|
<el-select
|
||||||
|
v-else-if="searchType === 'permission'"
|
||||||
|
v-model="searchForm.permission"
|
||||||
|
@change="searchHandle"
|
||||||
|
filterable
|
||||||
|
clearable
|
||||||
|
multiple
|
||||||
|
collapse-tags
|
||||||
|
collapse-tags-tooltip
|
||||||
|
style="width: 220px"
|
||||||
|
>
|
||||||
|
<template v-for="(item, index) in permissionOptions" :key="index">
|
||||||
|
<el-option :label="item.label" :value="item.value" />
|
||||||
|
</template>
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<app-table
|
||||||
|
ref="multipleTableRef"
|
||||||
|
class="mt-16"
|
||||||
|
:data="props.data"
|
||||||
|
:pagination-config="paginationConfig"
|
||||||
|
@sizeChange="handleSizeChange"
|
||||||
|
@changePage="props.getData"
|
||||||
|
@selection-change="handleSelectionChange"
|
||||||
|
:maxTableHeight="320"
|
||||||
|
:row-key="(row: any) => row.id"
|
||||||
|
>
|
||||||
|
<el-table-column type="selection" width="55" :reserve-selection="true" />
|
||||||
|
<el-table-column prop="name" :label="$t('common.name')">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-space :size="8">
|
||||||
|
<!-- 知识库 icon -->
|
||||||
|
<KnowledgeIcon :size="20" v-if="isKnowledge" :type="row.icon" />
|
||||||
|
<!-- 应用/工具 自定义 icon -->
|
||||||
|
<el-avatar
|
||||||
|
v-else-if="isAppIcon(row?.icon) && !isModel"
|
||||||
|
style="background: none"
|
||||||
|
shape="square"
|
||||||
|
:size="20"
|
||||||
|
>
|
||||||
|
<img :src="resetUrl(row?.icon)" alt="" />
|
||||||
|
</el-avatar>
|
||||||
|
<!-- 应用 icon -->
|
||||||
|
<LogoIcon v-else-if="isApplication" height="20px" />
|
||||||
|
<!-- 工具 icon -->
|
||||||
|
<el-avatar v-else-if="isTool" class="avatar-green" shape="square" :size="20">
|
||||||
|
<img src="@/assets/workflow/icon_tool.svg" style="width: 58%" alt="" />
|
||||||
|
</el-avatar>
|
||||||
|
<!-- 模型 icon -->
|
||||||
|
<span
|
||||||
|
v-else-if="isModel"
|
||||||
|
style="width: 20px; height: 20px; display: inline-block"
|
||||||
|
:innerHTML="getProviderIcon(row)"
|
||||||
|
></span>
|
||||||
|
<span :title="row?.name" class="ellipsis-1">
|
||||||
|
{{ row?.name }}
|
||||||
|
</span>
|
||||||
|
</el-space>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column :label="$t('common.operation')" align="left">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-radio-group
|
||||||
|
v-model="row.permission"
|
||||||
|
@change="(val: any) => submitPermissions(val, row)"
|
||||||
|
>
|
||||||
|
<template v-for="(item, index) in permissionOptions" :key="index">
|
||||||
|
<el-radio :value="item.value" class="mr-16">{{ item.label }}</el-radio>
|
||||||
|
</template>
|
||||||
|
</el-radio-group>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</app-table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 批量配置 弹出层 -->
|
||||||
|
<el-dialog
|
||||||
|
v-model="dialogVisible"
|
||||||
|
:title="$t('views.system.resourceAuthorization.setting.configure')"
|
||||||
|
destroy-on-close
|
||||||
|
@close="closeDialog"
|
||||||
|
>
|
||||||
|
<el-radio-group v-model="radioPermission" class="radio-block">
|
||||||
|
<template v-for="(item, index) in permissionOptions" :key="index">
|
||||||
|
<el-radio :value="item.value" class="mr-16">
|
||||||
|
<p class="color-text-primary lighter">{{ item.label }}</p>
|
||||||
|
<el-text class="color-secondary lighter">{{ item.desc }}</el-text>
|
||||||
|
</el-radio>
|
||||||
|
</template>
|
||||||
|
</el-radio-group>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer mt-24">
|
||||||
|
<el-button @click="closeDialog"> {{ $t('common.cancel') }}</el-button>
|
||||||
|
<el-button type="primary" @click="submitDialog"> {{ $t('common.confirm') }}</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, onMounted, watch, computed, reactive } from 'vue'
|
||||||
|
import { useRoute } from 'vue-router'
|
||||||
|
import type { Provider } from '@/api/type/model'
|
||||||
|
import { SourceTypeEnum } from '@/enums/common'
|
||||||
|
import { isAppIcon, resetUrl } from '@/utils/common'
|
||||||
|
import { RoleConst, PermissionConst } from '@/utils/permission/data'
|
||||||
|
import { hasPermission } from '@/utils/permission/index'
|
||||||
|
import { ComplexPermission } from '@/utils/permission/type'
|
||||||
|
import { permissionOptions } from '@/views/system/resource-authorization/constant'
|
||||||
|
import useStore from '@/stores'
|
||||||
|
const { model, user } = useStore()
|
||||||
|
const route = useRoute()
|
||||||
|
const props = defineProps<{
|
||||||
|
data: any[]
|
||||||
|
type: string
|
||||||
|
getData?: () => void
|
||||||
|
}>()
|
||||||
|
const emit = defineEmits(['submitPermissions'])
|
||||||
|
const permissionObj = ref<any>({
|
||||||
|
APPLICATION: new ComplexPermission(
|
||||||
|
[RoleConst.ADMIN, RoleConst.WORKSPACE_MANAGE],
|
||||||
|
[
|
||||||
|
PermissionConst.APPLICATION_WORKSPACE_USER_RESOURCE_PERMISSION_EDIT,
|
||||||
|
PermissionConst.APPLICATION_WORKSPACE_USER_RESOURCE_PERMISSION_EDIT
|
||||||
|
.getWorkspacePermissionWorkspaceManageRole,
|
||||||
|
],
|
||||||
|
[],
|
||||||
|
'OR',
|
||||||
|
),
|
||||||
|
KNOWLEDGE: new ComplexPermission(
|
||||||
|
[RoleConst.ADMIN, RoleConst.WORKSPACE_MANAGE],
|
||||||
|
[
|
||||||
|
PermissionConst.KNOWLEDGE_WORKSPACE_USER_RESOURCE_PERMISSION_EDIT,
|
||||||
|
PermissionConst.KNOWLEDGE_WORKSPACE_USER_RESOURCE_PERMISSION_EDIT
|
||||||
|
.getWorkspacePermissionWorkspaceManageRole,
|
||||||
|
],
|
||||||
|
[],
|
||||||
|
'OR',
|
||||||
|
),
|
||||||
|
TOOL: new ComplexPermission(
|
||||||
|
[RoleConst.ADMIN, RoleConst.WORKSPACE_MANAGE],
|
||||||
|
[
|
||||||
|
PermissionConst.TOOL_WORKSPACE_USER_RESOURCE_PERMISSION_EDIT,
|
||||||
|
PermissionConst.TOOL_WORKSPACE_USER_RESOURCE_PERMISSION_EDIT
|
||||||
|
.getWorkspacePermissionWorkspaceManageRole,
|
||||||
|
],
|
||||||
|
[],
|
||||||
|
'OR',
|
||||||
|
),
|
||||||
|
MODEL: new ComplexPermission(
|
||||||
|
[RoleConst.ADMIN, RoleConst.WORKSPACE_MANAGE],
|
||||||
|
[
|
||||||
|
PermissionConst.MODEL_WORKSPACE_USER_RESOURCE_PERMISSION_EDIT,
|
||||||
|
PermissionConst.MODEL_WORKSPACE_USER_RESOURCE_PERMISSION_EDIT
|
||||||
|
.getWorkspacePermissionWorkspaceManageRole,
|
||||||
|
],
|
||||||
|
[],
|
||||||
|
'OR',
|
||||||
|
),
|
||||||
|
})
|
||||||
|
const isKnowledge = computed(() => props.type === SourceTypeEnum.KNOWLEDGE)
|
||||||
|
const isApplication = computed(() => props.type === SourceTypeEnum.APPLICATION)
|
||||||
|
const isTool = computed(() => props.type === SourceTypeEnum.TOOL)
|
||||||
|
const isModel = computed(() => props.type === SourceTypeEnum.MODEL)
|
||||||
|
|
||||||
|
const multipleTableRef = ref()
|
||||||
|
const searchType = ref('name')
|
||||||
|
const searchForm = ref<any>({
|
||||||
|
name: '',
|
||||||
|
permission: undefined,
|
||||||
|
})
|
||||||
|
|
||||||
|
const search_type_change = () => {
|
||||||
|
searchForm.value = { name: '', permission: undefined }
|
||||||
|
}
|
||||||
|
|
||||||
|
const paginationConfig = reactive({
|
||||||
|
current_page: 1,
|
||||||
|
page_size: 20,
|
||||||
|
total: 0,
|
||||||
|
})
|
||||||
|
|
||||||
|
function handleSizeChange() {
|
||||||
|
paginationConfig.current_page = 1
|
||||||
|
if (props.getData) {
|
||||||
|
props.getData()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function searchHandle() {
|
||||||
|
paginationConfig.current_page = 1
|
||||||
|
if (props.getData) {
|
||||||
|
props.getData()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const multipleSelection = ref<any[]>([])
|
||||||
|
|
||||||
|
const handleSelectionChange = (val: any[]) => {
|
||||||
|
multipleSelection.value = val
|
||||||
|
}
|
||||||
|
|
||||||
|
const dialogVisible = ref(false)
|
||||||
|
const radioPermission = ref('')
|
||||||
|
function openMulConfigureDialog() {
|
||||||
|
if (multipleSelection.value.length === 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
dialogVisible.value = true
|
||||||
|
}
|
||||||
|
function submitDialog() {
|
||||||
|
if (multipleSelection.value.length === 0 || !radioPermission.value) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const obj = multipleSelection.value.map((item) => ({
|
||||||
|
target_id: item.id,
|
||||||
|
permission: radioPermission.value,
|
||||||
|
}))
|
||||||
|
emit('submitPermissions', obj)
|
||||||
|
closeDialog()
|
||||||
|
}
|
||||||
|
function closeDialog() {
|
||||||
|
dialogVisible.value = false
|
||||||
|
radioPermission.value = ''
|
||||||
|
multipleSelection.value = []
|
||||||
|
multipleTableRef.value?.clearSelection()
|
||||||
|
}
|
||||||
|
|
||||||
|
function submitPermissions(value: string, row: any) {
|
||||||
|
const obj = [
|
||||||
|
{
|
||||||
|
target_id: row.id,
|
||||||
|
permission: value,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
emit('submitPermissions', obj)
|
||||||
|
}
|
||||||
|
const provider_list = ref<Array<Provider>>([])
|
||||||
|
|
||||||
|
function getProvider() {
|
||||||
|
model.asyncGetProvider().then((res: any) => {
|
||||||
|
provider_list.value = res?.data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const getProviderIcon = computed(() => {
|
||||||
|
return (row: any) => {
|
||||||
|
return provider_list.value.find((p) => p.provider === row.icon)?.icon
|
||||||
|
}
|
||||||
|
})
|
||||||
|
onMounted(() => {
|
||||||
|
if (isModel.value) {
|
||||||
|
getProvider()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
paginationConfig,
|
||||||
|
searchForm,
|
||||||
|
searchType,
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.permission-setting {
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 100%;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
import { AuthorizationEnum } from '@/enums/system'
|
||||||
|
import { t } from '@/locales'
|
||||||
|
import { hasPermission } from '@/utils/permission'
|
||||||
|
import { EditionConst } from '@/utils/permission/data'
|
||||||
|
|
||||||
|
const notCommunity = hasPermission([EditionConst.IS_EE,EditionConst.IS_PE],'OR')
|
||||||
|
|
||||||
|
const permissionOptions = [
|
||||||
|
{
|
||||||
|
label: t('views.system.resourceAuthorization.setting.notAuthorized'),
|
||||||
|
value: AuthorizationEnum.NOT_AUTH,
|
||||||
|
desc: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('views.system.resourceAuthorization.setting.check'),
|
||||||
|
value: AuthorizationEnum.VIEW,
|
||||||
|
desc: t('views.system.resourceAuthorization.setting.checkDesc'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('views.system.resourceAuthorization.setting.management'),
|
||||||
|
value: AuthorizationEnum.MANAGE,
|
||||||
|
desc: t('views.system.resourceAuthorization.setting.managementDesc'),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
if (notCommunity) {
|
||||||
|
permissionOptions.push(
|
||||||
|
{
|
||||||
|
label: t('views.system.resourceAuthorization.setting.role'),
|
||||||
|
value: AuthorizationEnum.ROLE,
|
||||||
|
desc: t('views.system.resourceAuthorization.setting.roleDesc'),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export {permissionOptions}
|
||||||
|
|
@ -21,8 +21,8 @@
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-card style="--el-card-padding: 0">
|
<el-card style="--el-card-padding: 0; height: calc(100vh - 140px)">
|
||||||
<div class="flex main-calc-height">
|
<div class="flex">
|
||||||
<div class="resource-authorization__left border-r">
|
<div class="resource-authorization__left border-r">
|
||||||
<div class="p-24 pb-0">
|
<div class="p-24 pb-0">
|
||||||
<h4 class="mb-12">{{ $t('views.system.resourceAuthorization.member') }}</h4>
|
<h4 class="mb-12">{{ $t('views.system.resourceAuthorization.member') }}</h4>
|
||||||
|
|
@ -45,11 +45,15 @@
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<div class="flex-between">
|
<div class="flex-between">
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<span class="mr-8">{{ row.nick_name }}</span>
|
<span class="mr-8 ellipsis-1" :title="row.nick_name">{{
|
||||||
<TagGroup
|
row.nick_name
|
||||||
:tags="row.roles"
|
}}</span>
|
||||||
|
<el-text
|
||||||
|
class="color-input-placeholder ellipsis-1"
|
||||||
|
:title="row.roles.join(',')"
|
||||||
v-if="hasPermission([EditionConst.IS_EE, EditionConst.IS_PE], 'OR')"
|
v-if="hasPermission([EditionConst.IS_EE, EditionConst.IS_PE], 'OR')"
|
||||||
/>
|
>({{ row.roles?.join(',') }})</el-text
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -58,46 +62,13 @@
|
||||||
</el-scrollbar>
|
</el-scrollbar>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="permission-setting p-24 flex" v-loading="rLoading">
|
<PermissionTable
|
||||||
<div class="resource-authorization__table">
|
:data="permissionData"
|
||||||
<h4 class="mb-16">{{ $t('views.system.resourceAuthorization.permissionSetting') }}</h4>
|
:type="activeData.type"
|
||||||
<!-- <el-tabs
|
ref="PermissionTableRef"
|
||||||
v-model="activeName"
|
:getData="getPermissionList"
|
||||||
@tab-change="handleTabChange"
|
@submitPermissions="submitPermissions"
|
||||||
class="resource-authorization__tabs"
|
/>
|
||||||
>
|
|
||||||
<el-tab-pane
|
|
||||||
v-for="(item, index) in settingTags"
|
|
||||||
:key="item.value"
|
|
||||||
:label="item.label"
|
|
||||||
:name="item.value"
|
|
||||||
> -->
|
|
||||||
<PermissionSetting
|
|
||||||
:data="activeData.data"
|
|
||||||
:type="activeData.type"
|
|
||||||
:tableHeight="tableHeight"
|
|
||||||
:manage="isManage(currentType)"
|
|
||||||
@refreshData="refreshData"
|
|
||||||
v-model:isRole="activeData.isRole"
|
|
||||||
></PermissionSetting>
|
|
||||||
<!-- </el-tab-pane> -->
|
|
||||||
<!-- </el-tabs> -->
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="submit-button">
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
@click="submitPermissions"
|
|
||||||
v-if="
|
|
||||||
hasPermission(
|
|
||||||
permissionObj[(route.meta?.resource as string) || 'APPLICATION'],
|
|
||||||
'OR',
|
|
||||||
)
|
|
||||||
"
|
|
||||||
>{{ $t('common.save') }}</el-button
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -106,19 +77,18 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onMounted, ref, reactive, watch, computed } from 'vue'
|
import { onMounted, ref, reactive, watch, computed } from 'vue'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
import AuthorizationApi from '@/api/system/resource-authorization'
|
import PermissionTable from '@/views/system/resource-authorization/component/PermissionTable.vue'
|
||||||
import PermissionSetting from './component/PermissionSetting.vue'
|
|
||||||
import { MsgSuccess, MsgConfirm } from '@/utils/message'
|
import { MsgSuccess, MsgConfirm } from '@/utils/message'
|
||||||
import { AuthorizationEnum } from '@/enums/system'
|
import { SourceTypeEnum } from '@/enums/common'
|
||||||
import { t } from '@/locales'
|
import { t } from '@/locales'
|
||||||
import useStore from '@/stores'
|
import AuthorizationApi from '@/api/system/resource-authorization'
|
||||||
import { cloneDeep } from 'lodash'
|
import { EditionConst } from '@/utils/permission/data'
|
||||||
import { EditionConst, RoleConst, PermissionConst } from '@/utils/permission/data'
|
|
||||||
import { hasPermission } from '@/utils/permission/index'
|
import { hasPermission } from '@/utils/permission/index'
|
||||||
import type { WorkspaceItem } from '@/api/type/workspace'
|
import type { WorkspaceItem } from '@/api/type/workspace'
|
||||||
import { ComplexPermission } from '@/utils/permission/type'
|
|
||||||
import { loadPermissionApi } from '@/utils/dynamics-api/permission-api.ts'
|
import { loadPermissionApi } from '@/utils/dynamics-api/permission-api.ts'
|
||||||
|
|
||||||
|
import useStore from '@/stores'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const { user } = useStore()
|
const { user } = useStore()
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
|
|
@ -128,79 +98,27 @@ const filterMember = ref<any[]>([]) // 搜索过滤后列表
|
||||||
const currentUser = ref<string>('')
|
const currentUser = ref<string>('')
|
||||||
const currentType = ref<string>('')
|
const currentType = ref<string>('')
|
||||||
const filterText = ref('')
|
const filterText = ref('')
|
||||||
const tableHeight = ref(0)
|
const permissionData = ref<any[]>([])
|
||||||
|
|
||||||
const permissionObj = ref<any>({
|
|
||||||
APPLICATION: new ComplexPermission(
|
|
||||||
[RoleConst.ADMIN, RoleConst.WORKSPACE_MANAGE],
|
|
||||||
[
|
|
||||||
PermissionConst.APPLICATION_WORKSPACE_USER_RESOURCE_PERMISSION_EDIT,
|
|
||||||
PermissionConst.APPLICATION_WORKSPACE_USER_RESOURCE_PERMISSION_EDIT
|
|
||||||
.getWorkspacePermissionWorkspaceManageRole,
|
|
||||||
],
|
|
||||||
[],
|
|
||||||
'OR',
|
|
||||||
),
|
|
||||||
KNOWLEDGE: new ComplexPermission(
|
|
||||||
[RoleConst.ADMIN, RoleConst.WORKSPACE_MANAGE],
|
|
||||||
[
|
|
||||||
PermissionConst.KNOWLEDGE_WORKSPACE_USER_RESOURCE_PERMISSION_EDIT,
|
|
||||||
PermissionConst.KNOWLEDGE_WORKSPACE_USER_RESOURCE_PERMISSION_EDIT
|
|
||||||
.getWorkspacePermissionWorkspaceManageRole,
|
|
||||||
],
|
|
||||||
[],
|
|
||||||
'OR',
|
|
||||||
),
|
|
||||||
TOOL: new ComplexPermission(
|
|
||||||
[RoleConst.ADMIN, RoleConst.WORKSPACE_MANAGE],
|
|
||||||
[
|
|
||||||
PermissionConst.TOOL_WORKSPACE_USER_RESOURCE_PERMISSION_EDIT,
|
|
||||||
PermissionConst.TOOL_WORKSPACE_USER_RESOURCE_PERMISSION_EDIT
|
|
||||||
.getWorkspacePermissionWorkspaceManageRole,
|
|
||||||
],
|
|
||||||
[],
|
|
||||||
'OR',
|
|
||||||
),
|
|
||||||
MODEL: new ComplexPermission(
|
|
||||||
[RoleConst.ADMIN, RoleConst.WORKSPACE_MANAGE],
|
|
||||||
[
|
|
||||||
PermissionConst.MODEL_WORKSPACE_USER_RESOURCE_PERMISSION_EDIT,
|
|
||||||
PermissionConst.MODEL_WORKSPACE_USER_RESOURCE_PERMISSION_EDIT
|
|
||||||
.getWorkspacePermissionWorkspaceManageRole,
|
|
||||||
],
|
|
||||||
[],
|
|
||||||
'OR',
|
|
||||||
),
|
|
||||||
})
|
|
||||||
const settingTags = reactive([
|
const settingTags = reactive([
|
||||||
{
|
{
|
||||||
label: t('views.knowledge.title'),
|
label: t('views.knowledge.title'),
|
||||||
type: AuthorizationEnum.KNOWLEDGE,
|
type: SourceTypeEnum.KNOWLEDGE,
|
||||||
data: [] as any,
|
|
||||||
isRole: false,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('views.application.title'),
|
label: t('views.application.title'),
|
||||||
type: AuthorizationEnum.APPLICATION,
|
type: SourceTypeEnum.APPLICATION,
|
||||||
data: [] as any,
|
|
||||||
isRole: false,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('views.tool.title'),
|
label: t('views.tool.title'),
|
||||||
type: AuthorizationEnum.TOOL,
|
type: SourceTypeEnum.TOOL,
|
||||||
data: [] as any,
|
|
||||||
isRole: false,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('views.model.title'),
|
label: t('views.model.title'),
|
||||||
type: AuthorizationEnum.MODEL,
|
type: SourceTypeEnum.MODEL,
|
||||||
data: [] as any,
|
|
||||||
isRole: false,
|
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
// 当前激活的数据类型(应用/知识库/模型/工具)
|
// 当前激活的数据类型(应用/知识库/模型/工具)
|
||||||
|
|
||||||
const activeData = computed(() => {
|
const activeData = computed(() => {
|
||||||
const lastIndex = route.path.lastIndexOf('/')
|
const lastIndex = route.path.lastIndexOf('/')
|
||||||
const currentPathType = route.path.substring(lastIndex + 1).toUpperCase()
|
const currentPathType = route.path.substring(lastIndex + 1).toUpperCase()
|
||||||
|
|
@ -219,51 +137,46 @@ watch(filterText, (val: any) => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
function isManage(type: string) {
|
function submitPermissions(obj: any) {
|
||||||
return type === 'manage'
|
|
||||||
}
|
|
||||||
|
|
||||||
const flotTree = (tree: Array<any>, result: Array<any>) => {
|
|
||||||
tree.forEach((tItem) => {
|
|
||||||
result.push(tItem)
|
|
||||||
if (tItem.children) {
|
|
||||||
flotTree(tItem.children, result)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
function submitPermissions() {
|
|
||||||
const user_resource_permission_list = settingTags
|
|
||||||
.map((item: any, index: number) => {
|
|
||||||
return flotTree(item.data, [])
|
|
||||||
.filter((v: any) => !v.isFolder)
|
|
||||||
.map((v: any) => {
|
|
||||||
return {
|
|
||||||
target_id: v.id,
|
|
||||||
auth_target_type: item.value,
|
|
||||||
permission: v.permission,
|
|
||||||
auth_type: item.isRole ? 'ROLE' : 'RESOURCE_PERMISSION_GROUP',
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.reduce((pre: any, next: any) => [...pre, ...next], [])
|
|
||||||
const workspaceId = currentWorkspaceId.value || user.getWorkspaceId() || 'default'
|
const workspaceId = currentWorkspaceId.value || user.getWorkspaceId() || 'default'
|
||||||
AuthorizationApi.putResourceAuthorization(
|
AuthorizationApi.putResourceAuthorization(
|
||||||
workspaceId,
|
workspaceId,
|
||||||
currentUser.value,
|
currentUser.value,
|
||||||
(route.meta?.resource as string) || 'APPLICATION',
|
(route.meta?.resource as string) || 'APPLICATION',
|
||||||
{ user_resource_permission_list: user_resource_permission_list },
|
obj,
|
||||||
rLoading,
|
rLoading,
|
||||||
).then(() => {
|
).then(() => {
|
||||||
MsgSuccess(t('common.submitSuccess'))
|
MsgSuccess(t('common.submitSuccess'))
|
||||||
getWholeTree(currentUser.value)
|
getPermissionList()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const PermissionTableRef = ref()
|
||||||
|
|
||||||
|
const getPermissionList = () => {
|
||||||
|
const workspaceId = currentWorkspaceId.value || user.getWorkspaceId() || 'default'
|
||||||
|
const params: any = {}
|
||||||
|
if (PermissionTableRef.value.searchForm[PermissionTableRef.value.searchType]) {
|
||||||
|
params[PermissionTableRef.value.searchType] =
|
||||||
|
PermissionTableRef.value.searchForm[PermissionTableRef.value.searchType]
|
||||||
|
}
|
||||||
|
AuthorizationApi.getResourceAuthorization(
|
||||||
|
workspaceId,
|
||||||
|
currentUser.value,
|
||||||
|
(route.meta?.resource as string) || 'APPLICATION',
|
||||||
|
PermissionTableRef.value.paginationConfig,
|
||||||
|
params,
|
||||||
|
rLoading,
|
||||||
|
).then((res) => {
|
||||||
|
permissionData.value = res.data.records || []
|
||||||
|
PermissionTableRef.value.paginationConfig.total = res.data.total || 0
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function clickMemberHandle(item: any) {
|
function clickMemberHandle(item: any) {
|
||||||
currentUser.value = item.id
|
currentUser.value = item.id
|
||||||
currentType.value = item.type
|
currentType.value = item.type
|
||||||
getWholeTree(item.id)
|
getPermissionList()
|
||||||
}
|
}
|
||||||
|
|
||||||
function getMember(id?: string) {
|
function getMember(id?: string) {
|
||||||
|
|
@ -275,175 +188,13 @@ function getMember(id?: string) {
|
||||||
const member = (id && memberList.value.find((p: any) => p.user_id === id)) || null
|
const member = (id && memberList.value.find((p: any) => p.user_id === id)) || null
|
||||||
currentUser.value = member ? member.id : memberList.value?.[0]?.id
|
currentUser.value = member ? member.id : memberList.value?.[0]?.id
|
||||||
currentType.value = member ? member.type : memberList.value?.[0]?.type
|
currentType.value = member ? member.type : memberList.value?.[0]?.type
|
||||||
getWholeTree(currentUser.value)
|
getPermissionList()
|
||||||
} else {
|
} else {
|
||||||
activeData.value.data = []
|
permissionData.value = []
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const dfsPermissionIndeterminateTrue = (arr: any = [], type: string) => {
|
|
||||||
return arr.every((item: any) => {
|
|
||||||
if (item.children?.length) {
|
|
||||||
item.permission[type] = dfsPermissionIndeterminateTrue(item.children, type)
|
|
||||||
}
|
|
||||||
return item.permission[type]
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const dfsPermissionIndeterminate = (
|
|
||||||
arr: any = [],
|
|
||||||
type: string,
|
|
||||||
permissionHalf: any,
|
|
||||||
permissionHalfMap: any,
|
|
||||||
id: string,
|
|
||||||
) => {
|
|
||||||
arr.forEach((item: any) => {
|
|
||||||
if (item.isFolder) {
|
|
||||||
if (!permissionHalfMap[item.id]) {
|
|
||||||
permissionHalfMap[item.id] = cloneDeep(permissionHalf)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item.children?.length) {
|
|
||||||
dfsPermissionIndeterminate(item.children, type, permissionHalf, permissionHalfMap, item.id)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!item.isFolder) {
|
|
||||||
permissionHalfMap[id][type] = [...permissionHalfMap[id][type], item.permission[type]]
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item.isFolder) {
|
|
||||||
// 判断是否存在子项且全部选中或全部未选中
|
|
||||||
const hasPermissions = permissionHalfMap[item.id][type]
|
|
||||||
const allTrue = hasPermissions.length && hasPermissions.every((p: boolean) => p)
|
|
||||||
const allFalse = hasPermissions.length && hasPermissions.every((p: boolean) => !p)
|
|
||||||
|
|
||||||
// 只有在既有选中又有未选中的情况下才设置为半选状态
|
|
||||||
item.permissionHalf[type] = hasPermissions.length && !allTrue && !allFalse
|
|
||||||
|
|
||||||
// 检查子文件夹是否有半选状态
|
|
||||||
if (item.children.some((ele: any) => ele.isFolder && ele.permissionHalf[type])) {
|
|
||||||
item.permissionHalf[type] = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// 如果所有子项都已选中,确保当前项也被选中而不是半选
|
|
||||||
if (allTrue) {
|
|
||||||
item.permission[type] = true
|
|
||||||
item.permissionHalf[type] = false
|
|
||||||
}
|
|
||||||
|
|
||||||
// 如果子项中有选中的也有未选中的,则设置为半选状态
|
|
||||||
if (
|
|
||||||
item.children.some((ele: any) => ele.permission[type]) &&
|
|
||||||
item.children.some((ele: any) => !ele.permission[type])
|
|
||||||
) {
|
|
||||||
item.permissionHalf[type] = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const dfsFolder = (arr: any[] = [], folderIdMap: any) => {
|
|
||||||
arr.forEach((ele) => {
|
|
||||||
if (ele.permission) return
|
|
||||||
if (ele.children?.length) {
|
|
||||||
if (folderIdMap[ele.id]) {
|
|
||||||
ele.children = [...ele.children, ...folderIdMap[ele.id]]
|
|
||||||
}
|
|
||||||
dfsFolder(ele.children, folderIdMap)
|
|
||||||
} else {
|
|
||||||
ele.children = folderIdMap[ele.id] || []
|
|
||||||
}
|
|
||||||
ele.isFolder = true
|
|
||||||
ele.permission = {
|
|
||||||
VIEW: false,
|
|
||||||
MANAGE: false,
|
|
||||||
ROLE: false,
|
|
||||||
}
|
|
||||||
|
|
||||||
ele.permissionHalf = {
|
|
||||||
VIEW: false,
|
|
||||||
MANAGE: false,
|
|
||||||
ROLE: false,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function getFolder() {
|
|
||||||
const workspaceId = currentWorkspaceId.value || user.getWorkspaceId() || 'default'
|
|
||||||
return AuthorizationApi.getSystemFolder(workspaceId, activeData.value.type, {}, loading)
|
|
||||||
}
|
|
||||||
function getResourcePermissions(user_id: string) {
|
|
||||||
const workspaceId = currentWorkspaceId.value || user.getWorkspaceId() || 'default'
|
|
||||||
return AuthorizationApi.getResourceAuthorization(
|
|
||||||
workspaceId,
|
|
||||||
user_id,
|
|
||||||
(route.meta?.resource as string) || 'APPLICATION',
|
|
||||||
rLoading,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
const getWholeTree = async (user_id: string) => {
|
|
||||||
const [parentRes, childrenRes] = await Promise.all([getFolder(), getResourcePermissions(user_id)])
|
|
||||||
// if (!childrenRes.data || Object.keys(childrenRes.data).length > 0) {
|
|
||||||
// settingTags.map((item: any) => {
|
|
||||||
let folderIdMap = []
|
|
||||||
const folderTree = cloneDeep((parentRes as unknown as any).data)
|
|
||||||
if (Object.keys(childrenRes.data).indexOf(activeData.value.type) !== -1) {
|
|
||||||
activeData.value.isRole =
|
|
||||||
childrenRes.data[activeData.value.type].length > 0 &&
|
|
||||||
hasPermission([EditionConst.IS_EE, EditionConst.IS_PE], 'OR')
|
|
||||||
? childrenRes.data[activeData.value.type][0].auth_type == 'ROLE'
|
|
||||||
: false
|
|
||||||
folderIdMap = getFolderIdMap(childrenRes.data[activeData.value.type])
|
|
||||||
dfsFolder(folderTree, folderIdMap)
|
|
||||||
const permissionHalf = {
|
|
||||||
VIEW: [],
|
|
||||||
MANAGE: [],
|
|
||||||
ROLE: [],
|
|
||||||
}
|
|
||||||
Object.keys(permissionHalf).forEach((ele) => {
|
|
||||||
dfsPermissionIndeterminateTrue(folderTree, ele)
|
|
||||||
dfsPermissionIndeterminate(folderTree, ele, cloneDeep(permissionHalf), {}, 'default')
|
|
||||||
})
|
|
||||||
if (activeData.value.type === AuthorizationEnum.MODEL) {
|
|
||||||
activeData.value.data = folderTree[0].children
|
|
||||||
} else {
|
|
||||||
activeData.value.data = folderTree
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
activeData.value.data = []
|
|
||||||
}
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
const refreshData = () => {
|
|
||||||
settingTags.map((item: any) => {
|
|
||||||
if (activeData.value.type === item.type) {
|
|
||||||
const permissionHalf = {
|
|
||||||
VIEW: [],
|
|
||||||
MANAGE: [],
|
|
||||||
ROLE: [],
|
|
||||||
}
|
|
||||||
Object.keys(permissionHalf).forEach((ele) => {
|
|
||||||
dfsPermissionIndeterminateTrue(item.data, ele)
|
|
||||||
dfsPermissionIndeterminate(item.data, ele, cloneDeep(permissionHalf), {}, 'default')
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
const getFolderIdMap = (arr: any = []) => {
|
|
||||||
return arr.reduce((pre: any, next: any) => {
|
|
||||||
if (pre[next.folder_id]) {
|
|
||||||
pre[next.folder_id].push(next)
|
|
||||||
} else {
|
|
||||||
pre[next.folder_id] = [next]
|
|
||||||
}
|
|
||||||
return pre
|
|
||||||
}, {})
|
|
||||||
}
|
|
||||||
|
|
||||||
const workspaceList = ref<WorkspaceItem[]>([])
|
const workspaceList = ref<WorkspaceItem[]>([])
|
||||||
const currentWorkspaceId = ref<string | undefined>('')
|
const currentWorkspaceId = ref<string | undefined>('')
|
||||||
const currentWorkspace = computed(() => {
|
const currentWorkspace = computed(() => {
|
||||||
|
|
@ -461,12 +212,6 @@ function changeWorkspace(item: WorkspaceItem) {
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
tableHeight.value = window.innerHeight - 300
|
|
||||||
window.onresize = () => {
|
|
||||||
return (() => {
|
|
||||||
tableHeight.value = window.innerHeight - 300
|
|
||||||
})()
|
|
||||||
}
|
|
||||||
if (user.isEE()) {
|
if (user.isEE()) {
|
||||||
getWorkspaceList()
|
getWorkspaceList()
|
||||||
}
|
}
|
||||||
|
|
@ -481,20 +226,6 @@ onMounted(() => {
|
||||||
width: var(--setting-left-width);
|
width: var(--setting-left-width);
|
||||||
min-width: var(--setting-left-width);
|
min-width: var(--setting-left-width);
|
||||||
}
|
}
|
||||||
|
|
||||||
.permission-setting {
|
|
||||||
flex: 1;
|
|
||||||
overflow: hidden;
|
|
||||||
box-sizing: border-box;
|
|
||||||
width: 100%;
|
|
||||||
flex-direction: column;
|
|
||||||
position: relative;
|
|
||||||
.submit-button {
|
|
||||||
position: absolute;
|
|
||||||
top: 24px;
|
|
||||||
right: 24px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.list-height-left {
|
.list-height-left {
|
||||||
height: calc(100vh - 240px);
|
height: calc(100vh - 240px);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -250,6 +250,16 @@
|
||||||
<AppIcon iconName="app-operation" class="color-secondary"></AppIcon>
|
<AppIcon iconName="app-operation" class="color-secondary"></AppIcon>
|
||||||
{{ $t('common.param.initParam') }}
|
{{ $t('common.param.initParam') }}
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
|
<el-dropdown-item
|
||||||
|
@click.stop="openAuthorization(item)"
|
||||||
|
v-if="apiType === 'workspace' && permissionPrecise.auth(item.id)"
|
||||||
|
>
|
||||||
|
<AppIcon
|
||||||
|
iconName="app-resource-authorization"
|
||||||
|
class="color-secondary"
|
||||||
|
></AppIcon>
|
||||||
|
{{ $t('views.system.resourceAuthorization.title') }}
|
||||||
|
</el-dropdown-item>
|
||||||
<el-dropdown-item
|
<el-dropdown-item
|
||||||
@click.stop="openMoveToDialog(item)"
|
@click.stop="openMoveToDialog(item)"
|
||||||
v-if="permissionPrecise.copy(item.id) && apiType === 'workspace'"
|
v-if="permissionPrecise.copy(item.id) && apiType === 'workspace'"
|
||||||
|
|
@ -308,6 +318,11 @@
|
||||||
@refresh="refreshToolList"
|
@refresh="refreshToolList"
|
||||||
v-if="apiType === 'workspace'"
|
v-if="apiType === 'workspace'"
|
||||||
/>
|
/>
|
||||||
|
<ResourceAuthorizationDrawer
|
||||||
|
:type="SourceTypeEnum.TOOL"
|
||||||
|
ref="ResourceAuthorizationDrawerRef"
|
||||||
|
v-if="apiType === 'workspace'"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
|
@ -322,6 +337,7 @@ import AuthorizedWorkspace from '@/views/system-shared/AuthorizedWorkspaceDialog
|
||||||
import ToolStoreDialog from '@/views/tool/toolStore/ToolStoreDialog.vue'
|
import ToolStoreDialog from '@/views/tool/toolStore/ToolStoreDialog.vue'
|
||||||
import AddInternalToolDialog from '@/views/tool/toolStore/AddInternalToolDialog.vue'
|
import AddInternalToolDialog from '@/views/tool/toolStore/AddInternalToolDialog.vue'
|
||||||
import MoveToDialog from '@/components/folder-tree/MoveToDialog.vue'
|
import MoveToDialog from '@/components/folder-tree/MoveToDialog.vue'
|
||||||
|
import ResourceAuthorizationDrawer from '@/components/resource-authorization-drawer/index.vue'
|
||||||
import { resetUrl } from '@/utils/common'
|
import { resetUrl } from '@/utils/common'
|
||||||
import { MsgSuccess, MsgConfirm, MsgError } from '@/utils/message'
|
import { MsgSuccess, MsgConfirm, MsgError } from '@/utils/message'
|
||||||
import { SourceTypeEnum } from '@/enums/common'
|
import { SourceTypeEnum } from '@/enums/common'
|
||||||
|
|
@ -366,6 +382,11 @@ const MoreFieldPermission = (id: any) => {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ResourceAuthorizationDrawerRef = ref()
|
||||||
|
function openAuthorization(item: any) {
|
||||||
|
ResourceAuthorizationDrawerRef.value.open(item.id)
|
||||||
|
}
|
||||||
|
|
||||||
const InitParamDrawerRef = ref()
|
const InitParamDrawerRef = ref()
|
||||||
const search_type = ref('name')
|
const search_type = ref('name')
|
||||||
const search_form = ref<any>({
|
const search_form = ref<any>({
|
||||||
|
|
|
||||||
|
|
@ -147,13 +147,14 @@ import NodeContainer from '@/workflow/common/NodeContainer.vue'
|
||||||
import AddFormCollect from '@/workflow/common/AddFormCollect.vue'
|
import AddFormCollect from '@/workflow/common/AddFormCollect.vue'
|
||||||
import EditFormCollect from '@/workflow/common/EditFormCollect.vue'
|
import EditFormCollect from '@/workflow/common/EditFormCollect.vue'
|
||||||
import { type FormInstance } from 'element-plus'
|
import { type FormInstance } from 'element-plus'
|
||||||
import { ref, onMounted, computed } from 'vue'
|
import { ref, onMounted, computed, provide } from 'vue'
|
||||||
import { input_type_list } from '@/components/dynamics-form/constructor/data'
|
import { input_type_list } from '@/components/dynamics-form/constructor/data'
|
||||||
import { MsgError } from '@/utils/message'
|
import { MsgError } from '@/utils/message'
|
||||||
import { set, cloneDeep } from 'lodash'
|
import { set, cloneDeep } from 'lodash'
|
||||||
import Sortable from 'sortablejs'
|
import Sortable from 'sortablejs'
|
||||||
import { t } from '@/locales'
|
import { t } from '@/locales'
|
||||||
const props = defineProps<{ nodeModel: any }>()
|
const props = defineProps<{ nodeModel: any }>()
|
||||||
|
provide('getModel', () => props.nodeModel)
|
||||||
const formNodeFormRef = ref<FormInstance>()
|
const formNodeFormRef = ref<FormInstance>()
|
||||||
const tableRef = ref()
|
const tableRef = ref()
|
||||||
const editFormField = (form_field_data: any, field_index: number) => {
|
const editFormField = (form_field_data: any, field_index: number) => {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue