mirror of
https://github.com/1Panel-dev/MaxKB.git
synced 2025-12-26 01:33:05 +00:00
feat: add document replacement functionality with file upload
This commit is contained in:
parent
76ba9d0513
commit
620d4ff996
|
|
@ -28,6 +28,7 @@ from common.db.search import native_search, get_dynamics_model, native_page_sear
|
|||
from common.event import ListenerManagement
|
||||
from common.event.common import work_thread_pool
|
||||
from common.exception.app_exception import AppApiException
|
||||
from common.field.common import UploadedFileField
|
||||
from common.handle.impl.qa.csv_parse_qa_handle import CsvParseQAHandle
|
||||
from common.handle.impl.qa.xls_parse_qa_handle import XlsParseQAHandle
|
||||
from common.handle.impl.qa.xlsx_parse_qa_handle import XlsxParseQAHandle
|
||||
|
|
@ -1503,6 +1504,38 @@ class DocumentSerializers(serializers.Serializer):
|
|||
tag_id__in=tag_ids
|
||||
).delete()
|
||||
|
||||
class ReplaceSourceFile(serializers.Serializer):
|
||||
workspace_id = serializers.CharField(required=True, label=_('workspace id'))
|
||||
knowledge_id = serializers.UUIDField(required=True, label=_('knowledge id'))
|
||||
document_id = serializers.UUIDField(required=True, label=_('document id'))
|
||||
file = UploadedFileField(required=True, label=_("file"))
|
||||
|
||||
def is_valid(self, *, raise_exception=False):
|
||||
super().is_valid(raise_exception=True)
|
||||
workspace_id = self.data.get('workspace_id')
|
||||
query_set = QuerySet(Knowledge).filter(id=self.data.get('knowledge_id'))
|
||||
if workspace_id and workspace_id != 'None':
|
||||
query_set = query_set.filter(workspace_id=workspace_id)
|
||||
if not query_set.exists():
|
||||
raise AppApiException(500, _('Knowledge id does not exist'))
|
||||
if not QuerySet(Document).filter(
|
||||
id=self.data.get('document_id'),
|
||||
knowledge_id=self.data.get('knowledge_id')
|
||||
).exists():
|
||||
raise AppApiException(500, _('Document id does not exist'))
|
||||
|
||||
def replace(self):
|
||||
self.is_valid(raise_exception=True)
|
||||
file = self.data.get('file')
|
||||
source_file = QuerySet(File).filter(source_id=self.data.get('document_id')).first()
|
||||
|
||||
if not source_file:
|
||||
raise AppApiException(500, _('Source file not found'))
|
||||
|
||||
source_file.save(file.read())
|
||||
|
||||
return True
|
||||
|
||||
|
||||
class FileBufferHandle:
|
||||
buffer = None
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ urlpatterns = [
|
|||
path('workspace/<str:workspace_id>/knowledge/<str:knowledge_id>/document/<str:document_id>/export', views.DocumentView.Export.as_view()),
|
||||
path('workspace/<str:workspace_id>/knowledge/<str:knowledge_id>/document/<str:document_id>/export_zip', views.DocumentView.ExportZip.as_view()),
|
||||
path('workspace/<str:workspace_id>/knowledge/<str:knowledge_id>/document/<str:document_id>/download_source_file', views.DocumentView.DownloadSourceFile.as_view()),
|
||||
path('workspace/<str:workspace_id>/knowledge/<str:knowledge_id>/document/<str:document_id>/replace_source_file', views.DocumentView.ReplaceSourceFile.as_view()),
|
||||
path('workspace/<str:workspace_id>/knowledge/<str:knowledge_id>/document/<str:document_id>/tags', views.DocumentView.Tags.as_view()),
|
||||
path('workspace/<str:workspace_id>/knowledge/<str:knowledge_id>/document/<str:document_id>/tags/batch_delete', views.DocumentView.Tags.BatchDelete.as_view()),
|
||||
path('workspace/<str:workspace_id>/knowledge/<str:knowledge_id>/document/<str:document_id>/paragraph', views.ParagraphView.as_view()),
|
||||
|
|
|
|||
|
|
@ -686,6 +686,31 @@ class DocumentView(APIView):
|
|||
'workspace_id': workspace_id, 'document_id': document_id, 'knowledge_id': knowledge_id
|
||||
}).download_source_file()
|
||||
|
||||
class ReplaceSourceFile(APIView):
|
||||
authentication_classes = [TokenAuth]
|
||||
|
||||
@extend_schema(
|
||||
summary=_('Replace source file'),
|
||||
operation_id=_('Replace source file'), # type: ignore
|
||||
parameters=DocumentDownloadSourceAPI.get_parameters(),
|
||||
responses=DocumentDownloadSourceAPI.get_response(),
|
||||
tags=[_('Knowledge Base/Documentation')] # type: ignore
|
||||
)
|
||||
@has_permissions(
|
||||
PermissionConstants.KNOWLEDGE_DOCUMENT_EDIT.get_workspace_knowledge_permission(),
|
||||
PermissionConstants.KNOWLEDGE_DOCUMENT_EDIT.get_workspace_permission_workspace_manage_role(),
|
||||
RoleConstants.WORKSPACE_MANAGE.get_workspace_role(),
|
||||
ViewPermission([RoleConstants.USER.get_workspace_role()],
|
||||
[PermissionConstants.KNOWLEDGE.get_workspace_knowledge_permission()], CompareConstants.AND),
|
||||
)
|
||||
def post(self, request: Request, workspace_id: str, knowledge_id: str, document_id: str):
|
||||
return result.success(DocumentSerializers.ReplaceSourceFile(data={
|
||||
'workspace_id': workspace_id,
|
||||
'document_id': document_id,
|
||||
'knowledge_id': knowledge_id,
|
||||
'file': request.FILES.get('file')
|
||||
}).replace())
|
||||
|
||||
class Tags(APIView):
|
||||
authentication_classes = [TokenAuth]
|
||||
|
||||
|
|
|
|||
|
|
@ -144,6 +144,14 @@ const getDownloadSourceFile: (knowledge_id: string, document_id: string, documen
|
|||
return exportFile(document_name, `${prefix.value}/${knowledge_id}/document/${document_id}/download_source_file`, {}, undefined)
|
||||
}
|
||||
|
||||
const postReplaceSourceFile: (knowledge_id: string, document_id: string, data: any) => Promise<Result<any>> = (
|
||||
knowledge_id,
|
||||
document_id,
|
||||
data,
|
||||
) => {
|
||||
return post(`${prefix.value}/${knowledge_id}/document/${document_id}/replace_source_file`, data, {}, undefined)
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出文档
|
||||
* @param document_name 文档名称
|
||||
|
|
@ -608,6 +616,7 @@ export default {
|
|||
putBatchCancelTask,
|
||||
putCancelTask,
|
||||
getDownloadSourceFile,
|
||||
postReplaceSourceFile,
|
||||
exportDocument,
|
||||
exportDocumentZip,
|
||||
putDocumentRefresh,
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ export default {
|
|||
cancelGenerate: 'Cancel Generation',
|
||||
export: 'Export to',
|
||||
download: 'Download',
|
||||
replace: 'Replace',
|
||||
},
|
||||
|
||||
tip: {
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ export default {
|
|||
cancelGenerate: '取消生成',
|
||||
export: '导出',
|
||||
download: '下载原文档',
|
||||
replace: '替换原文档',
|
||||
},
|
||||
tip: {
|
||||
saveMessage: '当前的更改尚未保存,确认退出吗?',
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ export default {
|
|||
cancelGenerate: '取消生成',
|
||||
export: '匯出',
|
||||
download: '下載原文件',
|
||||
replace: '替換原文件',
|
||||
},
|
||||
tip: {
|
||||
saveMessage: '當前的更改尚未保存,確認退出嗎?',
|
||||
|
|
|
|||
|
|
@ -494,6 +494,21 @@
|
|||
</el-icon>
|
||||
{{ $t('views.document.setting.download') }}
|
||||
</el-dropdown-item>
|
||||
<el-upload
|
||||
ref="elUploadRef"
|
||||
:file-list="[]"
|
||||
action="#"
|
||||
:auto-upload="false"
|
||||
:show-file-list="false"
|
||||
:on-change="(file: any, fileList: any) => replaceDocument(file, row)"
|
||||
>
|
||||
<el-dropdown-item v-if="permissionPrecise.doc_edit(id)">
|
||||
<el-icon class="color-secondary">
|
||||
<Upload />
|
||||
</el-icon>
|
||||
{{ $t('views.document.setting.replace') }}
|
||||
</el-dropdown-item>
|
||||
</el-upload>
|
||||
<el-dropdown-item
|
||||
@click.stop="deleteDocument(row)"
|
||||
v-if="permissionPrecise.doc_delete(id)"
|
||||
|
|
@ -1079,6 +1094,20 @@ function downloadDocument(row: any) {
|
|||
})
|
||||
}
|
||||
|
||||
const elUploadRef = ref()
|
||||
|
||||
function replaceDocument(file: any, row: any) {
|
||||
const formData = new FormData()
|
||||
formData.append('file', file.raw, file.name)
|
||||
elUploadRef.value.clearFiles()
|
||||
loadSharedApi({ type: 'document', systemType: apiType.value })
|
||||
.postReplaceSourceFile(id, row.id, formData, loading)
|
||||
.then(() => {
|
||||
getList()
|
||||
})
|
||||
.catch((e: any) => {})
|
||||
}
|
||||
|
||||
function deleteDocument(row: any) {
|
||||
MsgConfirm(
|
||||
`${t('views.document.delete.confirmTitle3')} ${row.name} ?`,
|
||||
|
|
|
|||
Loading…
Reference in New Issue