feat(knowledge): 实现知识库上传功能并优化相关页面

- 新增上传到知识库的 API 接口和相关页面组件- 实现分段查看页面功能
- 优化文档详情页面布局和样式
- 调整知识库创建流程,支持直接上传至知识库
This commit is contained in:
陈昱达
2025-04-22 19:49:42 +08:00
parent 5637496340
commit 26e7ccac12
11 changed files with 125 additions and 37 deletions

View File

@@ -286,3 +286,12 @@ export function mdIndex(params) {
back: true back: true
}) })
} }
// 上传到知识库
export function embedding(data) {
return request({
url: getUrl(`/datasetDocumentEx/split/embedding`),
method: 'post',
data
})
}

View File

@@ -91,24 +91,24 @@
overflow: hidden; overflow: hidden;
} }
} }
.el-dialog__body { //.el-dialog__body {
padding: 30px 15px; // padding: 30px 15px;
width: 96%; // width: 96%;
margin: auto; // margin: auto;
max-height: 55vh; // max-height: 55vh;
overflow: auto; // overflow: auto;
} //}
.el-dialog__footer { //.el-dialog__footer {
text-align: right; // text-align: right;
} //}
.el-dialog__header { //.el-dialog__header {
font-weight: 600; // font-weight: 600;
.el-dialog__title { // .el-dialog__title {
font-size: 20px; // font-size: 20px;
color: #0096fd; // color: #0096fd;
line-height: 28px; // line-height: 28px;
} // }
} //}
.el-collapse-item__header.is-active { .el-collapse-item__header.is-active {
border-bottom: 1px solid #ebeef5; border-bottom: 1px solid #ebeef5;

View File

@@ -1,9 +1,7 @@
<template> <template>
<el-dialog :visible.sync="visible" :title="title"> <el-dialog :visible.sync="visible" :title="title" :append-to-body="appendToBody">
<div slot="default"> <div class="render-dialog-body">
<div class="render-dialog-body"> <slot name="default"></slot>
<slot></slot>
</div>
</div> </div>
<div slot="footer"> <div slot="footer">
<slot name="footer"> <slot name="footer">
@@ -20,6 +18,10 @@ export default {
return {} return {}
}, },
props: { props: {
appendToBody: {
type: Boolean,
default: false
},
visible: { visible: {
type: Boolean, type: Boolean,
default: false default: false

View File

@@ -74,6 +74,15 @@ export default [
title: '知识库新增', title: '知识库新增',
icon: 'el-icon-s-home' icon: 'el-icon-s-home'
} }
},
{
path: '/knowledge/detail/segments',
name: 'knowledge-segments',
component: () => import('@/views/knowledge/detail/components/viewSegments/index.vue'),
meta: {
title: '分段查看',
icon: 'el-icon-s-home'
}
} }
] ]
} }
@@ -135,7 +144,7 @@ export default [
} }
} }
] ]
}, }
] ]
}, },
{ {

View File

@@ -23,7 +23,7 @@
</div> </div>
<!-- 弹窗 --> <!-- 弹窗 -->
<el-dialog title="问答详情" :visible.sync="dialogVisible" width="50%" append-to-body :before-close="handleClose"> <r-dialog title="问答详情" :visible.sync="dialogVisible" width="50%" append-to-body :before-close="handleClose">
<div v-if="activeSegment !== null && descriptions.data && descriptions.data.length > 0"> <div v-if="activeSegment !== null && descriptions.data && descriptions.data.length > 0">
<div class="segment-content"> <div class="segment-content">
<div> <div>
@@ -49,9 +49,9 @@
</div> </div>
</div> </div>
<span slot="footer" class="dialog-footer"> <span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false"> </el-button> <el-button @click="dialogVisible = false" class="render-button"> </el-button>
</span> </span>
</el-dialog> </r-dialog>
</div> </div>
</template> </template>
<script> <script>

View File

@@ -20,26 +20,26 @@
</div> </div>
<!-- 弹窗 --> <!-- 弹窗 -->
<el-dialog title="分段详情" :visible.sync="dialogVisible" width="50%" append-to-body :before-close="handleClose"> <r-dialog title="分段详情" :visible.sync="dialogVisible" width="50%" append-to-body :before-close="handleClose">
<div v-if="activeSegment !== null && descriptions.data && descriptions.data.length > 0"> <div v-if="activeSegment !== null && descriptions.data && descriptions.data.length > 0">
<div class="segment-content"> <div class="segment-content">
{{ descriptions.data[activeSegment].content }} {{ descriptions.data[activeSegment].content }}
<div <div
class="flex align-items-c mt20" class="flex align-items-c mt20"
v-if="descriptions.data[activeSegment].keywords && descriptions.data[activeSegment].keywords.length" v-if="descriptions.data[activeSegment].keywords && descriptions.data[activeSegment].keywords.length"
style="width: max-content" style="flex-wrap: wrap"
> >
<span>关键词 </span> <span>关键词 </span>
<el-tag v-for="(item, index) in descriptions.data[activeSegment].keywords" :key="index" class="mr10" size="mini" type="primary"> <el-tag v-for="(item, index) in descriptions.data[activeSegment].keywords" :key="index" class="mr10 ellipsis" size="mini" type="primary">
{{ item }} {{ item }}
</el-tag> </el-tag>
</div> </div>
</div> </div>
</div> </div>
<span slot="footer" class="dialog-footer"> <span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false"> </el-button> <el-button @click="dialogVisible = false" class="render-button"> </el-button>
</span> </span>
</el-dialog> </r-dialog>
</div> </div>
</template> </template>
<script> <script>

View File

@@ -59,6 +59,7 @@
<!-- 添加预览组件 --> <!-- 添加预览组件 -->
<split-preview <split-preview
:documentId="documentId"
:visible.sync="previewVisible" :visible.sync="previewVisible"
:preview-data="previewData" :preview-data="previewData"
:is-auto-split="activeIndex === 0" :is-auto-split="activeIndex === 0"
@@ -104,7 +105,12 @@ export default {
] ]
} }
}, },
props: {}, props: {
documentId: {
type: String,
default: ''
}
},
watch: {}, watch: {},
filters: {}, filters: {},
methods: { methods: {

View File

@@ -9,16 +9,23 @@
</div> </div>
<span slot="footer" class="dialog-footer"> <span slot="footer" class="dialog-footer">
<el-button size="medium" @click="handleReUpload">重新上传</el-button> <el-button size="medium" @click="handleReUpload">重新上传</el-button>
<el-button size="medium" type="primary" @click="handleConfirm">完成</el-button> <el-button size="medium" type="primary" @click="handleConfirm">下一步</el-button>
<el-button size="medium" type="primary" @click="emitKnowledgeDataset">直接上传至知识库</el-button>
</span> </span>
</el-dialog> </el-dialog>
</div> </div>
</template> </template>
<script> <script>
import { embedding } from '@/api/generatedApi'
export default { export default {
name: 'SplitPreview', name: 'SplitPreview',
props: { props: {
documentId: {
type: String,
default: ''
},
visible: { visible: {
type: Boolean, type: Boolean,
default: false default: false
@@ -44,6 +51,19 @@ export default {
} }
}, },
methods: { methods: {
emitKnowledgeDataset() {
embedding({ documentId: this.documentId }).then(res => {
if (res) {
this.$router.push({
path: '/knowledge/detail/segments',
query: {
documentId: this.documentId,
datasetId: this.$route.query.datasetId
}
})
}
})
},
handleNodeClick() {}, handleNodeClick() {},
handleClose() { handleClose() {
this.$emit('update:visible', false) this.$emit('update:visible', false)

View File

@@ -0,0 +1,40 @@
<template>
<div>
<KnowledgeInfo :form="{ id: this.$route.query.documentId }"></KnowledgeInfo>
<div style="position: absolute;bottom:0;right:10px;width: 100%;height:50px;background: #fff;text-align: right">
<el-button size="medium" @click="back">返回</el-button>
</div>
</div>
</template>
<script>
import KnowledgeInfo from '@/views/track/views/knowledge-info/Index.vue'
export default {
name: 'index',
data() {
return {}
},
props: {},
watch: {},
components: {
KnowledgeInfo
},
filters: {},
methods: {
back() {
this.$router.push({
path: '/knowledge/detail',
query: {
datasetId: this.$route.query.datasetId
}
})
}
},
created() {},
mounted() {},
computed: {}
}
</script>
<style scoped lang="scss">
#index-container {
}
</style>

View File

@@ -19,6 +19,7 @@
v-if="active === 1" v-if="active === 1"
@previewConfirmed="handlePreviewConfirm" @previewConfirmed="handlePreviewConfirm"
@handleReUpload="handleReUpload" @handleReUpload="handleReUpload"
:documentId="documentId"
></step-split-config> ></step-split-config>
<step-words ref="words" v-if="active === 2"></step-words> <step-words ref="words" v-if="active === 2"></step-words>
</transition> </transition>
@@ -54,7 +55,7 @@ export default {
return { return {
visible: false, visible: false,
active: 0, active: 0,
documentId: '1363864715567140864' documentId: '1364315544778543104'
} }
}, },
props: {}, props: {},

View File

@@ -183,12 +183,13 @@ export default {
margin-bottom: 20px; margin-bottom: 20px;
.knowledge-content { .knowledge-content {
min-height: 300px; min-height: 250px;
} }
} }
.full-height { .full-height {
height: calc(100% - 20px); height: 100%;
padding-bottom: 20px;
} }
.mt20 { .mt20 {