Files
nest-trpc-prisma-starter/apps/server/src/modules/file/file.service.ts
T
2024-04-26 02:12:44 +08:00

87 lines
2.3 KiB
TypeScript

import { createWriteStream } from 'node:fs'
import path from 'node:path'
import { Readable, pipeline } from 'node:stream'
import { promisify } from 'node:util'
import {
BadRequestException,
Injectable,
NotFoundException,
} from '@nestjs/common'
import { ConfigService } from '@nestjs/config'
import { IAppConfig } from '@server/config/app.config'
import { STATIC_FILE_DIR } from '@server/constants/path.constant'
import fs from 'fs-extra'
import { FileType } from './file.constant'
const pump = promisify(pipeline)
@Injectable()
export class FileService {
constructor(private readonly configService: ConfigService) { }
private resolveFilePath(type: FileType, name: string) {
return path.resolve(STATIC_FILE_DIR, type, name)
}
private async checkIsExist(path: string) {
try {
await fs.access(path)
return true
}
catch {
return false
}
}
async getFileStream(type: FileType, name: string) {
const exists = await this.checkIsExist(this.resolveFilePath(type, name))
if (!exists)
throw new NotFoundException('文件不存在')
return fs.createReadStream(this.resolveFilePath(type, name))
}
async writeFile(
type: FileType,
name: string,
data: Readable,
encoding?: BufferEncoding,
) {
const filePath = this.resolveFilePath(type, name)
if (await this.checkIsExist(filePath))
throw new BadRequestException('文件已存在')
await fs.mkdir(path.dirname(filePath), { recursive: true })
const writable = createWriteStream(filePath, { encoding })
await pump(data, writable)
}
async deleteFile(type: FileType, name: string) {
try {
return await fs.unlink(this.resolveFilePath(type, name))
}
catch {
return null
}
}
async getDir(type: FileType) {
await fs.mkdir(this.resolveFilePath(type, ''), { recursive: true })
const path_1 = path.resolve(STATIC_FILE_DIR, type)
return await fs.readdir(path_1)
}
async resolveFileUrl(type: FileType, name: string) {
const { baseUrl, globalPrefix } = await this.configService.get<IAppConfig>('app')!
return `${baseUrl.replace(/\/+$/, '')}/${globalPrefix}/files/${type}/${name}`
}
exists(type: FileType, name: string) {
return this.checkIsExist(this.resolveFilePath(type, name))
}
}