feat: web知识库

This commit is contained in:
wangdan-fit2cloud 2024-01-19 17:51:27 +08:00
parent cf1dac76cd
commit 5e407c86ff
12 changed files with 136 additions and 35 deletions

View File

@ -88,15 +88,17 @@ const postDocument: (dataset_id: string, data: any) => Promise<Result<any>> = (
* dataset_id, document_id,
* {
"name": "string",
"is_active": true
"is_active": true,
"meta": {}
}
*/
const putDocument: (dataset_id: string, document_id: string, data: any) => Promise<Result<any>> = (
dataset_id,
document_id,
data: any
) => {
return put(`${prefix}/${dataset_id}/document/${document_id}`, data)
const putDocument: (
dataset_id: string,
document_id: string,
data: any,
loading?: Ref<boolean>
) => Promise<Result<any>> = (dataset_id, document_id, data: any, loading) => {
return put(`${prefix}/${dataset_id}/document/${document_id}`, data, undefined, loading)
}
/**

View File

Before

Width:  |  Height:  |  Size: 464 B

After

Width:  |  Height:  |  Size: 464 B

View File

@ -85,6 +85,7 @@
plain
size="small"
@click="openParagraph(item)"
:disabled="item.paragraph_list?.length === 0"
>引用分段{{ item.paragraph_list?.length }}</el-button
>
<el-tag type="info" effect="plain">

View File

@ -8,7 +8,11 @@
<div class="flex-between">
<div class="flex align-center">
<slot name="icon">
<AppAvatar class="mr-12" shape="square" :size="32">
<AppAvatar v-if="data.type === '1'" class="mr-8 avatar-purple" shape="square" :size="32">
<img src="@/assets/icon_web.svg" style="width: 58%" alt="" />
</AppAvatar>
<AppAvatar v-else class="mr-12" shape="square" :size="32">
<img src="@/assets/icon_document.svg" style="width: 58%" alt="" />
</AppAvatar>
</slot>

View File

@ -1,9 +1,37 @@
<template>
<div class="ml-8 mt-8 mb-16 flex">
<back-button :to="activeMenu"></back-button>
<el-dropdown placement="top" trigger="click" @command="changeMenu" class="w-full" style="display: block;">
<el-dropdown
placement="top"
trigger="click"
@command="changeMenu"
class="w-full"
style="display: block"
>
<div class="flex-between">
<div class="ellipsis">{{ currentName }}</div>
<div class="flex align-center">
<AppAvatar
v-if="isApplication"
:name="currentName"
pinyinColor
shape="square"
class="mr-8"
:size="24"
/>
<AppAvatar
v-else-if="isDataset && currentType === '1'"
class="mr-8 avatar-purple"
shape="square"
:size="24"
>
<img src="@/assets/icon_web.svg" style="width: 58%" alt="" />
</AppAvatar>
<AppAvatar v-else class="mr-8" shape="square" :size="24">
<img src="@/assets/icon_document.svg" style="width: 58%" alt="" />
</AppAvatar>
<div class="ellipsis">{{ currentName }}</div>
</div>
<el-button text>
<el-icon><CaretBottom /></el-icon>
</el-button>
@ -22,10 +50,17 @@
shape="square"
:size="24"
/>
<AppAvatar v-else-if="isDataset" class="mr-12" shape="square" :size="24">
<AppAvatar
v-else-if="isDataset && item.type === '1'"
class="mr-12 avatar-purple"
shape="square"
:size="24"
>
<img src="@/assets/icon_web.svg" style="width: 58%" alt="" />
</AppAvatar>
<AppAvatar v-else class="mr-12" shape="square" :size="24">
<img src="@/assets/icon_document.svg" style="width: 58%" alt="" />
</AppAvatar>
<span class="ellipsis"> {{ item?.name }}</span>
</div>
</el-dropdown-item>
@ -76,6 +111,12 @@ const currentName = computed(() => {
} = route
return list.value?.filter((v) => v.id === id)?.[0]?.name
})
const currentType = computed(() => {
const {
params: { id }
} = route
return list.value?.filter((v) => v.id === id)?.[0]?.type
})
const isApplication = computed(() => {
const { meta } = route as any

View File

@ -324,6 +324,12 @@ h4 {
border: none;
}
.purple-tag {
background: #f2ebfe;
color: #7f3bf5;
border-color: #e0d7f0;
}
/*
card 无边框无阴影 灰色背景
*/
@ -386,6 +392,10 @@ h4 {
background: var(--el-color-primary-light-4);
}
.avatar-purple {
background: #7f3bf5;
}
.success {
color: var(--el-color-success);
}

View File

@ -196,7 +196,16 @@
<el-card class="relate-dataset-card" shadow="never">
<div class="flex-between">
<div class="flex align-center">
<AppAvatar class="mr-12" shape="square" :size="32">
<AppAvatar
v-if="realatedObject(datasetList, item, 'id')?.type === '1'"
class="mr-8 avatar-purple"
shape="square"
:size="32"
>
<img src="@/assets/icon_web.svg" style="width: 58%" alt="" />
</AppAvatar>
<AppAvatar v-else class="mr-12" shape="square" :size="32">
<img src="@/assets/icon_document.svg" style="width: 58%" alt="" />
</AppAvatar>
<div class="ellipsis">

View File

@ -31,9 +31,22 @@
class="cursor"
@click="router.push({ path: `/dataset/${item.id}/document` })"
>
<template #icon>
<AppAvatar
v-if="item.type === '1'"
class="mr-8 avatar-purple"
shape="square"
:size="32"
>
<img src="@/assets/icon_web.svg" style="width: 58%" alt="" />
</AppAvatar>
<AppAvatar v-else class="mr-8" shape="square" :size="32">
<img src="@/assets/icon_document.svg" style="width: 58%" alt="" />
</AppAvatar>
</template>
<div class="delete-button">
<el-tag v-if="item.type === '0'">通用型</el-tag>
<el-tag v-else-if="item.type === '1'" type="warning">Web 站点</el-tag>
<el-tag class="purple-tag" v-else-if="item.type === '1'" type="warning">Web 站点</el-tag>
</div>
<template #footer>

View File

@ -57,6 +57,7 @@ const form = ref<any>({
source_url: '',
selector: ''
})
const documentId = ref('')
const rules = reactive({
source_url: [{ required: true, message: '请输入 Web 根地址', trigger: 'blur' }]
@ -76,6 +77,8 @@ watch(dialogVisible, (bool) => {
const open = (row: any) => {
if (row) {
documentId.value = row.id
form.value = row.meta
isImport.value = false
} else {
isImport.value = true
@ -84,15 +87,26 @@ const open = (row: any) => {
}
const submit = () => {
const obj = {
source_url_list: form.value.source_url.split('\n'),
selector: form.value.selector
if (isImport.value) {
const obj = {
source_url_list: form.value.source_url.split('\n'),
selector: form.value.selector
}
documentApi.postWebDocument(id, obj, loading).then((res: any) => {
MsgSuccess('导入成功')
emit('refresh')
dialogVisible.value = false
})
} else {
const obj = {
meta: form.value
}
documentApi.putDocument(id, documentId.value, obj, loading).then((res) => {
MsgSuccess('设置成功')
emit('refresh')
dialogVisible.value = false
})
}
documentApi.postWebDocument(id, obj, loading).then((res: any) => {
MsgSuccess('导入成功')
emit('refresh')
dialogVisible.value = false
})
}
defineExpose({ open })

View File

@ -310,18 +310,11 @@ function deleteDocument(row: any) {
更新名称或状态
*/
function updateData(documentId: string, data: any, msg: string) {
loading.value = true
documentApi
.putDocument(id, documentId, data)
.then((res) => {
const index = documentData.value.findIndex((v) => v.id === documentId)
documentData.value.splice(index, 1, res.data)
MsgSuccess(msg)
loading.value = false
})
.catch(() => {
loading.value = false
})
documentApi.putDocument(id, documentId, data, loading).then((res) => {
const index = documentData.value.findIndex((v) => v.id === documentId)
documentData.value.splice(index, 1, res.data)
MsgSuccess(msg)
})
}
function changeState(bool: Boolean, row: any) {

View File

@ -35,7 +35,20 @@
>
<template #default="{ node, data }">
<span class="flex align-center">
<AppAvatar v-if="!node.isLeaf" class="mr-12" shape="square" :size="24">
<AppAvatar
v-if="!node.isLeaf && data.type === '1'"
class="mr-12 avatar-purple"
shape="square"
:size="24"
>
<img src="@/assets/icon_web.svg" style="width: 58%" alt="" />
</AppAvatar>
<AppAvatar
v-else-if="!node.isLeaf && data.type === '0'"
class="mr-12"
shape="square"
:size="24"
>
<img src="@/assets/icon_document.svg" style="width: 58%" alt="" />
</AppAvatar>
<span class="ellipsis"> {{ data.name }}</span>

View File

@ -1,6 +1,7 @@
<template>
<LayoutContainer :header="documentDetail?.name" back-to="-1" class="document-detail">
<template #header>
<el-text type="info" v-if="documentDetail?.type==='1'">文档地址{{ documentDetail?.meta?.source_url }}</el-text>
<div class="document-detail__header">
<el-button @click="addParagraph" type="primary" :disabled="loading"> 添加分段 </el-button>
</div>