fix: 修复管理端前端类型校验问题
- 修正知识库与 Bot 设置页相关组件的类型定义和空值处理 - 补齐工作流与公开聊天页的前端类型约束和动态导入类型 - 收敛本次改动文件的局部格式与样式规范,确保 pnpm check:type 通过
This commit is contained in:
@@ -1,9 +1,11 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {computed} from 'vue';
|
import type { TagProps } from 'element-plus';
|
||||||
|
|
||||||
import {useAccess} from '@easyflow/access';
|
import { computed } from 'vue';
|
||||||
|
|
||||||
import {MoreFilled} from '@element-plus/icons-vue';
|
import { useAccess } from '@easyflow/access';
|
||||||
|
|
||||||
|
import { MoreFilled } from '@element-plus/icons-vue';
|
||||||
import {
|
import {
|
||||||
ElAvatar,
|
ElAvatar,
|
||||||
ElButton,
|
ElButton,
|
||||||
@@ -48,7 +50,7 @@ export interface CardListProps {
|
|||||||
actions?: ActionButton[];
|
actions?: ActionButton[];
|
||||||
cornerTagField?: string;
|
cornerTagField?: string;
|
||||||
cornerTagMap?: Record<string, string>;
|
cornerTagMap?: Record<string, string>;
|
||||||
cornerTagTypeMap?: Record<string, string>;
|
cornerTagTypeMap?: Record<string, TagProps['type']>;
|
||||||
defaultIcon: any;
|
defaultIcon: any;
|
||||||
data: any[];
|
data: any[];
|
||||||
primaryAction?: CardPrimaryAction;
|
primaryAction?: CardPrimaryAction;
|
||||||
@@ -97,7 +99,9 @@ const resolvedActions = computed<ResolvedActionButton[]>(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const inlineActions = computed(() => {
|
const inlineActions = computed(() => {
|
||||||
return resolvedActions.value.filter((action) => action.placement === 'inline');
|
return resolvedActions.value.filter(
|
||||||
|
(action) => action.placement === 'inline',
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
const menuActions = computed(() => {
|
const menuActions = computed(() => {
|
||||||
@@ -128,7 +132,10 @@ function handleActionClick(event: Event, action: ActionButton, item: any) {
|
|||||||
v-for="(item, index) in props.data"
|
v-for="(item, index) in props.data"
|
||||||
:key="item.id ?? index"
|
:key="item.id ?? index"
|
||||||
shadow="never"
|
shadow="never"
|
||||||
:class="['card-item', { 'card-item--interactive': resolvedPrimaryAction }]"
|
:class="[
|
||||||
|
'card-item',
|
||||||
|
{ 'card-item--interactive': resolvedPrimaryAction },
|
||||||
|
]"
|
||||||
:role="resolvedPrimaryAction ? 'button' : undefined"
|
:role="resolvedPrimaryAction ? 'button' : undefined"
|
||||||
:tabindex="resolvedPrimaryAction ? 0 : undefined"
|
:tabindex="resolvedPrimaryAction ? 0 : undefined"
|
||||||
@click="handlePrimaryAction(item)"
|
@click="handlePrimaryAction(item)"
|
||||||
@@ -171,9 +178,7 @@ function handleActionClick(event: Event, action: ActionButton, item: any) {
|
|||||||
:type="cornerTagTypeMap[item[cornerTagField]] || 'info'"
|
:type="cornerTagTypeMap[item[cornerTagField]] || 'info'"
|
||||||
round
|
round
|
||||||
>
|
>
|
||||||
{{
|
{{ cornerTagMap[item[cornerTagField]] || item[cornerTagField] }}
|
||||||
cornerTagMap[item[cornerTagField]] || item[cornerTagField]
|
|
||||||
}}
|
|
||||||
</ElTag>
|
</ElTag>
|
||||||
</slot>
|
</slot>
|
||||||
</div>
|
</div>
|
||||||
@@ -232,7 +237,9 @@ function handleActionClick(event: Event, action: ActionButton, item: any) {
|
|||||||
<ElDropdownItem
|
<ElDropdownItem
|
||||||
v-for="action in menuActions"
|
v-for="action in menuActions"
|
||||||
:key="action.text"
|
:key="action.text"
|
||||||
:class="{ 'card-menu-item--danger': action.tone === 'danger' }"
|
:class="{
|
||||||
|
'card-menu-item--danger': action.tone === 'danger',
|
||||||
|
}"
|
||||||
@click="action.onClick(item)"
|
@click="action.onClick(item)"
|
||||||
>
|
>
|
||||||
<div class="menu-action-content">
|
<div class="menu-action-content">
|
||||||
|
|||||||
@@ -77,10 +77,10 @@ const props = defineProps({
|
|||||||
const emit = defineEmits(['update:modelValue', 'change', 'check']);
|
const emit = defineEmits(['update:modelValue', 'change', 'check']);
|
||||||
|
|
||||||
// 响应式数据
|
// 响应式数据
|
||||||
const treeData = ref([]);
|
const treeData = ref<any[]>([]);
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const treeRef = ref<TreeV2Instance>();
|
const treeRef = ref<TreeV2Instance>();
|
||||||
const nodeMap = ref(new Map()); // 用于存储节点键到节点数据的映射
|
const nodeMap = ref<Map<any, any>>(new Map()); // 用于存储节点键到节点数据的映射
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
[() => props.modelValue, () => treeData.value],
|
[() => props.modelValue, () => treeData.value],
|
||||||
@@ -253,12 +253,12 @@ onMounted(() => {
|
|||||||
.tree-select {
|
.tree-select {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background:
|
background: linear-gradient(
|
||||||
linear-gradient(
|
180deg,
|
||||||
180deg,
|
color-mix(in srgb, var(--el-color-primary-light-9) 32%, var(--el-bg-color))
|
||||||
color-mix(in srgb, var(--el-color-primary-light-9) 32%, var(--el-bg-color)) 0%,
|
0%,
|
||||||
var(--el-bg-color) 72%
|
var(--el-bg-color) 72%
|
||||||
);
|
);
|
||||||
border: 1px solid var(--el-border-color-lighter);
|
border: 1px solid var(--el-border-color-lighter);
|
||||||
border-radius: 14px;
|
border-radius: 14px;
|
||||||
box-shadow: var(--el-box-shadow-lighter);
|
box-shadow: var(--el-box-shadow-lighter);
|
||||||
@@ -269,12 +269,11 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.tree-select--disabled {
|
.tree-select--disabled {
|
||||||
background:
|
background: linear-gradient(
|
||||||
linear-gradient(
|
180deg,
|
||||||
180deg,
|
var(--el-fill-color-extra-light) 0%,
|
||||||
var(--el-fill-color-extra-light) 0%,
|
var(--el-fill-color-blank) 72%
|
||||||
var(--el-fill-color-blank) 72%
|
);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.tree-node {
|
.tree-node {
|
||||||
|
|||||||
@@ -140,10 +140,10 @@
|
|||||||
"imageUploadFailed": "Image upload failed",
|
"imageUploadFailed": "Image upload failed",
|
||||||
"import": {
|
"import": {
|
||||||
"title": "Import FAQ",
|
"title": "Import FAQ",
|
||||||
"uploadTitle": "Drop Excel file here or click to upload",
|
"uploadTitle": "Drop Excel file here or click to upload",
|
||||||
"uploadDesc": "Only .xlsx/.xls files are supported, max 5000 rows in first sheet",
|
"uploadDesc": "Only .xlsx/.xls files are supported, max 5000 rows in first sheet",
|
||||||
"moreActions": "More Actions",
|
"moreActions": "More Actions",
|
||||||
"downloadTemplate": "Download Template",
|
"downloadTemplate": "Download Template",
|
||||||
"startImport": "Start Import",
|
"startImport": "Start Import",
|
||||||
"importFinished": "Import completed",
|
"importFinished": "Import completed",
|
||||||
"resultTitle": "Import Result",
|
"resultTitle": "Import Result",
|
||||||
|
|||||||
@@ -140,10 +140,10 @@
|
|||||||
"imageUploadFailed": "图片上传失败",
|
"imageUploadFailed": "图片上传失败",
|
||||||
"import": {
|
"import": {
|
||||||
"title": "导入FAQ",
|
"title": "导入FAQ",
|
||||||
"uploadTitle": "将 Excel 文件拖拽到此处,或点击上传",
|
"uploadTitle": "将 Excel 文件拖拽到此处,或点击上传",
|
||||||
"uploadDesc": "仅支持 .xlsx/.xls,首个工作表最多5000条",
|
"uploadDesc": "仅支持 .xlsx/.xls,首个工作表最多5000条",
|
||||||
"moreActions": "更多操作",
|
"moreActions": "更多操作",
|
||||||
"downloadTemplate": "下载导入模板",
|
"downloadTemplate": "下载导入模板",
|
||||||
"startImport": "开始导入",
|
"startImport": "开始导入",
|
||||||
"importFinished": "导入完成",
|
"importFinished": "导入完成",
|
||||||
"resultTitle": "导入结果",
|
"resultTitle": "导入结果",
|
||||||
|
|||||||
@@ -1689,9 +1689,9 @@ const handleBasicInfoChange = async (
|
|||||||
|
|
||||||
.publish-external-item {
|
.publish-external-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
min-width: 0;
|
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
|
min-width: 0;
|
||||||
padding: 12px;
|
padding: 12px;
|
||||||
background: var(--el-bg-color);
|
background: var(--el-bg-color);
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
@@ -1740,24 +1740,23 @@ const handleBasicInfoChange = async (
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
max-height: 180px;
|
max-height: 180px;
|
||||||
margin: 0;
|
|
||||||
overflow-x: auto;
|
|
||||||
overflow-y: auto;
|
|
||||||
padding: 10px 12px;
|
padding: 10px 12px;
|
||||||
|
margin: 0;
|
||||||
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.publish-external-code-block code {
|
.publish-external-code-block code {
|
||||||
display: block;
|
display: block;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
white-space: pre-wrap;
|
|
||||||
word-break: break-word;
|
|
||||||
overflow-wrap: anywhere;
|
|
||||||
font-family:
|
font-family:
|
||||||
ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono',
|
ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono',
|
||||||
'Courier New', monospace;
|
'Courier New', monospace;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
line-height: 1.6;
|
line-height: 1.6;
|
||||||
color: #d8e1f0;
|
color: #d8e1f0;
|
||||||
|
word-break: normal;
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
white-space: pre-wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.publish-external-code-block code .hljs-tag,
|
.publish-external-code-block code .hljs-tag,
|
||||||
@@ -1861,11 +1860,11 @@ const handleBasicInfoChange = async (
|
|||||||
.bot-avatar-label,
|
.bot-avatar-label,
|
||||||
.bot-basic-form-label {
|
.bot-basic-form-label {
|
||||||
flex: 0 0 60px;
|
flex: 0 0 60px;
|
||||||
|
padding-right: 16px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
color: var(--el-text-color-primary);
|
color: var(--el-text-color-primary);
|
||||||
text-align: left;
|
text-align: left;
|
||||||
padding-right: 16px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.bot-avatar-upload-wrap {
|
.bot-avatar-upload-wrap {
|
||||||
@@ -1884,8 +1883,8 @@ const handleBasicInfoChange = async (
|
|||||||
.bot-avatar-upload-wrap :deep(.avatar-uploader .avatar) {
|
.bot-avatar-upload-wrap :deep(.avatar-uploader .avatar) {
|
||||||
width: 50px;
|
width: 50px;
|
||||||
height: 50px;
|
height: 50px;
|
||||||
border-radius: 50%;
|
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
|
border-radius: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bot-avatar-upload-wrap :deep(.el-icon.avatar-uploader-icon) {
|
.bot-avatar-upload-wrap :deep(.el-icon.avatar-uploader-icon) {
|
||||||
@@ -1911,20 +1910,20 @@ const handleBasicInfoChange = async (
|
|||||||
|
|
||||||
.knowledge-binding-item {
|
.knowledge-binding-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
gap: 16px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
gap: 16px;
|
|
||||||
padding: 12px;
|
padding: 12px;
|
||||||
border-radius: 8px;
|
|
||||||
background-color: hsl(var(--background));
|
background-color: hsl(var(--background));
|
||||||
|
border-radius: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.knowledge-binding-main {
|
.knowledge-binding-main {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
|
||||||
gap: 10px;
|
|
||||||
min-width: 0;
|
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
gap: 10px;
|
||||||
|
align-items: center;
|
||||||
|
min-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.knowledge-binding-content {
|
.knowledge-binding-content {
|
||||||
@@ -1939,18 +1938,18 @@ const handleBasicInfoChange = async (
|
|||||||
}
|
}
|
||||||
|
|
||||||
.knowledge-binding-description {
|
.knowledge-binding-description {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
line-height: 20px;
|
line-height: 20px;
|
||||||
color: var(--el-text-color-secondary);
|
color: var(--el-text-color-secondary);
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.knowledge-binding-actions {
|
.knowledge-binding-actions {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.knowledge-binding-select {
|
.knowledge-binding-select {
|
||||||
|
|||||||
@@ -219,9 +219,9 @@ async function save() {
|
|||||||
<ElIcon
|
<ElIcon
|
||||||
style="
|
style="
|
||||||
margin-left: 4px;
|
margin-left: 4px;
|
||||||
|
font-size: 14px;
|
||||||
color: #909399;
|
color: #909399;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: 14px;
|
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<InfoFilled />
|
<InfoFilled />
|
||||||
@@ -258,9 +258,9 @@ async function save() {
|
|||||||
<ElIcon
|
<ElIcon
|
||||||
style="
|
style="
|
||||||
margin-left: 4px;
|
margin-left: 4px;
|
||||||
|
font-size: 14px;
|
||||||
color: #909399;
|
color: #909399;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: 14px;
|
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<InfoFilled />
|
<InfoFilled />
|
||||||
|
|||||||
@@ -301,9 +301,9 @@ defineExpose({
|
|||||||
<ElIcon
|
<ElIcon
|
||||||
style="
|
style="
|
||||||
margin-left: 4px;
|
margin-left: 4px;
|
||||||
|
font-size: 14px;
|
||||||
color: #909399;
|
color: #909399;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: 14px;
|
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<InfoFilled />
|
<InfoFilled />
|
||||||
@@ -340,9 +340,9 @@ defineExpose({
|
|||||||
<ElIcon
|
<ElIcon
|
||||||
style="
|
style="
|
||||||
margin-left: 4px;
|
margin-left: 4px;
|
||||||
|
font-size: 14px;
|
||||||
color: #909399;
|
color: #909399;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: 14px;
|
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<InfoFilled />
|
<InfoFilled />
|
||||||
|
|||||||
@@ -96,26 +96,27 @@ const handleSearch = () => {
|
|||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.search-container {
|
.search-container {
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
padding: 0 0 20px 0;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
padding: 0 0 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-input {
|
.search-input {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
gap: 12px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.retrieval-select {
|
.retrieval-select {
|
||||||
width: 180px;
|
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
width: 180px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-result {
|
.search-result {
|
||||||
padding-top: 20px;
|
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
padding-top: 20px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -168,18 +168,17 @@ const submitConfig = () => {
|
|||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.search-config-sidebar {
|
.search-config-sidebar {
|
||||||
|
box-sizing: border-box;
|
||||||
width: 60%;
|
width: 60%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
box-sizing: border-box;
|
overflow: hidden auto;
|
||||||
overflow-y: auto;
|
|
||||||
overflow-x: hidden;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.config-header {
|
.config-header {
|
||||||
|
padding-bottom: 8px;
|
||||||
margin-bottom: 16px;
|
margin-bottom: 16px;
|
||||||
border-bottom: 1px solid #e6e6e6;
|
border-bottom: 1px solid #e6e6e6;
|
||||||
padding-bottom: 8px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.config-header h3 {
|
.config-header h3 {
|
||||||
@@ -200,19 +199,19 @@ const submitConfig = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.form-item {
|
.form-item {
|
||||||
margin-bottom: 20px;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-item-label {
|
.form-item-label {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
|
||||||
gap: 4px;
|
gap: 4px;
|
||||||
|
align-items: center;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: #606266;
|
|
||||||
line-height: 1.4;
|
line-height: 1.4;
|
||||||
|
color: #606266;
|
||||||
}
|
}
|
||||||
|
|
||||||
.label-tooltip {
|
.label-tooltip {
|
||||||
@@ -227,8 +226,8 @@ const submitConfig = () => {
|
|||||||
|
|
||||||
.form-item-content {
|
.form-item-content {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
|
align-items: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin-top: 4px;
|
margin-top: 4px;
|
||||||
}
|
}
|
||||||
@@ -240,19 +239,19 @@ const submitConfig = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.switch-control {
|
.switch-control {
|
||||||
width: auto;
|
|
||||||
flex: none;
|
flex: none;
|
||||||
|
width: auto;
|
||||||
min-width: 80px;
|
min-width: 80px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.info-icon {
|
.info-icon {
|
||||||
|
flex: none;
|
||||||
|
flex-shrink: 0;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: #909399;
|
color: #909399;
|
||||||
cursor: help;
|
cursor: help;
|
||||||
width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
flex-shrink: 0;
|
|
||||||
flex: none;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.info-icon:hover {
|
.info-icon:hover {
|
||||||
@@ -278,8 +277,8 @@ const submitConfig = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
:deep(.el-form-item__content) {
|
:deep(.el-form-item__content) {
|
||||||
width: 100%;
|
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.el-slider) {
|
:deep(.el-slider) {
|
||||||
|
|||||||
@@ -83,21 +83,32 @@ const mdLevels = [1, 2, 3, 4, 5, 6];
|
|||||||
|
|
||||||
const formMap = reactive<Record<string, StrategyConfig>>({});
|
const formMap = reactive<Record<string, StrategyConfig>>({});
|
||||||
|
|
||||||
|
function createDefaultStrategyConfig(item?: AnalyzeItem): StrategyConfig {
|
||||||
|
return {
|
||||||
|
chunkSize: item?.strategyConfig?.chunkSize ?? 512,
|
||||||
|
mdSplitterLevel: item?.strategyConfig?.mdSplitterLevel ?? 2,
|
||||||
|
overlapSize: item?.strategyConfig?.overlapSize ?? 128,
|
||||||
|
regex: item?.strategyConfig?.regex ?? '',
|
||||||
|
rowsPerChunk: item?.strategyConfig?.rowsPerChunk ?? 1,
|
||||||
|
strategyCode:
|
||||||
|
item?.strategyConfig?.strategyCode ||
|
||||||
|
item?.analysis?.recommendedStrategyCode ||
|
||||||
|
'AUTO',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function getStrategyForm(filePath: string, item?: AnalyzeItem): StrategyConfig {
|
||||||
|
if (!formMap[filePath]) {
|
||||||
|
formMap[filePath] = createDefaultStrategyConfig(item);
|
||||||
|
}
|
||||||
|
return formMap[filePath]!;
|
||||||
|
}
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.analysisItems,
|
() => props.analysisItems,
|
||||||
(items) => {
|
(items) => {
|
||||||
for (const item of items || []) {
|
for (const item of items || []) {
|
||||||
formMap[item.filePath] = {
|
formMap[item.filePath] = createDefaultStrategyConfig(item);
|
||||||
chunkSize: item.strategyConfig?.chunkSize ?? 512,
|
|
||||||
mdSplitterLevel: item.strategyConfig?.mdSplitterLevel ?? 2,
|
|
||||||
overlapSize: item.strategyConfig?.overlapSize ?? 128,
|
|
||||||
regex: item.strategyConfig?.regex ?? '',
|
|
||||||
rowsPerChunk: item.strategyConfig?.rowsPerChunk ?? 1,
|
|
||||||
strategyCode:
|
|
||||||
item.strategyConfig?.strategyCode ||
|
|
||||||
item.analysis?.recommendedStrategyCode ||
|
|
||||||
'AUTO',
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ immediate: true },
|
{ immediate: true },
|
||||||
@@ -111,7 +122,7 @@ defineExpose({
|
|||||||
fileName: item.fileName,
|
fileName: item.fileName,
|
||||||
filePath: item.filePath,
|
filePath: item.filePath,
|
||||||
strategyConfig: {
|
strategyConfig: {
|
||||||
...formMap[item.filePath],
|
...getStrategyForm(item.filePath, item),
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
@@ -199,7 +210,7 @@ function showLengthSettings(strategyCode?: string) {
|
|||||||
|
|
||||||
<ElCol :span="12">
|
<ElCol :span="12">
|
||||||
<ElForm
|
<ElForm
|
||||||
:model="formMap[item.filePath]"
|
:model="getStrategyForm(item.filePath, item)"
|
||||||
label-position="top"
|
label-position="top"
|
||||||
class="strategy-form"
|
class="strategy-form"
|
||||||
>
|
>
|
||||||
@@ -207,7 +218,7 @@ function showLengthSettings(strategyCode?: string) {
|
|||||||
:label="$t('documentCollection.importDoc.strategySelection')"
|
:label="$t('documentCollection.importDoc.strategySelection')"
|
||||||
>
|
>
|
||||||
<ElSelect
|
<ElSelect
|
||||||
v-model="formMap[item.filePath].strategyCode"
|
v-model="getStrategyForm(item.filePath, item).strategyCode"
|
||||||
class="w-full"
|
class="w-full"
|
||||||
>
|
>
|
||||||
<ElOption
|
<ElOption
|
||||||
@@ -220,11 +231,15 @@ function showLengthSettings(strategyCode?: string) {
|
|||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
|
|
||||||
<ElFormItem
|
<ElFormItem
|
||||||
v-if="showLengthSettings(formMap[item.filePath].strategyCode)"
|
v-if="
|
||||||
|
showLengthSettings(
|
||||||
|
getStrategyForm(item.filePath, item).strategyCode,
|
||||||
|
)
|
||||||
|
"
|
||||||
:label="$t('documentCollection.splitterDoc.chunkSize')"
|
:label="$t('documentCollection.splitterDoc.chunkSize')"
|
||||||
>
|
>
|
||||||
<ElSlider
|
<ElSlider
|
||||||
v-model="formMap[item.filePath].chunkSize"
|
v-model="getStrategyForm(item.filePath, item).chunkSize"
|
||||||
:max="2048"
|
:max="2048"
|
||||||
:min="128"
|
:min="128"
|
||||||
show-input
|
show-input
|
||||||
@@ -233,13 +248,14 @@ function showLengthSettings(strategyCode?: string) {
|
|||||||
|
|
||||||
<ElFormItem
|
<ElFormItem
|
||||||
v-if="
|
v-if="
|
||||||
formMap[item.filePath].strategyCode === 'PARAGRAPH_LENGTH' ||
|
getStrategyForm(item.filePath, item).strategyCode ===
|
||||||
formMap[item.filePath].strategyCode === 'AUTO'
|
'PARAGRAPH_LENGTH' ||
|
||||||
|
getStrategyForm(item.filePath, item).strategyCode === 'AUTO'
|
||||||
"
|
"
|
||||||
:label="$t('documentCollection.splitterDoc.overlapSize')"
|
:label="$t('documentCollection.splitterDoc.overlapSize')"
|
||||||
>
|
>
|
||||||
<ElSlider
|
<ElSlider
|
||||||
v-model="formMap[item.filePath].overlapSize"
|
v-model="getStrategyForm(item.filePath, item).overlapSize"
|
||||||
:max="512"
|
:max="512"
|
||||||
:min="0"
|
:min="0"
|
||||||
show-input
|
show-input
|
||||||
@@ -248,12 +264,13 @@ function showLengthSettings(strategyCode?: string) {
|
|||||||
|
|
||||||
<ElFormItem
|
<ElFormItem
|
||||||
v-if="
|
v-if="
|
||||||
formMap[item.filePath].strategyCode === 'MARKDOWN_SECTION'
|
getStrategyForm(item.filePath, item).strategyCode ===
|
||||||
|
'MARKDOWN_SECTION'
|
||||||
"
|
"
|
||||||
:label="$t('documentCollection.splitterDoc.mdSplitterLevel')"
|
:label="$t('documentCollection.splitterDoc.mdSplitterLevel')"
|
||||||
>
|
>
|
||||||
<ElSelect
|
<ElSelect
|
||||||
v-model="formMap[item.filePath].mdSplitterLevel"
|
v-model="getStrategyForm(item.filePath, item).mdSplitterLevel"
|
||||||
class="w-full"
|
class="w-full"
|
||||||
>
|
>
|
||||||
<ElOption
|
<ElOption
|
||||||
@@ -266,10 +283,13 @@ function showLengthSettings(strategyCode?: string) {
|
|||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
|
|
||||||
<ElFormItem
|
<ElFormItem
|
||||||
v-if="formMap[item.filePath].strategyCode === 'CUSTOM_REGEX'"
|
v-if="
|
||||||
|
getStrategyForm(item.filePath, item).strategyCode ===
|
||||||
|
'CUSTOM_REGEX'
|
||||||
|
"
|
||||||
:label="$t('documentCollection.splitterDoc.regex')"
|
:label="$t('documentCollection.splitterDoc.regex')"
|
||||||
>
|
>
|
||||||
<ElInput v-model="formMap[item.filePath].regex" />
|
<ElInput v-model="getStrategyForm(item.filePath, item).regex" />
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
</ElForm>
|
</ElForm>
|
||||||
</ElCol>
|
</ElCol>
|
||||||
|
|||||||
@@ -503,23 +503,24 @@ const handleToggleVisibleChecked = (checked: boolean | number | string) => {
|
|||||||
checkedModelIds.value = [...next];
|
checkedModelIds.value = [...next];
|
||||||
};
|
};
|
||||||
|
|
||||||
const handlePublishToggle = async (nextValue: boolean) => {
|
const handlePublishToggle = async (nextValue: string | number | boolean) => {
|
||||||
if (!draft.id || !selectedModel.value || isPublishing.value) {
|
if (!draft.id || !selectedModel.value || isPublishing.value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const publishEnabled = Boolean(nextValue);
|
||||||
const previousValue = draft.publishEnabled;
|
const previousValue = draft.publishEnabled;
|
||||||
const draftInvokeCode = draft.invokeCode;
|
const draftInvokeCode = draft.invokeCode;
|
||||||
const preserveInvokeCodeDraft = isInvokeCodeDirty.value;
|
const preserveInvokeCodeDraft = isInvokeCodeDirty.value;
|
||||||
|
|
||||||
draft.publishEnabled = nextValue;
|
draft.publishEnabled = publishEnabled;
|
||||||
isPublishing.value = true;
|
isPublishing.value = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const payload: ModelInvokeConfigPayload = {
|
const payload: ModelInvokeConfigPayload = {
|
||||||
id: draft.id,
|
id: draft.id,
|
||||||
invokeCode: draft.invokeCode.trim(),
|
invokeCode: draft.invokeCode.trim(),
|
||||||
publishEnabled: nextValue,
|
publishEnabled,
|
||||||
};
|
};
|
||||||
const res = await updateModelInvokeConfig(payload);
|
const res = await updateModelInvokeConfig(payload);
|
||||||
|
|
||||||
@@ -533,7 +534,7 @@ const handlePublishToggle = async (nextValue: boolean) => {
|
|||||||
preserveInvokeCodeDraft,
|
preserveInvokeCodeDraft,
|
||||||
draftInvokeCode,
|
draftInvokeCode,
|
||||||
});
|
});
|
||||||
ElMessage.success(nextValue ? '已发布该模型' : '已关闭该模型发布');
|
ElMessage.success(publishEnabled ? '已发布该模型' : '已关闭该模型发布');
|
||||||
emit('updated');
|
emit('updated');
|
||||||
} finally {
|
} finally {
|
||||||
isPublishing.value = false;
|
isPublishing.value = false;
|
||||||
|
|||||||
@@ -1,30 +1,31 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {computed, onMounted, onUnmounted, ref} from 'vue';
|
import { computed, onMounted, onUnmounted, ref } from 'vue';
|
||||||
import {useRoute} from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
|
|
||||||
import {usePreferences} from '@easyflow/preferences';
|
import { usePreferences } from '@easyflow/preferences';
|
||||||
import {getOptions, sortNodes} from '@easyflow/utils';
|
import { getOptions, sortNodes } from '@easyflow/utils';
|
||||||
import {getIconByValue} from '#/views/ai/model/modelUtils/defaultIcon';
|
import { getIconByValue } from '#/views/ai/model/modelUtils/defaultIcon';
|
||||||
|
|
||||||
import {ArrowLeft, CircleCheck, Close} from '@element-plus/icons-vue';
|
import { ArrowLeft, CircleCheck, Close } from '@element-plus/icons-vue';
|
||||||
import {Tinyflow} from '@tinyflow-ai/vue';
|
import { Tinyflow } from '@tinyflow-ai/vue';
|
||||||
import {ElButton, ElDrawer, ElMessage, ElSkeleton} from 'element-plus';
|
import { ElButton, ElDrawer, ElMessage, ElSkeleton } from 'element-plus';
|
||||||
|
|
||||||
import {api} from '#/api/request';
|
import { api } from '#/api/request';
|
||||||
import CommonSelectDataModal from '#/components/commonSelectModal/CommonSelectDataModal.vue';
|
import CommonSelectDataModal from '#/components/commonSelectModal/CommonSelectDataModal.vue';
|
||||||
import {$t} from '#/locales';
|
import { $t } from '#/locales';
|
||||||
import {router} from '#/router';
|
import { router } from '#/router';
|
||||||
import ExecResult from '#/views/ai/workflow/components/ExecResult.vue';
|
import ExecResult from '#/views/ai/workflow/components/ExecResult.vue';
|
||||||
import SingleRun from '#/views/ai/workflow/components/SingleRun.vue';
|
import SingleRun from '#/views/ai/workflow/components/SingleRun.vue';
|
||||||
import WorkflowForm from '#/views/ai/workflow/components/WorkflowForm.vue';
|
import WorkflowForm from '#/views/ai/workflow/components/WorkflowForm.vue';
|
||||||
import WorkflowSteps from '#/views/ai/workflow/components/WorkflowSteps.vue';
|
import WorkflowSteps from '#/views/ai/workflow/components/WorkflowSteps.vue';
|
||||||
|
|
||||||
import {getCustomNode} from './customNode/index';
|
import { getCustomNode } from './customNode/index';
|
||||||
|
import nodeNames from './customNode/nodeNames';
|
||||||
|
|
||||||
import '@tinyflow-ai/vue/dist/index.css';
|
import '@tinyflow-ai/vue/dist/index.css';
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const {isDark} = usePreferences();
|
const { isDark } = usePreferences();
|
||||||
// vue
|
// vue
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
document.addEventListener('keydown', handleKeydown);
|
document.addEventListener('keydown', handleKeydown);
|
||||||
@@ -82,30 +83,31 @@ function buildModelIconMarkup(icon?: string, providerType?: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const provider = computed(() => ({
|
const provider = computed(() => ({
|
||||||
llm: () => llmList.value.map((item: any) => {
|
llm: () =>
|
||||||
const iconStr = buildModelIconMarkup(
|
llmList.value.map((item: any) => {
|
||||||
item.modelProvider?.icon,
|
const iconStr = buildModelIconMarkup(
|
||||||
item.modelProvider?.providerType,
|
item.modelProvider?.icon,
|
||||||
);
|
item.modelProvider?.providerType,
|
||||||
|
);
|
||||||
|
|
||||||
// Extract brand and model name directly from the title if it contains '/'
|
// Extract brand and model name directly from the title if it contains '/'
|
||||||
let displayTitle = item.title || '';
|
let displayTitle = item.title || '';
|
||||||
let brandName = item.modelProvider?.providerName || '其他';
|
let brandName = item.modelProvider?.providerName || '其他';
|
||||||
|
|
||||||
if (displayTitle.includes('/')) {
|
if (displayTitle.includes('/')) {
|
||||||
const parts = displayTitle.split('/');
|
const parts = displayTitle.split('/');
|
||||||
brandName = parts[0];
|
brandName = parts[0];
|
||||||
displayTitle = parts.slice(1).join('/');
|
displayTitle = parts.slice(1).join('/');
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
label: displayTitle,
|
label: displayTitle,
|
||||||
value: item.id,
|
value: item.id,
|
||||||
brand: brandName,
|
brand: brandName,
|
||||||
icon: iconStr,
|
icon: iconStr,
|
||||||
description: item.description,
|
description: item.description,
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
knowledge: () => getOptions('title', 'id', knowledgeList.value),
|
knowledge: () => getOptions('title', 'id', knowledgeList.value),
|
||||||
searchEngine: (): any => [
|
searchEngine: (): any => [
|
||||||
{
|
{
|
||||||
@@ -113,20 +115,21 @@ const provider = computed(() => ({
|
|||||||
label: $t('aiWorkflow.bochaSearch'),
|
label: $t('aiWorkflow.bochaSearch'),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
codeEngine: (): any => codeEngineList.value.map((item: any) => {
|
codeEngine: (): any =>
|
||||||
if (item.available === false) {
|
codeEngineList.value.map((item: any) => {
|
||||||
const reason = item.reason || '未满足运行条件';
|
if (item.available === false) {
|
||||||
|
const reason = item.reason || '未满足运行条件';
|
||||||
|
return {
|
||||||
|
value: item.value,
|
||||||
|
label: `${item.label}(不可用:${reason})`,
|
||||||
|
selectable: false,
|
||||||
|
};
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
value: item.value,
|
value: item.value,
|
||||||
label: `${item.label}(不可用:${reason})`,
|
label: item.label,
|
||||||
selectable: false,
|
|
||||||
};
|
};
|
||||||
}
|
}),
|
||||||
return {
|
|
||||||
value: item.value,
|
|
||||||
label: item.label,
|
|
||||||
};
|
|
||||||
}),
|
|
||||||
}));
|
}));
|
||||||
const customNode = ref();
|
const customNode = ref();
|
||||||
const showTinyFlow = ref(false);
|
const showTinyFlow = ref(false);
|
||||||
@@ -142,17 +145,28 @@ let focusPulseTimer: ReturnType<typeof setTimeout> | undefined;
|
|||||||
|
|
||||||
type WorkflowCheckStage = 'SAVE' | 'PRE_EXECUTE';
|
type WorkflowCheckStage = 'SAVE' | 'PRE_EXECUTE';
|
||||||
const builtInNodeIconMap: Record<string, string> = {
|
const builtInNodeIconMap: Record<string, string> = {
|
||||||
startNode: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22ZM12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20ZM12 15C10.3431 15 9 13.6569 9 12C9 10.3431 10.3431 9 12 9C13.6569 9 15 10.3431 15 12C15 13.6569 13.6569 15 12 15Z"></path></svg>',
|
startNode:
|
||||||
loopNode: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M5.46257 4.43262C7.21556 2.91688 9.5007 2 12 2C17.5228 2 22 6.47715 22 12C22 14.1361 21.3302 16.1158 20.1892 17.7406L17 12H20C20 7.58172 16.4183 4 12 4C9.84982 4 7.89777 4.84827 6.46023 6.22842L5.46257 4.43262ZM18.5374 19.5674C16.7844 21.0831 14.4993 22 12 22C6.47715 22 2 17.5228 2 12C2 9.86386 2.66979 7.88416 3.8108 6.25944L7 12H4C4 16.4183 7.58172 20 12 20C14.1502 20 16.1022 19.1517 17.5398 17.7716L18.5374 19.5674Z"></path></svg>',
|
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22ZM12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20ZM12 15C10.3431 15 9 13.6569 9 12C9 10.3431 10.3431 9 12 9C13.6569 9 15 10.3431 15 12C15 13.6569 13.6569 15 12 15Z"></path></svg>',
|
||||||
conditionNode: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M4 4H10V10H4V4ZM14 4H20V10H14V4ZM4 14H10V20H4V14ZM14 14H20V20H14V14ZM10 7H14V9H10V7ZM7 10H9V14H7V10ZM15 10H17V14H15V10Z"></path></svg>',
|
loopNode:
|
||||||
llmNode: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M20.7134 7.12811L20.4668 7.69379C20.2864 8.10792 19.7136 8.10792 19.5331 7.69379L19.2866 7.12811C18.8471 6.11947 18.0555 5.31641 17.0677 4.87708L16.308 4.53922C15.8973 4.35653 15.8973 3.75881 16.308 3.57612L17.0252 3.25714C18.0384 2.80651 18.8442 1.97373 19.2761 0.930828L19.5293 0.319534C19.7058 -0.106511 20.2942 -0.106511 20.4706 0.319534L20.7238 0.930828C21.1558 1.97373 21.9616 2.80651 22.9748 3.25714L23.6919 3.57612C24.1027 3.75881 24.1027 4.35653 23.6919 4.53922L22.9323 4.87708C21.9445 5.31641 21.1529 6.11947 20.7134 7.12811ZM9 2C13.0675 2 16.426 5.03562 16.9337 8.96494L19.1842 12.5037C19.3324 12.7367 19.3025 13.0847 18.9593 13.2317L17 14.071V17C17 18.1046 16.1046 19 15 19H13.001L13 22H4L4.00025 18.3061C4.00033 17.1252 3.56351 16.0087 2.7555 15.0011C1.65707 13.6313 1 11.8924 1 10C1 5.58172 4.58172 2 9 2ZM9 4C5.68629 4 3 6.68629 3 10C3 11.3849 3.46818 12.6929 4.31578 13.7499C5.40965 15.114 6.00036 16.6672 6.00025 18.3063L6.00013 20H11.0007L11.0017 17H15V12.7519L16.5497 12.0881L15.0072 9.66262L14.9501 9.22118C14.5665 6.25141 12.0243 4 9 4ZM19.4893 16.9929L21.1535 18.1024C22.32 16.3562 23 14.2576 23 12.0001C23 11.317 22.9378 10.6486 22.8186 10L20.8756 10.5C20.9574 10.9878 21 11.489 21 12.0001C21 13.8471 20.4436 15.5642 19.4893 16.9929Z"></path></svg>',
|
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M5.46257 4.43262C7.21556 2.91688 9.5007 2 12 2C17.5228 2 22 6.47715 22 12C22 14.1361 21.3302 16.1158 20.1892 17.7406L17 12H20C20 7.58172 16.4183 4 12 4C9.84982 4 7.89777 4.84827 6.46023 6.22842L5.46257 4.43262ZM18.5374 19.5674C16.7844 21.0831 14.4993 22 12 22C6.47715 22 2 17.5228 2 12C2 9.86386 2.66979 7.88416 3.8108 6.25944L7 12H4C4 16.4183 7.58172 20 12 20C14.1502 20 16.1022 19.1517 17.5398 17.7716L18.5374 19.5674Z"></path></svg>',
|
||||||
knowledgeNode: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M15.5 5C13.567 5 12 6.567 12 8.5C12 10.433 13.567 12 15.5 12C17.433 12 19 10.433 19 8.5C19 6.567 17.433 5 15.5 5ZM10 8.5C10 5.46243 12.4624 3 15.5 3C18.5376 3 21 5.46243 21 8.5C21 9.6575 20.6424 10.7315 20.0317 11.6175L22.7071 14.2929L21.2929 15.7071L18.6175 13.0317C17.7315 13.6424 16.6575 14 15.5 14C12.4624 14 10 11.5376 10 8.5ZM3 4H8V6H3V4ZM3 11H8V13H3V11ZM21 18V20H3V18H21Z"></path></svg>',
|
conditionNode:
|
||||||
searchEngineNode: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M18.031 16.6168L22.3137 20.8995L20.8995 22.3137L16.6168 18.031C15.0769 19.263 13.124 20 11 20C6.032 20 2 15.968 2 11C2 6.032 6.032 2 11 2C15.968 2 20 6.032 20 11C20 13.124 19.263 15.0769 18.031 16.6168ZM16.0247 15.8748C17.2475 14.6146 18 12.8956 18 11C18 7.1325 14.8675 4 11 4C7.1325 4 4 7.1325 4 11C4 14.8675 7.1325 18 11 18C12.8956 18 14.6146 17.2475 15.8748 16.0247L16.0247 15.8748Z"></path></svg>',
|
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M4 4H10V10H4V4ZM14 4H20V10H14V4ZM4 14H10V20H4V14ZM14 14H20V20H14V14ZM10 7H14V9H10V7ZM7 10H9V14H7V10ZM15 10H17V14H15V10Z"></path></svg>',
|
||||||
httpNode: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M6.23509 6.45329C4.85101 7.89148 4 9.84636 4 12C4 16.4183 7.58172 20 12 20C13.0808 20 14.1116 19.7857 15.0521 19.3972C15.1671 18.6467 14.9148 17.9266 14.8116 17.6746C14.582 17.115 13.8241 16.1582 12.5589 14.8308C12.2212 14.4758 12.2429 14.2035 12.3636 13.3943L12.3775 13.3029C12.4595 12.7486 12.5971 12.4209 14.4622 12.1248C15.4097 11.9746 15.6589 12.3533 16.0043 12.8777C16.0425 12.9358 16.0807 12.9928 16.1198 13.0499C16.4479 13.5297 16.691 13.6394 17.0582 13.8064C17.2227 13.881 17.428 13.9751 17.7031 14.1314C18.3551 14.504 18.3551 14.9247 18.3551 15.8472V15.9518C18.3551 16.3434 18.3168 16.6872 18.2566 16.9859C19.3478 15.6185 20 13.8854 20 12C20 8.70089 18.003 5.8682 15.1519 4.64482C14.5987 5.01813 13.8398 5.54726 13.575 5.91C13.4396 6.09538 13.2482 7.04166 12.6257 7.11976C12.4626 7.14023 12.2438 7.12589 12.012 7.11097C11.3905 7.07058 10.5402 7.01606 10.268 7.75495C10.0952 8.2232 10.0648 9.49445 10.6239 10.1543C10.7134 10.2597 10.7307 10.4547 10.6699 10.6735C10.59 10.9608 10.4286 11.1356 10.3783 11.1717C10.2819 11.1163 10.0896 10.8931 9.95938 10.7412C9.64554 10.3765 9.25405 9.92233 8.74797 9.78176C8.56395 9.73083 8.36166 9.68867 8.16548 9.64736C7.6164 9.53227 6.99443 9.40134 6.84992 9.09302C6.74442 8.8672 6.74488 8.55621 6.74529 8.22764C6.74529 7.8112 6.74529 7.34029 6.54129 6.88256C6.46246 6.70541 6.35689 6.56446 6.23509 6.45329ZM12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22Z"></path></svg>',
|
llmNode:
|
||||||
codeNode: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M23 12L15.9289 19.0711L14.5147 17.6569L20.1716 12L14.5147 6.34317L15.9289 4.92896L23 12ZM3.82843 12L9.48528 17.6569L8.07107 19.0711L1 12L8.07107 4.92896L9.48528 6.34317L3.82843 12Z"></path></svg>',
|
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M20.7134 7.12811L20.4668 7.69379C20.2864 8.10792 19.7136 8.10792 19.5331 7.69379L19.2866 7.12811C18.8471 6.11947 18.0555 5.31641 17.0677 4.87708L16.308 4.53922C15.8973 4.35653 15.8973 3.75881 16.308 3.57612L17.0252 3.25714C18.0384 2.80651 18.8442 1.97373 19.2761 0.930828L19.5293 0.319534C19.7058 -0.106511 20.2942 -0.106511 20.4706 0.319534L20.7238 0.930828C21.1558 1.97373 21.9616 2.80651 22.9748 3.25714L23.6919 3.57612C24.1027 3.75881 24.1027 4.35653 23.6919 4.53922L22.9323 4.87708C21.9445 5.31641 21.1529 6.11947 20.7134 7.12811ZM9 2C13.0675 2 16.426 5.03562 16.9337 8.96494L19.1842 12.5037C19.3324 12.7367 19.3025 13.0847 18.9593 13.2317L17 14.071V17C17 18.1046 16.1046 19 15 19H13.001L13 22H4L4.00025 18.3061C4.00033 17.1252 3.56351 16.0087 2.7555 15.0011C1.65707 13.6313 1 11.8924 1 10C1 5.58172 4.58172 2 9 2ZM9 4C5.68629 4 3 6.68629 3 10C3 11.3849 3.46818 12.6929 4.31578 13.7499C5.40965 15.114 6.00036 16.6672 6.00025 18.3063L6.00013 20H11.0007L11.0017 17H15V12.7519L16.5497 12.0881L15.0072 9.66262L14.9501 9.22118C14.5665 6.25141 12.0243 4 9 4ZM19.4893 16.9929L21.1535 18.1024C22.32 16.3562 23 14.2576 23 12.0001C23 11.317 22.9378 10.6486 22.8186 10L20.8756 10.5C20.9574 10.9878 21 11.489 21 12.0001C21 13.8471 20.4436 15.5642 19.4893 16.9929Z"></path></svg>',
|
||||||
templateNode: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M2 4C2 3.44772 2.44772 3 3 3H21C21.5523 3 22 3.44772 22 4V20C22 20.5523 21.5523 21 21 21H3C2.44772 21 2 20.5523 2 20V4ZM4 5V19H20V5H4ZM7 8H17V11H15V10H13V14H14.5V16H9.5V14H11V10H9V11H7V8Z"></path></svg>',
|
knowledgeNode:
|
||||||
confirmNode: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M15.3873 13.4975L17.9403 20.5117L13.2418 22.2218L10.6889 15.2076L6.79004 17.6529L8.4086 1.63318L19.9457 12.8646L15.3873 13.4975ZM15.3768 19.3163L12.6618 11.8568L15.6212 11.4459L9.98201 5.9561L9.19088 13.7863L11.7221 12.1988L14.4371 19.6583L15.3768 19.3163Z"></path></svg>',
|
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M15.5 5C13.567 5 12 6.567 12 8.5C12 10.433 13.567 12 15.5 12C17.433 12 19 10.433 19 8.5C19 6.567 17.433 5 15.5 5ZM10 8.5C10 5.46243 12.4624 3 15.5 3C18.5376 3 21 5.46243 21 8.5C21 9.6575 20.6424 10.7315 20.0317 11.6175L22.7071 14.2929L21.2929 15.7071L18.6175 13.0317C17.7315 13.6424 16.6575 14 15.5 14C12.4624 14 10 11.5376 10 8.5ZM3 4H8V6H3V4ZM3 11H8V13H3V11ZM21 18V20H3V18H21Z"></path></svg>',
|
||||||
endNode: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M6 5.1438V16.0002H18.3391L6 5.1438ZM4 2.932C4 2.07155 5.01456 1.61285 5.66056 2.18123L21.6501 16.2494C22.3423 16.8584 21.9116 18.0002 20.9896 18.0002H6V22H4V2.932Z"></path></svg>',
|
searchEngineNode:
|
||||||
|
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M18.031 16.6168L22.3137 20.8995L20.8995 22.3137L16.6168 18.031C15.0769 19.263 13.124 20 11 20C6.032 20 2 15.968 2 11C2 6.032 6.032 2 11 2C15.968 2 20 6.032 20 11C20 13.124 19.263 15.0769 18.031 16.6168ZM16.0247 15.8748C17.2475 14.6146 18 12.8956 18 11C18 7.1325 14.8675 4 11 4C7.1325 4 4 7.1325 4 11C4 14.8675 7.1325 18 11 18C12.8956 18 14.6146 17.2475 15.8748 16.0247L16.0247 15.8748Z"></path></svg>',
|
||||||
|
httpNode:
|
||||||
|
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M6.23509 6.45329C4.85101 7.89148 4 9.84636 4 12C4 16.4183 7.58172 20 12 20C13.0808 20 14.1116 19.7857 15.0521 19.3972C15.1671 18.6467 14.9148 17.9266 14.8116 17.6746C14.582 17.115 13.8241 16.1582 12.5589 14.8308C12.2212 14.4758 12.2429 14.2035 12.3636 13.3943L12.3775 13.3029C12.4595 12.7486 12.5971 12.4209 14.4622 12.1248C15.4097 11.9746 15.6589 12.3533 16.0043 12.8777C16.0425 12.9358 16.0807 12.9928 16.1198 13.0499C16.4479 13.5297 16.691 13.6394 17.0582 13.8064C17.2227 13.881 17.428 13.9751 17.7031 14.1314C18.3551 14.504 18.3551 14.9247 18.3551 15.8472V15.9518C18.3551 16.3434 18.3168 16.6872 18.2566 16.9859C19.3478 15.6185 20 13.8854 20 12C20 8.70089 18.003 5.8682 15.1519 4.64482C14.5987 5.01813 13.8398 5.54726 13.575 5.91C13.4396 6.09538 13.2482 7.04166 12.6257 7.11976C12.4626 7.14023 12.2438 7.12589 12.012 7.11097C11.3905 7.07058 10.5402 7.01606 10.268 7.75495C10.0952 8.2232 10.0648 9.49445 10.6239 10.1543C10.7134 10.2597 10.7307 10.4547 10.6699 10.6735C10.59 10.9608 10.4286 11.1356 10.3783 11.1717C10.2819 11.1163 10.0896 10.8931 9.95938 10.7412C9.64554 10.3765 9.25405 9.92233 8.74797 9.78176C8.56395 9.73083 8.36166 9.68867 8.16548 9.64736C7.6164 9.53227 6.99443 9.40134 6.84992 9.09302C6.74442 8.8672 6.74488 8.55621 6.74529 8.22764C6.74529 7.8112 6.74529 7.34029 6.54129 6.88256C6.46246 6.70541 6.35689 6.56446 6.23509 6.45329ZM12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22Z"></path></svg>',
|
||||||
|
codeNode:
|
||||||
|
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M23 12L15.9289 19.0711L14.5147 17.6569L20.1716 12L14.5147 6.34317L15.9289 4.92896L23 12ZM3.82843 12L9.48528 17.6569L8.07107 19.0711L1 12L8.07107 4.92896L9.48528 6.34317L3.82843 12Z"></path></svg>',
|
||||||
|
templateNode:
|
||||||
|
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M2 4C2 3.44772 2.44772 3 3 3H21C21.5523 3 22 3.44772 22 4V20C22 20.5523 21.5523 21 21 21H3C2.44772 21 2 20.5523 2 20V4ZM4 5V19H20V5H4ZM7 8H17V11H15V10H13V14H14.5V16H9.5V14H11V10H9V11H7V8Z"></path></svg>',
|
||||||
|
confirmNode:
|
||||||
|
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M15.3873 13.4975L17.9403 20.5117L13.2418 22.2218L10.6889 15.2076L6.79004 17.6529L8.4086 1.63318L19.9457 12.8646L15.3873 13.4975ZM15.3768 19.3163L12.6618 11.8568L15.6212 11.4459L9.98201 5.9561L9.19088 13.7863L11.7221 12.1988L14.4371 19.6583L15.3768 19.3163Z"></path></svg>',
|
||||||
|
endNode:
|
||||||
|
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M6 5.1438V16.0002H18.3391L6 5.1438ZM4 2.932C4 2.07155 5.01456 1.61285 5.66056 2.18123L21.6501 16.2494C22.3423 16.8584 21.9116 18.0002 20.9896 18.0002H6V22H4V2.932Z"></path></svg>',
|
||||||
};
|
};
|
||||||
const builtInNodeTitleMap: Record<string, string> = {
|
const builtInNodeTitleMap: Record<string, string> = {
|
||||||
startNode: '开始节点',
|
startNode: '开始节点',
|
||||||
@@ -317,7 +331,11 @@ async function getKnowledgeList() {
|
|||||||
}
|
}
|
||||||
async function getCodeEngineList() {
|
async function getCodeEngineList() {
|
||||||
return api.get('/api/v1/workflow/supportedCodeEngines').then((res) => {
|
return api.get('/api/v1/workflow/supportedCodeEngines').then((res) => {
|
||||||
if (res?.errorCode === 0 && Array.isArray(res.data) && res.data.length > 0) {
|
if (
|
||||||
|
res?.errorCode === 0 &&
|
||||||
|
Array.isArray(res.data) &&
|
||||||
|
res.data.length > 0
|
||||||
|
) {
|
||||||
codeEngineList.value = res.data;
|
codeEngineList.value = res.data;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -332,7 +350,10 @@ function getRunningParams() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
async function runCheck(stage: WorkflowCheckStage, silentPass: boolean = false) {
|
async function runCheck(
|
||||||
|
stage: WorkflowCheckStage,
|
||||||
|
silentPass: boolean = false,
|
||||||
|
) {
|
||||||
const content = tinyflowRef.value?.getData();
|
const content = tinyflowRef.value?.getData();
|
||||||
if (!content) {
|
if (!content) {
|
||||||
ElMessage.error($t('aiWorkflow.checkContentEmpty'));
|
ElMessage.error($t('aiWorkflow.checkContentEmpty'));
|
||||||
@@ -595,8 +616,16 @@ function onAsyncExecute(info: any) {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="check-summary">
|
<div class="check-summary">
|
||||||
<span>{{ $t('aiWorkflow.checkStageLabel') }}:{{ checkStageText(checkResult?.stage) }}</span>
|
<span
|
||||||
<span>{{ $t('aiWorkflow.issueCount') }}:{{ checkResult?.issueCount || 0 }}</span>
|
>{{ $t('aiWorkflow.checkStageLabel') }}:{{
|
||||||
|
checkStageText(checkResult?.stage)
|
||||||
|
}}</span
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
>{{ $t('aiWorkflow.issueCount') }}:{{
|
||||||
|
checkResult?.issueCount || 0
|
||||||
|
}}</span
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
<div class="checklist-body">
|
<div class="checklist-body">
|
||||||
<button
|
<button
|
||||||
@@ -604,13 +633,20 @@ function onAsyncExecute(info: any) {
|
|||||||
:key="item.key"
|
:key="item.key"
|
||||||
class="check-item"
|
class="check-item"
|
||||||
:class="[
|
:class="[
|
||||||
{ 'is-clickable': canFocusIssue(item.issue), 'is-active': focusedIssueKey === item.key },
|
{
|
||||||
|
'is-clickable': canFocusIssue(item.issue),
|
||||||
|
'is-active': focusedIssueKey === item.key,
|
||||||
|
},
|
||||||
]"
|
]"
|
||||||
:disabled="!canFocusIssue(item.issue)"
|
:disabled="!canFocusIssue(item.issue)"
|
||||||
@click="focusIssue(item.issue, item.index)"
|
@click="focusIssue(item.issue, item.index)"
|
||||||
>
|
>
|
||||||
<div class="check-item-meta">
|
<div class="check-item-meta">
|
||||||
<span class="check-level" :class="issueLevelClass(item.issue.level)">{{ item.issue.level || '-' }}</span>
|
<span
|
||||||
|
class="check-level"
|
||||||
|
:class="issueLevelClass(item.issue.level)"
|
||||||
|
>{{ item.issue.level || '-' }}</span
|
||||||
|
>
|
||||||
<span class="check-node-display">
|
<span class="check-node-display">
|
||||||
<span
|
<span
|
||||||
v-if="item.nodeDisplay.icon"
|
v-if="item.nodeDisplay.icon"
|
||||||
@@ -618,10 +654,14 @@ function onAsyncExecute(info: any) {
|
|||||||
v-html="item.nodeDisplay.icon"
|
v-html="item.nodeDisplay.icon"
|
||||||
/>
|
/>
|
||||||
<span v-else class="check-node-icon-fallback">N</span>
|
<span v-else class="check-node-icon-fallback">N</span>
|
||||||
<span class="check-node-title">{{ item.nodeDisplay.title }}</span>
|
<span class="check-node-title">{{
|
||||||
|
item.nodeDisplay.title
|
||||||
|
}}</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="check-item-message">{{ item.issue.message || '-' }}</div>
|
<div class="check-item-message">
|
||||||
|
{{ item.issue.message || '-' }}
|
||||||
|
</div>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -714,7 +754,10 @@ function onAsyncExecute(info: any) {
|
|||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
background: var(--el-fill-color-lighter);
|
background: var(--el-fill-color-lighter);
|
||||||
padding: 10px 12px;
|
padding: 10px 12px;
|
||||||
transition: border-color 0.2s ease, box-shadow 0.2s ease, background-color 0.2s ease;
|
transition:
|
||||||
|
border-color 0.2s ease,
|
||||||
|
box-shadow 0.2s ease,
|
||||||
|
background-color 0.2s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.check-item.is-clickable {
|
.check-item.is-clickable {
|
||||||
|
|||||||
@@ -30,7 +30,9 @@ type NodeLike = {
|
|||||||
|
|
||||||
type UpdateNodeData = (
|
type UpdateNodeData = (
|
||||||
nodeId: string,
|
nodeId: string,
|
||||||
data: Record<string, any> | ((node: Record<string, any>) => Record<string, any>),
|
data:
|
||||||
|
| Record<string, any>
|
||||||
|
| ((node: Record<string, any>) => Record<string, any>),
|
||||||
) => void;
|
) => void;
|
||||||
|
|
||||||
type FlowInstance = {
|
type FlowInstance = {
|
||||||
@@ -80,7 +82,9 @@ function getSourceKey(datasetRef?: DatasetRefPayload | null) {
|
|||||||
return datasetRef?.sourceId == null ? '' : String(datasetRef.sourceId);
|
return datasetRef?.sourceId == null ? '' : String(datasetRef.sourceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
function createSourceOnlyDatasetRef(source: ManagedDatasetSourceOption): DatasetRefPayload {
|
function createSourceOnlyDatasetRef(
|
||||||
|
source: ManagedDatasetSourceOption,
|
||||||
|
): DatasetRefPayload {
|
||||||
return {
|
return {
|
||||||
sourceId: source.sourceId,
|
sourceId: source.sourceId,
|
||||||
catalogId: null,
|
catalogId: null,
|
||||||
@@ -337,7 +341,10 @@ function buildStyles() {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function filterTableOptions(options: ManagedDatasetOption[], searchText: string) {
|
function filterTableOptions(
|
||||||
|
options: ManagedDatasetOption[],
|
||||||
|
searchText: string,
|
||||||
|
) {
|
||||||
const keyword = searchText.trim().toLowerCase();
|
const keyword = searchText.trim().toLowerCase();
|
||||||
if (!keyword) {
|
if (!keyword) {
|
||||||
return options;
|
return options;
|
||||||
@@ -350,7 +357,11 @@ function ensureOptionsLoaded(
|
|||||||
parent: HTMLElement,
|
parent: HTMLElement,
|
||||||
node: NodeLike,
|
node: NodeLike,
|
||||||
flowInstance: RenderContext,
|
flowInstance: RenderContext,
|
||||||
rerender: (parent: HTMLElement, node: NodeLike, flowInstance?: RenderContext) => void,
|
rerender: (
|
||||||
|
parent: HTMLElement,
|
||||||
|
node: NodeLike,
|
||||||
|
flowInstance?: RenderContext,
|
||||||
|
) => void,
|
||||||
) {
|
) {
|
||||||
if (state.loadingOptions || state.optionsLoaded) {
|
if (state.loadingOptions || state.optionsLoaded) {
|
||||||
return;
|
return;
|
||||||
@@ -394,7 +405,11 @@ function buildPickerListItem(
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildSourceList(options: ManagedDatasetSourceOption[], activeKey: string, emptyText: string) {
|
function buildSourceList(
|
||||||
|
options: ManagedDatasetSourceOption[],
|
||||||
|
activeKey: string,
|
||||||
|
emptyText: string,
|
||||||
|
) {
|
||||||
if (!options.length) {
|
if (!options.length) {
|
||||||
return `<div class="dataset-node-empty">${emptyText}</div>`;
|
return `<div class="dataset-node-empty">${emptyText}</div>`;
|
||||||
}
|
}
|
||||||
@@ -412,7 +427,11 @@ function buildSourceList(options: ManagedDatasetSourceOption[], activeKey: strin
|
|||||||
.join('');
|
.join('');
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildTableList(options: ManagedDatasetOption[], activeKey: string, emptyText: string) {
|
function buildTableList(
|
||||||
|
options: ManagedDatasetOption[],
|
||||||
|
activeKey: string,
|
||||||
|
emptyText: string,
|
||||||
|
) {
|
||||||
if (!options.length) {
|
if (!options.length) {
|
||||||
return `<div class="dataset-node-empty">${emptyText}</div>`;
|
return `<div class="dataset-node-empty">${emptyText}</div>`;
|
||||||
}
|
}
|
||||||
@@ -443,20 +462,29 @@ function buildSearchSummary(currentSource?: ManagedDatasetSourceOption) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function bindInteractiveElements(parent: HTMLElement) {
|
function bindInteractiveElements(parent: HTMLElement) {
|
||||||
parent.querySelectorAll<HTMLElement>('button, input, select, textarea').forEach((element) => {
|
parent
|
||||||
element.onpointerdown = (event) => event.stopPropagation();
|
.querySelectorAll<HTMLElement>('button, input, select, textarea')
|
||||||
element.onmousedown = (event) => event.stopPropagation();
|
.forEach((element) => {
|
||||||
});
|
element.onpointerdown = (event) => event.stopPropagation();
|
||||||
|
element.onmousedown = (event) => event.stopPropagation();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function rerenderSearchNode(parent: HTMLElement, node: NodeLike, flowInstance?: RenderContext) {
|
export function rerenderSearchNode(
|
||||||
|
parent: HTMLElement,
|
||||||
|
node: NodeLike,
|
||||||
|
flowInstance?: RenderContext,
|
||||||
|
) {
|
||||||
const state = getState(parent);
|
const state = getState(parent);
|
||||||
const updateNodeData = getUpdateNodeData(parent, flowInstance);
|
const updateNodeData = getUpdateNodeData(parent, flowInstance);
|
||||||
ensureOptionsLoaded(state, parent, node, flowInstance, rerenderSearchNode);
|
ensureOptionsLoaded(state, parent, node, flowInstance, rerenderSearchNode);
|
||||||
|
|
||||||
const datasetRef = (node.data?.datasetRef || null) as DatasetRefPayload | null;
|
const datasetRef = (node.data?.datasetRef ||
|
||||||
|
null) as DatasetRefPayload | null;
|
||||||
const sourceKey = getSourceKey(datasetRef);
|
const sourceKey = getSourceKey(datasetRef);
|
||||||
const currentSource = state.sources.find((item) => String(item.sourceId) === sourceKey);
|
const currentSource = state.sources.find(
|
||||||
|
(item) => String(item.sourceId) === sourceKey,
|
||||||
|
);
|
||||||
|
|
||||||
parent.innerHTML = `
|
parent.innerHTML = `
|
||||||
${buildStyles()}
|
${buildStyles()}
|
||||||
@@ -469,61 +497,75 @@ export function rerenderSearchNode(parent: HTMLElement, node: NodeLike, flowInst
|
|||||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M11.9999 13.1714L16.9497 8.22168L18.3639 9.63589L11.9999 15.9999L5.63599 9.63589L7.0502 8.22168L11.9999 13.1714Z"></path></svg>
|
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M11.9999 13.1714L16.9497 8.22168L18.3639 9.63589L11.9999 15.9999L5.63599 9.63589L7.0502 8.22168L11.9999 13.1714Z"></path></svg>
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
${state.pickerOpen ? `
|
${
|
||||||
|
state.pickerOpen
|
||||||
|
? `
|
||||||
<div class="dataset-node-picker">
|
<div class="dataset-node-picker">
|
||||||
<div class="dataset-node-picker-body">
|
<div class="dataset-node-picker-body">
|
||||||
${state.loadingOptions ? '<div class="dataset-node-empty">正在加载连接服务...</div>' : buildSourceList(state.sources, sourceKey, '暂无可用连接服务')}
|
${state.loadingOptions ? '<div class="dataset-node-empty">正在加载连接服务...</div>' : buildSourceList(state.sources, sourceKey, '暂无可用连接服务')}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
` : ''}
|
`
|
||||||
|
: ''
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
bindInteractiveElements(parent);
|
bindInteractiveElements(parent);
|
||||||
|
|
||||||
parent.querySelector<HTMLElement>('[data-action="toggle-picker"]')?.addEventListener('click', (event) => {
|
parent
|
||||||
event.preventDefault();
|
.querySelector<HTMLElement>('[data-action="toggle-picker"]')
|
||||||
event.stopPropagation();
|
?.addEventListener('click', (event) => {
|
||||||
state.pickerOpen = !state.pickerOpen;
|
|
||||||
rerenderSearchNode(parent, node, flowInstance);
|
|
||||||
});
|
|
||||||
|
|
||||||
parent.querySelectorAll<HTMLElement>('[data-action="select-source"]').forEach((element) => {
|
|
||||||
element.addEventListener('click', (event) => {
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
const sourceId = element.dataset.sourceId;
|
state.pickerOpen = !state.pickerOpen;
|
||||||
const source = state.sources.find((item) => String(item.sourceId) === String(sourceId));
|
|
||||||
if (!source) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
state.pickerOpen = false;
|
|
||||||
const nextDatasetRef = createSourceOnlyDatasetRef(source);
|
|
||||||
node.data = {
|
|
||||||
...(node.data || {}),
|
|
||||||
datasetRef: nextDatasetRef,
|
|
||||||
sourceName: source.sourceName,
|
|
||||||
sourceType: source.sourceType,
|
|
||||||
};
|
|
||||||
updateNodeData?.(node.id, {
|
|
||||||
datasetRef: nextDatasetRef,
|
|
||||||
sourceName: source.sourceName,
|
|
||||||
sourceType: source.sourceType,
|
|
||||||
});
|
|
||||||
rerenderSearchNode(parent, node, flowInstance);
|
rerenderSearchNode(parent, node, flowInstance);
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
parent
|
||||||
|
.querySelectorAll<HTMLElement>('[data-action="select-source"]')
|
||||||
|
.forEach((element) => {
|
||||||
|
element.addEventListener('click', (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
const sourceId = element.dataset.sourceId;
|
||||||
|
const source = state.sources.find(
|
||||||
|
(item) => String(item.sourceId) === String(sourceId),
|
||||||
|
);
|
||||||
|
if (!source) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
state.pickerOpen = false;
|
||||||
|
const nextDatasetRef = createSourceOnlyDatasetRef(source);
|
||||||
|
node.data = {
|
||||||
|
...(node.data || {}),
|
||||||
|
datasetRef: nextDatasetRef,
|
||||||
|
sourceName: source.sourceName,
|
||||||
|
sourceType: source.sourceType,
|
||||||
|
};
|
||||||
|
updateNodeData?.(node.id, {
|
||||||
|
datasetRef: nextDatasetRef,
|
||||||
|
sourceName: source.sourceName,
|
||||||
|
sourceType: source.sourceType,
|
||||||
|
});
|
||||||
|
rerenderSearchNode(parent, node, flowInstance);
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function rerenderSaveNode(parent: HTMLElement, node: NodeLike, flowInstance?: RenderContext) {
|
export function rerenderSaveNode(
|
||||||
|
parent: HTMLElement,
|
||||||
|
node: NodeLike,
|
||||||
|
flowInstance?: RenderContext,
|
||||||
|
) {
|
||||||
const state = getState(parent);
|
const state = getState(parent);
|
||||||
const updateNodeData = getUpdateNodeData(parent, flowInstance);
|
const updateNodeData = getUpdateNodeData(parent, flowInstance);
|
||||||
ensureOptionsLoaded(state, parent, node, flowInstance, rerenderSaveNode);
|
ensureOptionsLoaded(state, parent, node, flowInstance, rerenderSaveNode);
|
||||||
|
|
||||||
const datasetRef = (node.data?.datasetRef || null) as DatasetRefPayload | null;
|
const datasetRef = (node.data?.datasetRef ||
|
||||||
|
null) as DatasetRefPayload | null;
|
||||||
const activeKey = getDatasetKey(datasetRef);
|
const activeKey = getDatasetKey(datasetRef);
|
||||||
const currentOption = state.options.find((item) => String(item.datasetRef.tableId) === activeKey);
|
|
||||||
const filtered = filterTableOptions(state.options, state.tableSearchText);
|
const filtered = filterTableOptions(state.options, state.tableSearchText);
|
||||||
|
|
||||||
parent.innerHTML = `
|
parent.innerHTML = `
|
||||||
@@ -541,33 +583,40 @@ export function rerenderSaveNode(parent: HTMLElement, node: NodeLike, flowInstan
|
|||||||
|
|
||||||
bindInteractiveElements(parent);
|
bindInteractiveElements(parent);
|
||||||
|
|
||||||
parent.querySelector<HTMLInputElement>('[data-role="table-search"]')?.addEventListener('input', (event) => {
|
parent
|
||||||
event.stopPropagation();
|
.querySelector<HTMLInputElement>('[data-role="table-search"]')
|
||||||
state.tableSearchText = (event.currentTarget as HTMLInputElement).value || '';
|
?.addEventListener('input', (event) => {
|
||||||
rerenderSaveNode(parent, node, flowInstance);
|
|
||||||
});
|
|
||||||
|
|
||||||
parent.querySelectorAll<HTMLElement>('[data-action="select-dataset"]').forEach((element) => {
|
|
||||||
element.addEventListener('click', (event) => {
|
|
||||||
event.preventDefault();
|
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
const tableId = element.dataset.tableId;
|
state.tableSearchText =
|
||||||
const option = state.options.find((item) => String(item.datasetRef.tableId) === String(tableId));
|
(event.currentTarget as HTMLInputElement).value || '';
|
||||||
if (!option) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
node.data = {
|
|
||||||
...(node.data || {}),
|
|
||||||
datasetRef: option.datasetRef,
|
|
||||||
sourceName: option.sourceName,
|
|
||||||
sourceType: option.sourceType,
|
|
||||||
};
|
|
||||||
updateNodeData?.(node.id, {
|
|
||||||
datasetRef: option.datasetRef,
|
|
||||||
sourceName: option.sourceName,
|
|
||||||
sourceType: option.sourceType,
|
|
||||||
});
|
|
||||||
rerenderSaveNode(parent, node, flowInstance);
|
rerenderSaveNode(parent, node, flowInstance);
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
parent
|
||||||
|
.querySelectorAll<HTMLElement>('[data-action="select-dataset"]')
|
||||||
|
.forEach((element) => {
|
||||||
|
element.addEventListener('click', (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
const tableId = element.dataset.tableId;
|
||||||
|
const option = state.options.find(
|
||||||
|
(item) => String(item.datasetRef.tableId) === String(tableId),
|
||||||
|
);
|
||||||
|
if (!option) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
node.data = {
|
||||||
|
...(node.data || {}),
|
||||||
|
datasetRef: option.datasetRef,
|
||||||
|
sourceName: option.sourceName,
|
||||||
|
sourceType: option.sourceType,
|
||||||
|
};
|
||||||
|
updateNodeData?.(node.id, {
|
||||||
|
datasetRef: option.datasetRef,
|
||||||
|
sourceName: option.sourceName,
|
||||||
|
sourceType: option.sourceType,
|
||||||
|
});
|
||||||
|
rerenderSaveNode(parent, node, flowInstance);
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -172,12 +172,14 @@ const scrollToBottom = (force = false) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const buildRequestHeaders = (token = requestAccessToken.value) =>
|
const buildRequestHeaders = (
|
||||||
|
token = requestAccessToken.value,
|
||||||
|
): Record<string, string> | undefined =>
|
||||||
token
|
token
|
||||||
? {
|
? {
|
||||||
'easyflow-token': token,
|
'easyflow-token': token,
|
||||||
}
|
}
|
||||||
: {};
|
: undefined;
|
||||||
|
|
||||||
const getResponseBody = async <T,>(request: Promise<any>) => {
|
const getResponseBody = async <T,>(request: Promise<any>) => {
|
||||||
const response = await request;
|
const response = await request;
|
||||||
|
|||||||
@@ -41,21 +41,18 @@ function parseSvg(svgData: string): IconifyIconStructure {
|
|||||||
*/
|
*/
|
||||||
async function loadSvgIcons() {
|
async function loadSvgIcons() {
|
||||||
addIcon('svg:chat-history', {
|
addIcon('svg:chat-history', {
|
||||||
...parseSvg(
|
...parseSvg(chatHistorySvg),
|
||||||
typeof chatHistorySvg === 'object'
|
|
||||||
? chatHistorySvg.default
|
|
||||||
: chatHistorySvg,
|
|
||||||
),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const svgEagers = import.meta.glob('./icons/**', {
|
const svgEagers = import.meta.glob<string>('./icons/**', {
|
||||||
eager: true,
|
eager: true,
|
||||||
|
import: 'default',
|
||||||
query: '?raw',
|
query: '?raw',
|
||||||
});
|
});
|
||||||
|
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
Object.entries(svgEagers).map((svg) => {
|
Object.entries(svgEagers).map((svg) => {
|
||||||
const [key, body] = svg as [string, string | { default: string }];
|
const [key, body] = svg;
|
||||||
|
|
||||||
// ./icons/xxxx.svg => xxxxxx
|
// ./icons/xxxx.svg => xxxxxx
|
||||||
const start = key.lastIndexOf('/') + 1;
|
const start = key.lastIndexOf('/') + 1;
|
||||||
@@ -63,7 +60,7 @@ async function loadSvgIcons() {
|
|||||||
const iconName = key.slice(start, end);
|
const iconName = key.slice(start, end);
|
||||||
|
|
||||||
return addIcon(`svg:${iconName}`, {
|
return addIcon(`svg:${iconName}`, {
|
||||||
...parseSvg(typeof body === 'object' ? body.default : body),
|
...parseSvg(body),
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user