feat: The document supports setting tags

v3.2
wangdan-fit2cloud 2025-10-20 17:31:40 +08:00
parent aa42c6f76f
commit 75eab6749e
12 changed files with 291 additions and 200 deletions

View File

@ -75,5 +75,25 @@ export default {
]) ])
}, },
}, },
'app-tag': {
iconReader: () => {
return h('i', [
h(
'svg',
{
style: { height: '100%', width: '100%' },
viewBox: '0 0 1024 1024',
version: '1.1',
xmlns: 'http://www.w3.org/2000/svg',
},
[
h('path', {
d: 'M512 85.333333a42.666667 42.666667 0 0 1 30.165333 12.501334l345.045334 345.045333a119.466667 119.466667 0 0 1 0 168.448l-275.413334 275.370667a119.466667 119.466667 0 0 1-169.002666 0.042666l-344.96-344.533333A42.666667 42.666667 0 0 1 85.333333 512V128a42.666667 42.666667 0 0 1 42.666667-42.666667h384z m-17.706667 85.333334H170.666667v323.669333l332.458666 332.074667a34.133333 34.133333 0 0 0 18.773334 9.557333l5.376 0.426667a34.133333 34.133333 0 0 0 24.149333-10.026667l275.242667-275.2a34.133333 34.133333 0 0 0 0.085333-48.042667L494.293333 170.666667zM352 298.666667a53.333333 53.333333 0 1 1 0 106.666666 53.333333 53.333333 0 0 1 0-106.666666z',
fill: 'currentColor',
}),
],
),
])
},
},
} }

View File

@ -106,10 +106,12 @@ export default {
addTag: 'Add Tag', addTag: 'Add Tag',
setting: 'Tag Settings', setting: 'Tag Settings',
create: 'Create Tag', create: 'Create Tag',
createValue: 'Create Tag Value',
edit: 'Edit Tag', edit: 'Edit Tag',
editValue: 'Edit Tag Value', editValue: 'Edit Tag Value',
deleteConfirm: 'Confirm delete tag: ', deleteConfirm: 'Confirm delete tag: ',
deleteTip: 'After deletion, resources using this tag will have the tag removed. Please proceed with caution!', deleteTip:
'After deletion, resources using this tag will have the tag removed. Please proceed with caution!',
requiredMessage1: 'Please enter a tag', requiredMessage1: 'Please enter a tag',
requiredMessage2: 'Please enter a value', requiredMessage2: 'Please enter a value',
}, },
@ -174,8 +176,8 @@ export default {
requiredMessage: 'Please enter similarity value', requiredMessage: 'Please enter similarity value',
}, },
allow_download: { allow_download: {
label: 'Allow download in knowledge base source', label: 'Allow download in knowledge base source',
} },
}, },
hitHandlingMethod: { hitHandlingMethod: {
optimization: 'Model optimization', optimization: 'Model optimization',

View File

@ -102,6 +102,7 @@ export default {
addValue: '添加标签值', addValue: '添加标签值',
setting: '标签设置', setting: '标签设置',
create: '创建标签', create: '创建标签',
createValue: '创建标签值',
edit: '编辑标签', edit: '编辑标签',
editValue: '编辑标签值', editValue: '编辑标签值',
deleteConfirm: '是否删除标签: ', deleteConfirm: '是否删除标签: ',
@ -169,7 +170,7 @@ export default {
}, },
allow_download: { allow_download: {
label: '允许在知识库来源中下载', label: '允许在知识库来源中下载',
} },
}, },
hitHandlingMethod: { hitHandlingMethod: {
optimization: '模型优化', optimization: '模型优化',

View File

@ -104,6 +104,7 @@ export default {
addTag: '添加標籤', addTag: '添加標籤',
setting: '標籤設置', setting: '標籤設置',
create: '創建標籤', create: '創建標籤',
createValue: '創建標籤值',
edit: '編輯標籤', edit: '編輯標籤',
editValue: '編輯標籤值', editValue: '編輯標籤值',
deleteConfirm: '是否刪除標籤: ', deleteConfirm: '是否刪除標籤: ',
@ -170,8 +171,8 @@ export default {
requiredMessage: '请输入相似度', requiredMessage: '请输入相似度',
}, },
allow_download: { allow_download: {
label: '允許在知識庫來源下載', label: '允許在知識庫來源下載',
} },
}, },
hitHandlingMethod: { hitHandlingMethod: {
optimization: '模型優化', optimization: '模型優化',

View File

@ -57,13 +57,7 @@
> >
{{ $t('common.setting') }} {{ $t('common.setting') }}
</el-button> </el-button>
<el-button
@click="openAddTagDialog()"
:disabled="multipleSelection.length === 0"
v-if="permissionPrecise.doc_edit(id)"
>
{{ $t('views.document.tag.addTag') }}
</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">
<AppIcon iconName="app-more"></AppIcon> <AppIcon iconName="app-more"></AppIcon>
@ -77,6 +71,12 @@
> >
{{ $t('views.document.setting.migration') }} {{ $t('views.document.setting.migration') }}
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item
@click="openAddTagDialog()"
:disabled="multipleSelection.length === 0"
v-if="permissionPrecise.doc_edit(id)"
>{{ $t('views.document.tag.addTag') }}
</el-dropdown-item>
<el-dropdown-item <el-dropdown-item
divided divided
@click="syncMulDocument" @click="syncMulDocument"
@ -91,6 +91,7 @@
v-if="knowledgeDetail?.type === 2 && permissionPrecise.doc_sync(id)" v-if="knowledgeDetail?.type === 2 && permissionPrecise.doc_sync(id)"
>{{ $t('views.document.syncDocument') }} >{{ $t('views.document.syncDocument') }}
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item <el-dropdown-item
divided divided
@click="deleteMulDocument" @click="deleteMulDocument"
@ -459,9 +460,9 @@
></AppIcon> ></AppIcon>
{{ $t('views.document.generateQuestion.title') }} {{ $t('views.document.generateQuestion.title') }}
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item <el-dropdown-item @click="openTagSettingDrawer(row)">
@click="openTagSettingDrawer(row)" <AppIcon iconName="app-tag" class="color-secondary"></AppIcon>
>
{{ $t('views.document.tag.setting') }} {{ $t('views.document.tag.setting') }}
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item <el-dropdown-item
@ -676,15 +677,15 @@
:workspaceId="knowledgeDetail?.workspace_id" :workspaceId="knowledgeDetail?.workspace_id"
/> />
<GenerateRelatedDialog ref="GenerateRelatedDialogRef" @refresh="getList" :apiType="apiType" /> <GenerateRelatedDialog ref="GenerateRelatedDialogRef" @refresh="getList" :apiType="apiType" />
<TagDrawer ref="tagDrawerRef"/> <TagDrawer ref="tagDrawerRef" />
<TagSettingDrawer ref="tagSettingDrawerRef" :knowledge-tags="knowledgeTags"/> <TagSettingDrawer ref="tagSettingDrawerRef" />
<AddTagDialog ref="addTagDialogRef" @addTags="addTags" :knowledge-tags="knowledgeTags"/> <AddTagDialog ref="addTagDialogRef" @addTags="addTags" :apiType="apiType" />
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted, onBeforeUnmount, computed } from 'vue' import { ref, onMounted, onBeforeUnmount, computed } from 'vue'
import { useRouter, useRoute, onBeforeRouteLeave, onBeforeRouteUpdate } from 'vue-router' import { useRouter, useRoute, onBeforeRouteLeave, onBeforeRouteUpdate } from 'vue-router'
import { ElTable } from 'element-plus' import type { ElTable } from 'element-plus'
import ImportDocumentDialog from './component/ImportDocumentDialog.vue' import ImportDocumentDialog from './component/ImportDocumentDialog.vue'
import SyncWebDialog from '@/views/knowledge/component/SyncWebDialog.vue' import SyncWebDialog from '@/views/knowledge/component/SyncWebDialog.vue'
import SelectKnowledgeDialog from './component/SelectKnowledgeDialog.vue' import SelectKnowledgeDialog from './component/SelectKnowledgeDialog.vue'
@ -700,9 +701,9 @@ import { TaskType, State } from '@/utils/status'
import { t } from '@/locales' import { t } from '@/locales'
import permissionMap from '@/permission' import permissionMap from '@/permission'
import { loadSharedApi } from '@/utils/dynamics-api/shared-api' import { loadSharedApi } from '@/utils/dynamics-api/shared-api'
import TagDrawer from "./tag/TagDrawer.vue"; import TagDrawer from './tag/TagDrawer.vue'
import TagSettingDrawer from "./tag/TagSettingDrawer.vue"; import TagSettingDrawer from './tag/TagSettingDrawer.vue'
import AddTagDialog from "@/views/document/tag/MulAddTagDialog.vue"; import AddTagDialog from '@/views/document/tag/MulAddTagDialog.vue'
const route = useRoute() const route = useRoute()
const router = useRouter() const router = useRouter()
@ -1020,15 +1021,14 @@ function syncMulDocument() {
confirmButtonClass: 'danger', confirmButtonClass: 'danger',
}) })
.then(() => { .then(() => {
loadSharedApi({type: 'document', systemType: apiType.value}) loadSharedApi({ type: 'document', systemType: apiType.value })
.putMulSyncDocument(id, arr, loading) .putMulSyncDocument(id, arr, loading)
.then(() => { .then(() => {
MsgSuccess(t('views.document.sync.successMessage')) MsgSuccess(t('views.document.sync.successMessage'))
getList() getList()
}) })
}) })
.catch(() => { .catch(() => {})
})
} }
function syncLarkMulDocument() { function syncLarkMulDocument() {
@ -1239,7 +1239,7 @@ function openTagDrawer() {
const tagSettingDrawerRef = ref() const tagSettingDrawerRef = ref()
function openTagSettingDrawer(doc: any) { function openTagSettingDrawer(doc: any) {
tagSettingDrawerRef.value.open(doc) tagSettingDrawerRef.value.open(doc)
} }
const addTagDialogRef = ref() const addTagDialogRef = ref()
@ -1251,8 +1251,8 @@ function openAddTagDialog() {
function addTags(tags: any) { function addTags(tags: any) {
const arr: string[] = multipleSelection.value.map((v) => v.id) const arr: string[] = multipleSelection.value.map((v) => v.id)
loadSharedApi({type: 'document', systemType: apiType.value}) loadSharedApi({ type: 'document', systemType: apiType.value })
.postMulDocumentTags(id, {tag_ids: tags, document_ids: arr}, loading) .postMulDocumentTags(id, { tag_ids: tags, document_ids: arr }, loading)
.then(() => { .then(() => {
addTagDialogRef.value?.close() addTagDialogRef.value?.close()
getList() getList()
@ -1260,15 +1260,6 @@ function addTags(tags: any) {
}) })
} }
const knowledgeTags = ref<any[]>([])
function getTags() {
loadSharedApi({type: 'knowledge', systemType: apiType.value, isShared: isShared.value})
.getTags(id, {}, loading)
.then((res: any) => {
knowledgeTags.value = res.data
})
}
onMounted(() => { onMounted(() => {
getDetail() getDetail()
if (beforePagination.value) { if (beforePagination.value) {
@ -1279,7 +1270,6 @@ onMounted(() => {
filterMethod.value = beforeSearch.value['filterMethod'] filterMethod.value = beforeSearch.value['filterMethod']
} }
getList() getList()
getTags()
// //
initInterval() initInterval()
}) })

View File

@ -3,6 +3,7 @@
v-model="dialogVisible" v-model="dialogVisible"
:title="currentTagKey ? $t('views.document.tag.addValue') : $t('views.document.tag.create')" :title="currentTagKey ? $t('views.document.tag.addValue') : $t('views.document.tag.create')"
:before-close="close" :before-close="close"
append-to-body
> >
<el-form <el-form
ref="FormRef" ref="FormRef"
@ -12,7 +13,7 @@
@submit.prevent @submit.prevent
> >
<el-scrollbar> <el-scrollbar>
<el-row :gutter="8" align="bottom" style="margin-right: 10px" class="tag-list-max-list"> <el-row :gutter="8" style="margin-right: 10px" class="tag-list-max-list">
<template v-for="(tag, index) in tags" :key="tag"> <template v-for="(tag, index) in tags" :key="tag">
<el-col :span="12"> <el-col :span="12">
<el-form-item <el-form-item
@ -26,7 +27,7 @@
> >
<el-input <el-input
v-model="tag.key" v-model="tag.key"
:disabled="currentTagKey" :disabled="currentTagKey? true : false"
class="w-full" class="w-full"
:placeholder="$t('views.document.tag.requiredMessage1')" :placeholder="$t('views.document.tag.requiredMessage1')"
></el-input> ></el-input>
@ -55,7 +56,7 @@
link link
type="info" type="info"
@click="deleteTag(index)" @click="deleteTag(index)"
class="mb-24" :style="{ marginTop: index === 0 ? '35px' : '5px' }"
> >
<AppIcon iconName="app-delete"></AppIcon> <AppIcon iconName="app-delete"></AppIcon>
</el-button> </el-button>
@ -124,7 +125,7 @@ const submit = () => {
.postTags(id, tags.value, loading) .postTags(id, tags.value, loading)
.then((res: any) => { .then((res: any) => {
close() close()
emit('refresh') emit('refresh', currentTagKey.value)
}) })
}) })
} }

View File

@ -1,52 +1,98 @@
<template> <template>
<el-dialog v-model="dialogVisible" :title="$t('views.document.tag.add')" :before-close="close"> <el-dialog v-model="dialogVisible" :title="$t('views.document.tag.addTag')" :before-close="close">
<el-form <el-form
ref="FormRef" ref="FormRef"
:model="{ tags }" :model="{ tagList }"
label-position="top" label-position="top"
require-asterisk-position="right" require-asterisk-position="right"
@submit.prevent @submit.prevent
> >
<div class="flex-between flex" v-for="(tag, index) in tags" :key="tag"> <el-scrollbar>
<el-form-item <el-row :gutter="8" style="margin-right: 10px" class="tag-list-max-list">
:label="index === 0 ? $t('views.document.tag.key') : ''" <template v-for="(tag, index) in tagList" :key="tag">
:prop="`tags.${index}.key`" <el-col :span="12">
style="width: 50%" <el-form-item
:rules="{ :label="index === 0 ? $t('views.document.tag.key') : ''"
required: true, :prop="`tagList.${index}.key`"
message: $t('views.document.tag.requiredMessage1'), :rules="{
trigger: 'blur', required: true,
}" message: $t('views.document.tag.requiredMessage1'),
> trigger: 'blur',
<el-select v-model="tag.key" @change="tagKeyChange(tag)" filterable> }"
<el-option >
v-for="op in keyOptions" <el-select
:key="op" v-model="tag.key"
:value="op.key" @change="tagKeyChange(tag)"
:label="op.key" filterable
></el-option> :placeholder="$t('views.document.tag.requiredMessage1')"
</el-select> :loading="optionLoading"
</el-form-item> >
<el-form-item <el-option
:label="index === 0 ? $t('views.document.tag.value') : ''" v-for="op in keyOptions"
:prop="`tags.${index}.value`" :key="op"
style="width: 50%" :value="op.key"
:rules="{ :label="op.key"
required: true, ></el-option>
message: $t('views.document.tag.requiredMessage2'), <template #footer>
trigger: 'blur', <slot name="footer">
}" <div class="w-full text-left cursor">
> <el-button type="primary" link @click="openCreateTagDialog()">
<el-select v-model="tag.value" filterable> <AppIcon iconName="app-add-outlined" class="mr-4"></AppIcon>
<el-option {{ $t('views.document.tag.create') }}
v-for="op in tag.valueOptions" </el-button>
:key="op" </div>
:value="op.id" </slot>
:label="op.value" </template>
></el-option> </el-select>
</el-select> </el-form-item>
</el-form-item> </el-col>
</div> <el-col :span="11">
<el-form-item
:label="index === 0 ? $t('views.document.tag.value') : ''"
:prop="`tagList.${index}.value`"
:rules="{
required: true,
message: $t('views.document.tag.requiredMessage2'),
trigger: 'blur',
}"
>
<el-select
v-model="tag.value"
filterable
:placeholder="$t('views.document.tag.requiredMessage2')"
>
<el-option
v-for="op in tag.valueOptions"
:key="op"
:value="op.id"
:label="op.value"
></el-option>
<template #footer>
<slot name="footer">
<div class="w-full text-left cursor">
<el-button type="primary" link @click="openCreateTagDialog(tag)">
<AppIcon iconName="app-add-outlined" class="mr-4"></AppIcon>
{{ $t('views.document.tag.createValue') }}
</el-button>
</div>
</slot>
</template>
</el-select>
</el-form-item>
</el-col>
<el-col :span="1">
<el-button
:disabled="index === 0"
text
@click="deleteTag(index)"
:style="{ marginTop: index === 0 ? '35px' : '5px' }"
>
<AppIcon iconName="app-delete"></AppIcon>
</el-button>
</el-col>
</template>
</el-row>
</el-scrollbar>
</el-form> </el-form>
<el-button link type="primary" @click="add"> <el-button link type="primary" @click="add">
@ -60,26 +106,40 @@
<el-button type="primary" @click="submit">{{ $t('common.confirm') }}</el-button> <el-button type="primary" @click="submit">{{ $t('common.confirm') }}</el-button>
</div> </div>
</template> </template>
<CreateTagDialog ref="createTagDialogRef" @refresh="getTags" />
</el-dialog> </el-dialog>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue' import { ref, computed } from 'vue'
import { useRoute } from 'vue-router'
import { loadSharedApi } from '@/utils/dynamics-api/shared-api'
import CreateTagDialog from './CreateTagDialog.vue'
const emit = defineEmits(['addTags']) const emit = defineEmits(['addTags'])
const props = defineProps({ const props = defineProps<{
knowledgeTags: { apiType: 'systemShare' | 'workspace' | 'systemManage' | 'workspaceShare'
type: Array, }>()
default: () => [],
}, const route = useRoute()
const {
params: { id, folderId }, // idknowledgeID
} = route as any
const isShared = computed(() => {
return folderId === 'share'
}) })
const optionLoading = ref<boolean>(false)
const FormRef = ref() const FormRef = ref()
const dialogVisible = ref<boolean>(false) const dialogVisible = ref<boolean>(false)
const tags = ref<Array<any>>([]) const tagList = ref<Array<any>>([])
const keyOptions = ref() const keyOptions = ref()
const add = () => { const add = () => {
tags.value.push({}) tagList.value.push({})
}
const deleteTag = (index: number) => {
tagList.value.splice(index, 1)
} }
function tagKeyChange(tag: any) { function tagKeyChange(tag: any) {
@ -93,15 +153,34 @@ const submit = () => {
if (!valid) return if (!valid) return
emit( emit(
'addTags', 'addTags',
tags.value.map((tag) => tag.value), tagList.value.map((tag) => tag.value),
) )
}) })
} }
function getTags(Key?: string) {
loadSharedApi({ type: 'knowledge', systemType: props.apiType, isShared: isShared.value })
.getTags(id, {}, optionLoading)
.then((res: any) => {
if (Key) {
const index = res.data.findIndex((op: any) => op.key === Key)
tagList.value[index].valueOptions = res.data[index].values
} else {
keyOptions.value = res.data
}
})
}
const createTagDialogRef = ref()
function openCreateTagDialog(row?: any) {
createTagDialogRef.value?.open(row)
}
const open = () => { const open = () => {
getTags()
dialogVisible.value = true dialogVisible.value = true
tags.value = [{}] tagList.value = [{}]
keyOptions.value = props.knowledgeTags
} }
const close = () => { const close = () => {

View File

@ -3,7 +3,7 @@
<template #header> <template #header>
<h4>{{ $t('views.document.tag.setting') }}</h4> <h4>{{ $t('views.document.tag.setting') }}</h4>
</template> </template>
<div class="flex-between"> <div class="flex-between mb-16">
<div> <div>
<el-button type="primary" @click="openAddTagDialog()"> <el-button type="primary" @click="openAddTagDialog()">
{{ $t('views.document.tag.addTag') }} {{ $t('views.document.tag.addTag') }}
@ -18,6 +18,7 @@
class="w-240" class="w-240"
@change="getList" @change="getList"
clearable clearable
:placeholder="$t('common.search')"
/> />
</div> </div>
<el-table <el-table
@ -26,7 +27,7 @@
v-loading="loading" v-loading="loading"
@selection-change="handleSelectionChange" @selection-change="handleSelectionChange"
> >
<el-table-column type="selection" width="55"/> <el-table-column type="selection" width="55" />
<el-table-column :label="$t('views.document.tag.key')"> <el-table-column :label="$t('views.document.tag.key')">
<template #default="{ row }"> <template #default="{ row }">
<div class="flex-between"> <div class="flex-between">
@ -34,42 +35,37 @@
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column :label="$t('views.document.tag.value')"> <el-table-column :label="$t('views.document.tag.value')" class-name="border-l">
<template #default="{ row }"> <template #default="{ row }">
<div class="flex-between"> {{ row.value }}
{{ row.value }} </template>
<div> </el-table-column>
<el-button link> <el-table-column :label="$t('common.operation')" align="left" width="100" fixed="right">
<AppIcon iconName="app-delete" class="mr-4" @click="delTagValue(row)"/> <template #default="{ row }">
</el-button> <el-tooltip effect="dark" :content="$t('common.delete')">
</div> <el-button type="primary" text @click.stop="delTagValue(row)">
</div> <AppIcon iconName="app-delete" />
</el-button>
</el-tooltip>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
</el-drawer> </el-drawer>
<AddTagDialog ref="addTagDialogRef" @addTags="addTags" :knowledge-tags="knowledgeTags"/> <AddTagDialog ref="addTagDialogRef" @addTags="addTags" :apiType="apiType" />
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { computed, ref } from 'vue' import { computed, ref } from 'vue'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
import { loadSharedApi } from "@/utils/dynamics-api/shared-api.ts" import { loadSharedApi } from '@/utils/dynamics-api/shared-api.ts'
import { MsgConfirm } from "@/utils/message.ts"; import { MsgConfirm } from '@/utils/message.ts'
import { t } from "@/locales"; import { t } from '@/locales'
import AddTagDialog from "@/views/document/tag/MulAddTagDialog.vue"; import AddTagDialog from '@/views/document/tag/MulAddTagDialog.vue'
const emit = defineEmits(['refresh']) const emit = defineEmits(['refresh'])
const props = defineProps({
knowledgeTags: {
type: Array,
default: () => []
}
})
const route = useRoute() const route = useRoute()
const { const {
params: {id}, // idknowledgeID params: { id, folderId }, // idknowledgeID
} = route as any } = route as any
const apiType = computed(() => { const apiType = computed(() => {
@ -82,6 +78,10 @@ const apiType = computed(() => {
} }
}) })
const isShared = computed(() => {
return folderId === 'share'
})
const document_id = ref('') const document_id = ref('')
const loading = ref(false) const loading = ref(false)
const debugVisible = ref(false) const debugVisible = ref(false)
@ -98,7 +98,7 @@ const tableData = computed(() => {
id: value.id, id: value.id,
key: tag.key, key: tag.key,
value: value.value, value: value.value,
keyIndex: index // keyIndex: index, //
}) })
}) })
} }
@ -106,33 +106,31 @@ const tableData = computed(() => {
return result return result
}) })
// //
const spanMethod = ({row, column, rowIndex, columnIndex}: any) => { const spanMethod = ({ row, column, rowIndex, columnIndex }: any) => {
if (columnIndex === 0 || columnIndex === 1) { // key (1) if (columnIndex === 0 || columnIndex === 1) {
// key (1)
if (row.keyIndex === 0) { if (row.keyIndex === 0) {
// key // key
const sameKeyCount = tableData.value.filter(item => item.key === row.key).length const sameKeyCount = tableData.value.filter((item) => item.key === row.key).length
return { return {
rowspan: sameKeyCount, rowspan: sameKeyCount,
colspan: 1 colspan: 1,
} }
} else { } else {
return { return {
rowspan: 0, rowspan: 0,
colspan: 0 colspan: 0,
} }
} }
} }
} }
const multipleSelection = ref<any[]>([]) const multipleSelection = ref<any[]>([])
const handleSelectionChange = (val: any[]) => { const handleSelectionChange = (val: any[]) => {
multipleSelection.value = val multipleSelection.value = val
} }
function batchDelete() { function batchDelete() {
MsgConfirm(t('views.document.tag.deleteConfirm'), t('views.document.tag.deleteTip'), { MsgConfirm(t('views.document.tag.deleteConfirm'), t('views.document.tag.deleteTip'), {
confirmButtonText: t('common.delete'), confirmButtonText: t('common.delete'),
@ -141,42 +139,44 @@ function batchDelete() {
.then(() => { .then(() => {
const tagsToDelete = multipleSelection.value.reduce((acc, item) => { const tagsToDelete = multipleSelection.value.reduce((acc, item) => {
// keyvalue id // keyvalue id
const sameKeyItems = tableData.value.filter(data => data.key === item.key) const sameKeyItems = tableData.value.filter((data) => data.key === item.key)
const sameKeyIds = sameKeyItems.map(data => data.id) const sameKeyIds = sameKeyItems.map((data) => data.id)
return [...acc, ...sameKeyIds] return [...acc, ...sameKeyIds]
}, [] as string[]) }, [] as string[])
loadSharedApi({type: 'document', systemType: apiType.value}) loadSharedApi({ type: 'document', systemType: apiType.value })
.delMulDocumentTag(id, document_id.value, tagsToDelete, loading) .delMulDocumentTag(id, document_id.value, tagsToDelete, loading)
.then(() => { .then(() => {
getList() getList()
}) })
}) })
.catch(() => { .catch(() => {})
})
} }
function delTagValue(row: any) { function delTagValue(row: any) {
MsgConfirm(t('views.document.tag.deleteConfirm') + row.key + '-' + row.value, t('views.document.tag.deleteTip'), { MsgConfirm(
confirmButtonText: t('common.delete'), t('views.document.tag.deleteConfirm') + row.key + '-' + row.value,
confirmButtonClass: 'danger', t('views.document.tag.deleteTip'),
}) {
confirmButtonText: t('common.delete'),
confirmButtonClass: 'danger',
},
)
.then(() => { .then(() => {
loadSharedApi({type: 'document', systemType: apiType.value}) loadSharedApi({ type: 'document', systemType: apiType.value })
.delMulDocumentTag(id, document_id.value, [row.id], loading) .delMulDocumentTag(id, document_id.value, [row.id], loading)
.then(() => { .then(() => {
getList() getList()
}) })
}) })
.catch(() => { .catch(() => {})
})
} }
function getList() { function getList() {
const params = { const params = {
...(filterText.value && {name: filterText.value}), ...(filterText.value && { name: filterText.value }),
} }
loadSharedApi({type: 'document', systemType: apiType.value}) loadSharedApi({ type: 'document', systemType: apiType.value })
.getDocumentTags(id, document_id.value, params, loading) .getDocumentTags(id, document_id.value, params, loading)
.then((res: any) => { .then((res: any) => {
tags.value = res.data tags.value = res.data
@ -190,7 +190,7 @@ function openAddTagDialog() {
} }
function addTags(tags: any) { function addTags(tags: any) {
loadSharedApi({type: 'document', systemType: apiType.value}) loadSharedApi({ type: 'document', systemType: apiType.value })
.postDocumentTags(id, document_id.value, tags, loading) .postDocumentTags(id, document_id.value, tags, loading)
.then(() => { .then(() => {
addTagDialogRef.value?.close() addTagDialogRef.value?.close()
@ -198,8 +198,6 @@ function addTags(tags: any) {
}) })
} }
const open = (doc: any) => { const open = (doc: any) => {
debugVisible.value = true debugVisible.value = true
document_id.value = doc.id document_id.value = doc.id

View File

@ -219,7 +219,7 @@
<template #dropdown> <template #dropdown>
<el-dropdown-menu> <el-dropdown-menu>
<el-dropdown-item <el-dropdown-item
@click.stop="openAuthorization(row)" @click.stop="openParamSetting(row)"
v-if=" v-if="
(row.model_type === 'TTS' || (row.model_type === 'TTS' ||
row.model_type === 'LLM' || row.model_type === 'LLM' ||

View File

@ -22,7 +22,7 @@
> >
<template #prefix> <template #prefix>
<el-icon> <el-icon>
<Search></Search> <Search />
</el-icon> </el-icon>
</template> </template>
</el-input> </el-input>

View File

@ -617,13 +617,13 @@ export const menuNodes = [
list: [ list: [
aiChatNode, aiChatNode,
intentNode, intentNode,
imageGenerateNode,
imageUnderstandNode,
videoUnderstandNode,
textToSpeechNode, textToSpeechNode,
speechToTextNode, speechToTextNode,
imageGenerateNode,
imageUnderstandNode,
textToVideoNode, textToVideoNode,
imageToVideoNode, imageToVideoNode,
videoUnderstandNode,
questionNode, questionNode,
], ],
}, },

View File

@ -89,8 +89,7 @@
:step-strictly="true" :step-strictly="true"
/> />
</el-form-item> </el-form-item>
<el-form-item <el-form-item>
>
<template #label> <template #label>
<div class="flex-between"> <div class="flex-between">
<div> <div>
@ -100,48 +99,44 @@
> >
</div> </div>
<el-button @click="addClassfiyBranch" type="primary" size="large" link> <el-button @click="addClassfiyBranch" type="primary" size="large" link>
<el-icon><Plus /></el-icon> <AppIcon iconName="app-add-outlined" />
</el-button> </el-button>
</div> </div>
</template> </template>
<div> <div>
<div <div v-for="(item, index) in form_data.branch" :key="item.id" class="mb-8">
v-for="(item, index) in form_data.branch" <el-form-item
:key="item.id" :prop="`branch.${index}.content`"
class="mb-8" :rules="{
> message: $t('views.applicationWorkflow.nodes.intentNode.classify.placeholder'),
<el-form-item trigger: 'change',
:prop="`branch.${index}.content`" required: true,
:rules="{ }"
message: $t('views.applicationWorkflow.nodes.intentNode.classify.placeholder'), >
trigger: 'change', <el-row :gutter="12" align="middle">
required: true, <el-col :span="21">
}" <el-input
> v-model="item.content"
<el-row :gutter="12" align="middle"> style="width: 210px"
<el-col :span="21"> :disabled="item.isOther"
<el-input :placeholder="
v-model="item.content" $t('views.applicationWorkflow.nodes.intentNode.classify.placeholder')
style="width: 210px" "
:disabled="item.isOther" />
:placeholder=" </el-col>
$t('views.applicationWorkflow.nodes.intentNode.classify.placeholder') <el-col :span="3">
" <el-button
/> link
</el-col> size="large"
<el-col :span="3"> v-if="!item.isOther"
<el-button :disabled="form_data.branch.filter((b: any) => !b.isOther).length <= 1"
link @click="deleteClassifyBranch(item.id)"
size="large" >
v-if="!item.isOther" <AppIcon iconName="app-delete"></AppIcon>
:disabled="form_data.branch.filter((b: any) => !b.isOther).length <= 1" </el-button>
@click="deleteClassifyBranch(item.id)" </el-col>
> </el-row>
<el-icon><Delete /></el-icon> </el-form-item>
</el-button>
</el-col>
</el-row>
</el-form-item>
</div> </div>
</div> </div>
</el-form-item> </el-form-item>
@ -331,17 +326,21 @@ const IntentClassifyNodeFormRef = ref<FormInstance>()
const modelOptions = ref<any>(null) const modelOptions = ref<any>(null)
const validate = () => { const validate = () => {
return Promise.all([ return Promise.all([
nodeCascaderRef.value ? nodeCascaderRef.value.validate() : Promise.resolve(''), nodeCascaderRef.value ? nodeCascaderRef.value.validate() : Promise.resolve(''),
IntentClassifyNodeFormRef.value?.validate(), IntentClassifyNodeFormRef.value?.validate(),
]).then(() => { ])
if (form_data.value.branch.length != new Set(form_data.value.branch.map((item: any) => item.content)).size) { .then(() => {
throw t('views.applicationWorkflow.nodes.intentNode.error2') if (
} form_data.value.branch.length !=
}).catch((err: any) => { new Set(form_data.value.branch.map((item: any) => item.content)).size
return Promise.reject({ node: props.nodeModel, errMessage: err }) ) {
}) throw t('views.applicationWorkflow.nodes.intentNode.error2')
}
})
.catch((err: any) => {
return Promise.reject({ node: props.nodeModel, errMessage: err })
})
} }
const application = getApplicationDetail() const application = getApplicationDetail()