feat: remove upload file

This commit is contained in:
eeee0717
2025-06-04 14:30:03 +08:00
parent 9418701ccd
commit fa7d7deda6
11 changed files with 52 additions and 27 deletions
@@ -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 })
+2
View File
@@ -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
}
+2
View File
@@ -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) => {
+6 -3
View File
@@ -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>
+1
View File
@@ -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 }
})
)