fix: file upload failed by folder not created

This commit is contained in:
CrescentLeaf
2025-09-13 00:36:48 +08:00
parent fd6ceb82df
commit 6b0e781fdf

View File

@@ -2,6 +2,7 @@ import { DatabaseSync, SQLInputValue } from "node:sqlite"
import { Buffer } from "node:buffer" import { Buffer } from "node:buffer"
import path from 'node:path' import path from 'node:path'
import crypto from 'node:crypto' import crypto from 'node:crypto'
import fs from 'node:fs/promises'
import fs_sync from 'node:fs' import fs_sync from 'node:fs'
import chalk from "chalk" import chalk from "chalk"
import { fileTypeFromBuffer } from 'file-type' import { fileTypeFromBuffer } from 'file-type'
@@ -39,7 +40,7 @@ class File {
const hash = this.bean.hash const hash = this.bean.hash
return path.join( return path.join(
config.data_path, config.data_path,
"files", "uploaded_files",
hash.substring(0, 1), hash.substring(0, 1),
hash.substring(2, 3), hash.substring(2, 3),
hash.substring(3, 4), hash.substring(3, 4),
@@ -88,20 +89,21 @@ export default class FileManager {
static async uploadFile(fileName: string, data: Buffer, chatId?: string) { static async uploadFile(fileName: string, data: Buffer, chatId?: string) {
const hash = crypto.createHash('sha256').update(data).digest('hex') const hash = crypto.createHash('sha256').update(data).digest('hex')
try { const file = FileManager.findByHash(hash)
return FileManager.findByHash(hash) if (file) return file
} catch (_e) {
// Do nothing...
}
const mime = (await fileTypeFromBuffer(data))?.mime || 'application/octet-stream' const mime = (await fileTypeFromBuffer(data))?.mime || 'application/octet-stream'
fs_sync.writeFileSync( const folder = path.join(
config.data_path,
"uploaded_files",
hash.substring(0, 1),
hash.substring(2, 3),
hash.substring(3, 4)
)
await fs.mkdir(folder, { recursive: true })
await fs.writeFile(
path.join( path.join(
config.data_path, folder,
"files",
hash.substring(0, 1),
hash.substring(2, 3),
hash.substring(3, 4),
hash hash
), ),
data data
@@ -131,10 +133,10 @@ export default class FileManager {
private static findAllBeansByCondition(condition: string, ...args: SQLInputValue[]): FileBean[] { private static findAllBeansByCondition(condition: string, ...args: SQLInputValue[]): FileBean[] {
return FileManager.database.prepare(`SELECT * FROM ${FileManager.table_name} WHERE ${condition};`).all(...args) as unknown as FileBean[] return FileManager.database.prepare(`SELECT * FROM ${FileManager.table_name} WHERE ${condition};`).all(...args) as unknown as FileBean[]
} }
static findByHash(hash: string): File { static findByHash(hash: string): File | null {
const beans = FileManager.findAllBeansByCondition('hash = ?', hash) const beans = FileManager.findAllBeansByCondition('hash = ?', hash)
if (beans.length == 0) if (beans.length == 0)
throw new Error(`找不到 hash 为 ${hash} 的文件`) return null
else if (beans.length > 1) else if (beans.length > 1)
console.error(chalk.red(`警告: 查询 hash = ${hash} 时, 查询到多个相同 Hash 的文件`)) console.error(chalk.red(`警告: 查询 hash = ${hash} 时, 查询到多个相同 Hash 的文件`))
return new FileManager.File(beans[0]) return new FileManager.File(beans[0])