feat: remove upload file
This commit is contained in:
@@ -10,7 +10,7 @@ import { TypedArray } from 'pdfjs-dist/types/src/display/api'
|
||||
|
||||
export default abstract class BasePreprocessProvider {
|
||||
protected provider: PreprocessProvider
|
||||
private storageDir = path.join(app.getPath('userData'), 'Data', 'Files')
|
||||
public storageDir = path.join(app.getPath('userData'), 'Data', 'Files')
|
||||
|
||||
constructor(provider: PreprocessProvider) {
|
||||
if (!provider) {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import fs from 'node:fs'
|
||||
import path from 'node:path'
|
||||
|
||||
import { getFileDir } from '@main/utils/file'
|
||||
import { FileMetadata, PreprocessProvider } from '@types'
|
||||
import AdmZip from 'adm-zip'
|
||||
import axios, { AxiosRequestConfig } from 'axios'
|
||||
@@ -84,7 +83,7 @@ export default class Doc2xPreprocessProvider extends BasePreprocessProvider {
|
||||
}
|
||||
|
||||
private createProcessedFileInfo(file: FileMetadata, outputPath: string): FileMetadata {
|
||||
const outputFilePath = `${outputPath}/${file.id}.md`
|
||||
const outputFilePath = `${outputPath}/${file.name.split('.').slice(0, -1).join('.')}.md`
|
||||
return {
|
||||
...file,
|
||||
name: file.name.replace('.pdf', '.md'),
|
||||
@@ -280,7 +279,7 @@ export default class Doc2xPreprocessProvider extends BasePreprocessProvider {
|
||||
* @returns 下载文件的路径
|
||||
*/
|
||||
private async downloadFile(url: string, file: FileMetadata): Promise<{ path: string }> {
|
||||
const dirPath = getFileDir(file.path)
|
||||
const dirPath = this.storageDir
|
||||
// 使用统一的存储路径:Data/Files/{file.id}/
|
||||
const extractPath = path.join(dirPath, file.id)
|
||||
const zipPath = path.join(dirPath, `${file.id}.zip`)
|
||||
|
||||
@@ -126,7 +126,7 @@ export default class MineruPreprocessProvider extends BasePreprocessProvider {
|
||||
}
|
||||
|
||||
private async downloadAndExtractFile(zipUrl: string, originalFilePath: string): Promise<{ path: string }> {
|
||||
const dirPath = path.dirname(originalFilePath)
|
||||
const dirPath = this.storageDir
|
||||
const baseName = path.basename(originalFilePath, path.extname(originalFilePath))
|
||||
const zipPath = path.join(dirPath, `${baseName}.zip`)
|
||||
const extractPath = path.join(dirPath, `${baseName}`)
|
||||
|
||||
@@ -94,7 +94,8 @@ export default class MistralPreprocessProvider extends BasePreprocessProvider {
|
||||
private convertFile(result: OCRResponse, file: FileMetadata): FileMetadata {
|
||||
// 使用统一的存储路径:Data/Files/{file.id}/
|
||||
const conversionId = file.id
|
||||
const outputPath = path.join(path.dirname(file.path), file.id)
|
||||
const outputPath = path.join(this.storageDir, file.id)
|
||||
// const outputPath = this.storageDir
|
||||
const outputFileName = path.basename(file.path, path.extname(file.path))
|
||||
fs.mkdirSync(outputPath, { recursive: true })
|
||||
|
||||
|
||||
@@ -53,6 +53,7 @@ class FileStorage {
|
||||
|
||||
findDuplicateFile = async (filePath: string): Promise<FileMetadata | null> => {
|
||||
const stats = fs.statSync(filePath)
|
||||
console.log('stats', stats, filePath)
|
||||
const fileSize = stats.size
|
||||
|
||||
const files = await fs.promises.readdir(this.storageDir)
|
||||
@@ -220,6 +221,7 @@ class FileStorage {
|
||||
}
|
||||
|
||||
public deleteDir = async (_: Electron.IpcMainInvokeEvent, id: string): Promise<void> => {
|
||||
console.log('[FileStorage] Deleting directory:', path.join(this.storageDir, id))
|
||||
if (!fs.existsSync(path.join(this.storageDir, id))) {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -170,6 +170,8 @@ class KnowledgeService {
|
||||
// 添加预处理逻辑
|
||||
const fileToProcess: FileMetadata = await this.preprocessing(file, base, item)
|
||||
|
||||
console.log('fileToProcess', fileToProcess)
|
||||
|
||||
// 使用处理后的文件进行加载
|
||||
return addFileLoader(ragApplication, fileToProcess, base, forceReload)
|
||||
.then((result) => {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { db } from '@renderer/databases'
|
||||
import KnowledgeQueue from '@renderer/queue/KnowledgeQueue'
|
||||
import FileManager from '@renderer/services/FileManager'
|
||||
import { getKnowledgeBaseParams } from '@renderer/services/KnowledgeService'
|
||||
import { RootState } from '@renderer/store'
|
||||
import {
|
||||
@@ -54,6 +53,7 @@ export const useKnowledge = (baseId: string) => {
|
||||
processingError: '',
|
||||
retryCount: 0
|
||||
}))
|
||||
console.log('Adding files:', filesItems)
|
||||
dispatch(addFilesAction({ baseId, items: filesItems }))
|
||||
setTimeout(() => KnowledgeQueue.checkAllBases(), 0)
|
||||
}
|
||||
@@ -145,8 +145,11 @@ export const useKnowledge = (baseId: string) => {
|
||||
}
|
||||
}
|
||||
if (item.type === 'file' && typeof item.content === 'object') {
|
||||
await FileManager.deleteFile(item.content.id)
|
||||
await window.api.file.deleteDir(item.content.id)
|
||||
// await FileManager.deleteFile(item.content.id)
|
||||
// file name 1.xxx.pdf
|
||||
// get 1.xxx
|
||||
// remove .pdf ext
|
||||
await window.api.file.deleteDir(item.content.name.split('.').slice(0, -1).join('.'))
|
||||
}
|
||||
}
|
||||
// 刷新项目
|
||||
|
||||
@@ -10,7 +10,7 @@ import { useKnowledge } from '@renderer/hooks/useKnowledge'
|
||||
import FileManager from '@renderer/services/FileManager'
|
||||
import { getProviderName } from '@renderer/services/ProviderService'
|
||||
import { FileMetadata, FileTypes, KnowledgeBase, KnowledgeItem } from '@renderer/types'
|
||||
import { formatFileSize } from '@renderer/utils'
|
||||
import { formatFileSize, uuid } from '@renderer/utils'
|
||||
import { bookExts, documentExts, textExts, thirdPartyApplicationExts } from '@shared/config/constant'
|
||||
import { Alert, Button, Dropdown, Empty, message, Tag, Tooltip, Upload } from 'antd'
|
||||
import dayjs from 'dayjs'
|
||||
@@ -102,23 +102,36 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
|
||||
if (disabled) {
|
||||
return
|
||||
}
|
||||
|
||||
if (files) {
|
||||
const _files: FileMetadata[] = files
|
||||
.map((file) => ({
|
||||
id: file.name,
|
||||
name: file.name,
|
||||
path: window.api.file.getPathForFile(file),
|
||||
size: file.size,
|
||||
ext: `.${file.name.split('.').pop()}`.toLowerCase(),
|
||||
count: 1,
|
||||
origin_name: file.name,
|
||||
type: file.type as FileTypes,
|
||||
created_at: new Date().toISOString()
|
||||
}))
|
||||
.map((file) => {
|
||||
// 这个路径 filePath 很可能是在文件选择时的原始路径。
|
||||
const filePath = window.api.file.getPathForFile(file)
|
||||
let nameFromPath = filePath
|
||||
const lastSlash = filePath.lastIndexOf('/')
|
||||
const lastBackslash = filePath.lastIndexOf('\\')
|
||||
if (lastSlash !== -1 || lastBackslash !== -1) {
|
||||
nameFromPath = filePath.substring(Math.max(lastSlash, lastBackslash) + 1)
|
||||
}
|
||||
|
||||
// 从派生的文件名中获取扩展名
|
||||
const extFromPath = nameFromPath.includes('.') ? `.${nameFromPath.split('.').pop()}` : ''
|
||||
|
||||
return {
|
||||
id: uuid(),
|
||||
name: nameFromPath, // 使用从路径派生的文件名
|
||||
path: filePath,
|
||||
size: file.size,
|
||||
ext: extFromPath.toLowerCase(),
|
||||
count: 1,
|
||||
origin_name: file.name, // 保存 File 对象中原始的文件名
|
||||
type: file.type as FileTypes,
|
||||
created_at: new Date().toISOString()
|
||||
}
|
||||
})
|
||||
.filter(({ ext }) => fileTypes.includes(ext))
|
||||
const uploadedFiles = await FileManager.uploadFiles(_files)
|
||||
addFiles(uploadedFiles)
|
||||
// const uploadedFiles = await FileManager.uploadFiles(_files)
|
||||
addFiles(_files)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,6 @@ const PopupContainer: React.FC<Props> = ({ base, resolve }) => {
|
||||
const [searchKeyword, setSearchKeyword] = useState('')
|
||||
const { t } = useTranslation()
|
||||
const searchInputRef = useRef<any>(null)
|
||||
|
||||
const handleSearch = async (value: string) => {
|
||||
if (!value.trim()) {
|
||||
setResults([])
|
||||
@@ -131,7 +130,10 @@ const PopupContainer: React.FC<Props> = ({ base, resolve }) => {
|
||||
{item.file.origin_name}
|
||||
</a>
|
||||
) : (
|
||||
item.metadata.source
|
||||
// item.metadata.source
|
||||
<a href={`http://file/${item.metadata.source}`} target="_blank" rel="noreferrer">
|
||||
{item.metadata.source.split('/').pop() || item.metadata.source}
|
||||
</a>
|
||||
)}
|
||||
</Text>
|
||||
</MetadataContainer>
|
||||
|
||||
@@ -59,6 +59,7 @@ class FileManager {
|
||||
Logger.log(`[FileManager] Uploading file: ${JSON.stringify(file)}`)
|
||||
|
||||
const uploadFile = await window.api.file.upload(file)
|
||||
console.log('[FileManager] Uploaded file:', uploadFile)
|
||||
const fileRecord = await db.files.get(uploadFile.id)
|
||||
|
||||
if (fileRecord) {
|
||||
|
||||
@@ -56,6 +56,7 @@ export const getKnowledgeBaseParams = (base: KnowledgeBase): KnowledgeBaseParams
|
||||
}
|
||||
|
||||
export const getFileFromUrl = async (url: string): Promise<FileMetadata | null> => {
|
||||
console.log('getFileFromUrl', url)
|
||||
let fileName = ''
|
||||
|
||||
if (url && url.includes('CherryStudio')) {
|
||||
@@ -67,7 +68,7 @@ export const getFileFromUrl = async (url: string): Promise<FileMetadata | null>
|
||||
fileName = url.split('\\Data\\Files\\')[1]
|
||||
}
|
||||
}
|
||||
|
||||
console.log('fileName', fileName)
|
||||
if (fileName) {
|
||||
const actualFileName = fileName.split(/[/\\]/).pop() || fileName
|
||||
console.log('actualFileName', actualFileName)
|
||||
@@ -129,6 +130,7 @@ export const searchKnowledgeBase = async (
|
||||
return await Promise.all(
|
||||
limitedResults.map(async (item) => {
|
||||
const file = await getFileFromUrl(item.metadata.source)
|
||||
console.log('Knowledge search item:', item, 'File:', file)
|
||||
return { ...item, file }
|
||||
})
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user