Merge pull request #365 from halfss/dev
add Knowledge Base delete and file delete
This commit is contained in:
commit
ff8cecd780
14
api.py
14
api.py
|
|
@ -3,6 +3,7 @@ import json
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
from typing import List, Optional
|
from typing import List, Optional
|
||||||
|
import urllib
|
||||||
|
|
||||||
import nltk
|
import nltk
|
||||||
import pydantic
|
import pydantic
|
||||||
|
|
@ -169,24 +170,27 @@ async def list_docs(
|
||||||
|
|
||||||
|
|
||||||
async def delete_docs(
|
async def delete_docs(
|
||||||
knowledge_base_id: str = Form(...,
|
knowledge_base_id: str = Query(...,
|
||||||
description="Knowledge Base Name(注意此方法仅删除上传的文件并不会删除知识库(FAISS)内数据)",
|
description="Knowledge Base Name(注意此方法仅删除上传的文件并不会删除知识库(FAISS)内数据)",
|
||||||
example="kb1"),
|
example="kb1"),
|
||||||
doc_name: Optional[str] = Form(
|
doc_name: Optional[str] = Query(
|
||||||
None, description="doc name", example="doc_name_1.pdf"
|
None, description="doc name", example="doc_name_1.pdf"
|
||||||
),
|
),
|
||||||
):
|
):
|
||||||
|
knowledge_base_id = urllib.parse.unquote(knowledge_base_id)
|
||||||
if not os.path.exists(os.path.join(UPLOAD_ROOT_PATH, knowledge_base_id)):
|
if not os.path.exists(os.path.join(UPLOAD_ROOT_PATH, knowledge_base_id)):
|
||||||
return {"code": 1, "msg": f"Knowledge base {knowledge_base_id} not found"}
|
return {"code": 1, "msg": f"Knowledge base {knowledge_base_id} not found"}
|
||||||
if doc_name:
|
if doc_name:
|
||||||
doc_path = get_file_path(knowledge_base_id, doc_name)
|
doc_path = get_file_path(knowledge_base_id, doc_name)
|
||||||
if os.path.exists(doc_path):
|
if os.path.exists(doc_path):
|
||||||
os.remove(doc_path)
|
os.remove(doc_path)
|
||||||
|
return BaseResponse(code=200, msg=f"document {doc_name} delete success")
|
||||||
else:
|
else:
|
||||||
BaseResponse(code=1, msg=f"document {doc_name} not found")
|
return BaseResponse(code=1, msg=f"document {doc_name} not found")
|
||||||
|
|
||||||
remain_docs = await list_docs(knowledge_base_id)
|
remain_docs = await list_docs(knowledge_base_id)
|
||||||
if remain_docs["code"] != 0 or len(remain_docs["data"]) == 0:
|
remain_docs = remain_docs.json()
|
||||||
|
if len(remain_docs["data"]) == 0:
|
||||||
shutil.rmtree(get_folder_path(knowledge_base_id), ignore_errors=True)
|
shutil.rmtree(get_folder_path(knowledge_base_id), ignore_errors=True)
|
||||||
else:
|
else:
|
||||||
local_doc_qa.init_knowledge_vector_store(
|
local_doc_qa.init_knowledge_vector_store(
|
||||||
|
|
@ -194,7 +198,7 @@ async def delete_docs(
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
shutil.rmtree(get_folder_path(knowledge_base_id))
|
shutil.rmtree(get_folder_path(knowledge_base_id))
|
||||||
return BaseResponse()
|
return BaseResponse(code=200, msg=f"Knowledge Base {knowledge_base_id} delete success")
|
||||||
|
|
||||||
|
|
||||||
async def local_doc_chat(
|
async def local_doc_chat(
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ onMounted(async () => {
|
||||||
} */
|
} */
|
||||||
|
|
||||||
async function handleDelete(item: any) {
|
async function handleDelete(item: any) {
|
||||||
/* const mid = */await deletefile({ knowledge_base_id: knowledge_base_id.value, doc_name: item })
|
/* const mid = */await deletefile(knowledge_base_id.value, item)
|
||||||
const res = await getfilelist(knowledge_base_id.value)
|
const res = await getfilelist(knowledge_base_id.value)
|
||||||
dataSources.value = res.data.data
|
dataSources.value = res.data.data
|
||||||
}
|
}
|
||||||
|
|
@ -35,7 +35,6 @@ function handleEnter({ uuid }: Chat.History, isEdit: boolean, event: KeyboardEve
|
||||||
if (event.key === 'Enter')
|
if (event.key === 'Enter')
|
||||||
chatStore.updateHistory(uuid, { isEdit })
|
chatStore.updateHistory(uuid, { isEdit })
|
||||||
}
|
}
|
||||||
console.log(`${web_url()}/api/local_doc_qa/upload_file`)
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
@ -51,11 +50,6 @@ console.log(`${web_url()}/api/local_doc_qa/upload_file`)
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<NUploadDragger>
|
<NUploadDragger>
|
||||||
<!-- <div style="margin-bottom: 12px">
|
|
||||||
<NIcon size="48" :depth="3">
|
|
||||||
<archive-icon />
|
|
||||||
</NIcon>
|
|
||||||
</div> -->
|
|
||||||
<NText style="font-size: 16px">
|
<NText style="font-size: 16px">
|
||||||
点击或者拖动文件到该区域来上传
|
点击或者拖动文件到该区域来上传
|
||||||
</NText>
|
</NText>
|
||||||
|
|
@ -73,8 +67,9 @@ console.log(`${web_url()}/api/local_doc_qa/upload_file`)
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<div v-for="(item, index) of dataSources" :key="index">
|
<div v-for="(item, index) of dataSources" :key="index" class="flex items-center">
|
||||||
<a
|
<a
|
||||||
|
style="width:90%"
|
||||||
class="relative flex items-center gap-3 px-3 py-3 break-all border rounded-md cursor-pointer hover:bg-neutral-100 group dark:border-neutral-800 dark:hover:bg-[#24272e]"
|
class="relative flex items-center gap-3 px-3 py-3 break-all border rounded-md cursor-pointer hover:bg-neutral-100 group dark:border-neutral-800 dark:hover:bg-[#24272e]"
|
||||||
>
|
>
|
||||||
<span>
|
<span>
|
||||||
|
|
@ -88,27 +83,28 @@ console.log(`${web_url()}/api/local_doc_qa/upload_file`)
|
||||||
/>
|
/>
|
||||||
<span v-else>{{ item }}</span>
|
<span v-else>{{ item }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="absolute z-10 flex visible right-1">
|
|
||||||
<template v-if="item.isEdit">
|
</a>
|
||||||
<!-- <button class="p-1" @click="handleEdit(item, false, $event)">
|
<div class="absolute z-10 flex visible right-1">
|
||||||
|
<template v-if="item.isEdit">
|
||||||
|
<!-- <button class="p-1" @click="handleEdit(item, false, $event)">
|
||||||
<SvgIcon icon="ri:save-line" />
|
<SvgIcon icon="ri:save-line" />
|
||||||
</button> -->
|
</button> -->
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<!-- <button class="p-1">
|
<!-- <button class="p-1">
|
||||||
<SvgIcon icon="ri:edit-line" @click="handleEdit(item, true, $event)" />
|
<SvgIcon icon="ri:edit-line" @click="handleEdit(item, true, $event)" />
|
||||||
</button> -->
|
</button> -->
|
||||||
<NPopconfirm placement="bottom" @positive-click="handleDelete(item)">
|
<NPopconfirm placement="bottom" @positive-click="handleDelete(item)">
|
||||||
<template #trigger>
|
<template #trigger>
|
||||||
<button class="p-1">
|
<button class="p-1">
|
||||||
<!-- <SvgIcon icon="ri:delete-bin-line" /> -->
|
<SvgIcon icon="ri:delete-bin-line" />
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
确定删除此文件?
|
确定删除此文件?
|
||||||
</NPopconfirm>
|
</NPopconfirm>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
<script setup lang='ts'>
|
<script setup lang='ts'>
|
||||||
import { NButton, NForm, NFormItem, NInput } from 'naive-ui'
|
import { NButton, NForm, NFormItem, NInput, NPopconfirm } from 'naive-ui'
|
||||||
import { onMounted, ref } from 'vue'
|
import { onMounted, ref } from 'vue'
|
||||||
import filelist from './filelist.vue'
|
import filelist from './filelist.vue'
|
||||||
import { getfilelist } from '@/api/chat'
|
import { SvgIcon } from '@/components/common'
|
||||||
|
import { deletefile, getfilelist } from '@/api/chat'
|
||||||
import { idStore } from '@/store/modules/knowledgebaseid/id'
|
import { idStore } from '@/store/modules/knowledgebaseid/id'
|
||||||
const items = ref<any>([])
|
const items = ref<any>([])
|
||||||
const choice = ref('')
|
const choice = ref('')
|
||||||
|
|
@ -51,6 +52,17 @@ const handleClick = () => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
async function handleDelete(item: any) {
|
||||||
|
await deletefile(item.value)
|
||||||
|
const res = await getfilelist({})
|
||||||
|
items.value = []
|
||||||
|
res.data.data.forEach((item: any) => {
|
||||||
|
items.value.push({
|
||||||
|
value: item,
|
||||||
|
show: false,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
@ -74,9 +86,25 @@ const handleClick = () => {
|
||||||
</NFormItem>
|
</NFormItem>
|
||||||
</NForm>
|
</NForm>
|
||||||
<div v-for="item in items" :key="item.value">
|
<div v-for="item in items" :key="item.value">
|
||||||
<NButton block size="large" @click="handleValidateClick(item.value)">
|
<div class="flex items-center">
|
||||||
{{ item.value }}
|
<NButton block size="large" style="width:90%" @click="handleValidateClick(item.value)">
|
||||||
</NButton>
|
{{ item.value }}
|
||||||
|
</NButton>
|
||||||
|
<div class="absolute z-10 flex visible right-1">
|
||||||
|
<template v-if="item.isEdit" />
|
||||||
|
<template v-else>
|
||||||
|
<NPopconfirm placement="bottom" @positive-click="handleDelete(item)">
|
||||||
|
<template #trigger>
|
||||||
|
<button class="p-1">
|
||||||
|
<SvgIcon icon="ri:delete-bin-line" />
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
|
确定删除此文件?
|
||||||
|
</NPopconfirm>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div v-if="item.show" class="p-2 flex-1 min-h-0 pb-4 overflow-hidden">
|
<div v-if="item.show" class="p-2 flex-1 min-h-0 pb-4 overflow-hidden">
|
||||||
<filelist v-if="item.value" :knowledgebaseid="item.value" />
|
<filelist v-if="item.value" :knowledgebaseid="item.value" />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue