api-server/src/modules/files/files.service.ts

75 lines
2.2 KiB
TypeScript
Raw Normal View History

import {
Injectable,
NotFoundException,
ForbiddenException,
} from '@nestjs/common';
import { FilesRepository } from './files.repository';
import { StorageService } from '../../infrastructure/storage/storage.service';
import { CosStorageProvider } from '../../infrastructure/storage/cos-storage.provider';
import { CreateUploadUrlDto, CompleteUploadDto } from './dto';
@Injectable()
export class FilesService {
constructor(
private readonly repository: FilesRepository,
private readonly storage: StorageService,
private readonly cos: CosStorageProvider,
) {}
async requestUploadUrl(userId: string, dto: CreateUploadUrlDto) {
return this.storage.createUploadUrl(userId, {
filename: dto.filename,
mimeType: dto.mimeType,
sizeBytes: dto.sizeBytes,
});
}
async confirmUpload(userId: string, dto: CompleteUploadDto) {
const info = await this.storage.verifyUpload(dto.objectKey);
const parts = dto.objectKey.split('/');
const originalFilename = parts[parts.length - 1];
return this.repository.create({
userId,
filename: originalFilename,
mimeType: info.contentType,
storagePath: dto.objectKey,
objectKey: dto.objectKey,
bucket: this.cos.getBucket(),
sizeBytes: info.size,
checksum: dto.checksum,
});
}
async getFile(userId: string, fileId: string) {
const file = await this.repository.findById(fileId);
if (!file) {
throw new NotFoundException('文件不存在');
}
if (file.userId !== userId) {
throw new ForbiddenException('无权访问该文件');
}
const downloadUrl = await this.storage.getDownloadUrl(file.objectKey!);
return { file, downloadUrl };
}
async deleteFile(userId: string, fileId: string) {
const file = await this.repository.findById(fileId);
if (!file) {
throw new NotFoundException('文件不存在');
}
if (file.userId !== userId) {
throw new ForbiddenException('无权操作该文件');
}
await this.storage.deleteObject(file.objectKey!);
await this.repository.delete(fileId);
}
async findByUserId(userId: string) {
return this.repository.findByUserId(userId);
}
}