mirror of
https://gitee.com/myxzgzs/boyue-ui-admin-vue3
synced 2025-08-08 08:22:41 +08:00
105 lines
2.8 KiB
Vue
105 lines
2.8 KiB
Vue
<!-- 知识引用组件 -->
|
||
<template>
|
||
<!-- 知识引用列表 -->
|
||
<div v-if="segments && segments.length > 0" class="mt-10px p-10px rounded-8px bg-[#f5f5f5]">
|
||
<div class="text-14px text-[#666] mb-8px flex items-center">
|
||
<Icon icon="ep:document" class="mr-5px" /> 知识引用
|
||
</div>
|
||
<div class="flex flex-wrap gap-8px">
|
||
<div
|
||
v-for="(doc, index) in documentList"
|
||
:key="index"
|
||
class="p-8px px-12px bg-white rounded-6px cursor-pointer transition-all hover:bg-[#e6f4ff]"
|
||
@click="handleClick(doc)"
|
||
>
|
||
<div class="text-14px text-[#333] mb-4px">
|
||
{{ doc.title }}
|
||
<span class="text-12px text-[#999] ml-4px">({{ doc.segments.length }} 条)</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 知识引用详情弹窗 -->
|
||
<el-popover
|
||
v-model:visible="dialogVisible"
|
||
:width="600"
|
||
trigger="click"
|
||
placement="top-start"
|
||
:offset="55"
|
||
popper-class="knowledge-popover"
|
||
>
|
||
<template #reference>
|
||
<div ref="documentRef"></div>
|
||
</template>
|
||
<template #default>
|
||
<div class="text-16px font-bold mb-12px">{{ document?.title }}</div>
|
||
<div class="max-h-[60vh] overflow-y-auto">
|
||
<div
|
||
v-for="(segment, index) in document?.segments"
|
||
:key="index"
|
||
class="p-12px border-b-solid border-b-[#eee] last:border-b-0"
|
||
>
|
||
<div
|
||
class="block mb-8px px-8px py-2px bg-[#f5f5f5] rounded-4px text-12px text-[#666] w-fit"
|
||
>
|
||
分段 {{ segment.id }}
|
||
</div>
|
||
<div class="text-14px leading-[1.6] text-[#333] mt-[10px]">
|
||
{{ segment.content }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
</el-popover>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
const props = defineProps<{
|
||
segments: {
|
||
id: number
|
||
documentId: number
|
||
documentName: string
|
||
content: string
|
||
}[]
|
||
}>()
|
||
|
||
const document = ref<{
|
||
id: number
|
||
title: string
|
||
segments: {
|
||
id: number
|
||
content: string
|
||
}[]
|
||
} | null>(null) // 知识库文档列表
|
||
const dialogVisible = ref(false) // 知识引用详情弹窗
|
||
const documentRef = ref<HTMLElement>() // 知识引用详情弹窗 Ref
|
||
|
||
/** 按照 document 聚合 segments */
|
||
const documentList = computed(() => {
|
||
if (!props.segments) return []
|
||
|
||
const docMap = new Map()
|
||
props.segments.forEach((segment) => {
|
||
if (!docMap.has(segment.documentId)) {
|
||
docMap.set(segment.documentId, {
|
||
id: segment.documentId,
|
||
title: segment.documentName,
|
||
segments: []
|
||
})
|
||
}
|
||
docMap.get(segment.documentId).segments.push({
|
||
id: segment.id,
|
||
content: segment.content
|
||
})
|
||
})
|
||
return Array.from(docMap.values())
|
||
})
|
||
|
||
/** 点击 document 处理 */
|
||
const handleClick = (doc: any) => {
|
||
document.value = doc
|
||
dialogVisible.value = true
|
||
}
|
||
</script>
|