2025-01-06 08:45:23 +08:00
|
|
|
|
import {
|
2025-01-27 22:43:31 +08:00
|
|
|
|
Controller,
|
|
|
|
|
All,
|
|
|
|
|
Req,
|
|
|
|
|
Res,
|
|
|
|
|
Get,
|
|
|
|
|
Post,
|
|
|
|
|
Patch,
|
|
|
|
|
Param,
|
|
|
|
|
Delete,
|
|
|
|
|
Head,
|
|
|
|
|
Options,
|
2025-03-21 10:55:44 +08:00
|
|
|
|
NotFoundException,
|
|
|
|
|
HttpException,
|
|
|
|
|
HttpStatus,
|
2025-03-21 17:25:39 +08:00
|
|
|
|
Body,
|
2025-01-06 08:45:23 +08:00
|
|
|
|
} from '@nestjs/common';
|
2025-01-27 22:43:31 +08:00
|
|
|
|
import { Request, Response } from 'express';
|
2025-01-06 18:30:16 +08:00
|
|
|
|
import { TusService } from './tus.service';
|
2025-03-21 10:55:44 +08:00
|
|
|
|
import { ShareCodeService } from './share-code.service';
|
2025-03-21 17:25:39 +08:00
|
|
|
|
import { ResourceService } from '@server/models/resource/resource.service';
|
2025-01-06 08:45:23 +08:00
|
|
|
|
@Controller('upload')
|
2025-01-03 09:24:46 +08:00
|
|
|
|
export class UploadController {
|
2025-03-21 10:55:44 +08:00
|
|
|
|
constructor(
|
|
|
|
|
private readonly tusService: TusService,
|
|
|
|
|
private readonly shareCodeService: ShareCodeService,
|
2025-03-21 17:25:39 +08:00
|
|
|
|
private readonly resourceService: ResourceService,
|
2025-03-21 10:55:44 +08:00
|
|
|
|
) {}
|
2025-01-27 22:43:31 +08:00
|
|
|
|
// @Post()
|
|
|
|
|
// async handlePost(@Req() req: Request, @Res() res: Response) {
|
|
|
|
|
// return this.tusService.handleTus(req, res);
|
|
|
|
|
// }
|
2025-01-08 00:52:11 +08:00
|
|
|
|
|
2025-01-27 22:43:31 +08:00
|
|
|
|
@Options()
|
|
|
|
|
async handleOptions(@Req() req: Request, @Res() res: Response) {
|
|
|
|
|
return this.tusService.handleTus(req, res);
|
|
|
|
|
}
|
2025-01-08 00:52:11 +08:00
|
|
|
|
|
2025-01-27 22:43:31 +08:00
|
|
|
|
@Head()
|
|
|
|
|
async handleHead(@Req() req: Request, @Res() res: Response) {
|
|
|
|
|
return this.tusService.handleTus(req, res);
|
|
|
|
|
}
|
2025-01-08 00:52:11 +08:00
|
|
|
|
|
2025-01-27 22:43:31 +08:00
|
|
|
|
@Post()
|
|
|
|
|
async handlePost(@Req() req: Request, @Res() res: Response) {
|
|
|
|
|
return this.tusService.handleTus(req, res);
|
|
|
|
|
}
|
2025-03-21 17:25:39 +08:00
|
|
|
|
@Get('share/:code')
|
|
|
|
|
async validateShareCode(@Param('code') code: string) {
|
2025-03-21 18:11:36 +08:00
|
|
|
|
console.log('收到验证分享码请求,code:', code);
|
|
|
|
|
|
|
|
|
|
const shareCode = await this.shareCodeService.validateAndUseCode(code);
|
|
|
|
|
console.log('验证分享码结果:', shareCode);
|
|
|
|
|
|
|
|
|
|
if (!shareCode) {
|
|
|
|
|
throw new NotFoundException('分享码无效或已过期');
|
2025-03-21 17:25:39 +08:00
|
|
|
|
}
|
2025-03-21 18:11:36 +08:00
|
|
|
|
|
|
|
|
|
// 获取文件信息
|
|
|
|
|
const resource = await this.resourceService.findUnique({
|
|
|
|
|
where: { fileId: shareCode.fileId },
|
|
|
|
|
});
|
|
|
|
|
console.log('获取到的资源信息:', resource);
|
|
|
|
|
|
|
|
|
|
if (!resource) {
|
|
|
|
|
throw new NotFoundException('文件不存在');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 直接返回正确的数据结构
|
|
|
|
|
const response = {
|
|
|
|
|
fileId: shareCode.fileId,
|
|
|
|
|
fileName:shareCode.fileName || 'downloaded_file',
|
|
|
|
|
code: shareCode.code,
|
|
|
|
|
expiresAt: shareCode.expiresAt
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
console.log('返回给前端的数据:', response); // 添加日志
|
|
|
|
|
return response;
|
2025-03-21 17:25:39 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Get('share/info/:code')
|
|
|
|
|
async getShareCodeInfo(@Param('code') code: string) {
|
|
|
|
|
const info = await this.shareCodeService.getShareCodeInfo(code);
|
|
|
|
|
if (!info) {
|
|
|
|
|
throw new NotFoundException('分享码不存在');
|
|
|
|
|
}
|
|
|
|
|
return info;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Get('share/history/:fileId')
|
|
|
|
|
async getFileShareHistory(@Param('fileId') fileId: string) {
|
|
|
|
|
return this.shareCodeService.getFileShareHistory(fileId);
|
|
|
|
|
}
|
2025-01-27 22:43:31 +08:00
|
|
|
|
@Get('/*')
|
|
|
|
|
async handleGet(@Req() req: Request, @Res() res: Response) {
|
|
|
|
|
return this.tusService.handleTus(req, res);
|
|
|
|
|
}
|
2025-01-08 00:52:11 +08:00
|
|
|
|
|
2025-01-27 22:43:31 +08:00
|
|
|
|
@Patch('/*')
|
|
|
|
|
async handlePatch(@Req() req: Request, @Res() res: Response) {
|
|
|
|
|
return this.tusService.handleTus(req, res);
|
|
|
|
|
}
|
2025-01-06 08:45:23 +08:00
|
|
|
|
|
2025-01-27 22:43:31 +08:00
|
|
|
|
// Keeping the catch-all method as a fallback
|
|
|
|
|
@All()
|
|
|
|
|
async handleUpload(@Req() req: Request, @Res() res: Response) {
|
|
|
|
|
return this.tusService.handleTus(req, res);
|
|
|
|
|
}
|
2025-03-21 10:55:44 +08:00
|
|
|
|
@Post('share/:fileId(*)')
|
|
|
|
|
async generateShareCode(@Param('fileId') fileId: string) {
|
|
|
|
|
try {
|
|
|
|
|
console.log('收到生成分享码请求,fileId:', fileId);
|
|
|
|
|
const result = await this.shareCodeService.generateShareCode(fileId);
|
|
|
|
|
console.log('生成分享码结果:', result);
|
|
|
|
|
return result;
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('生成分享码错误:', error);
|
|
|
|
|
throw new HttpException(
|
|
|
|
|
{
|
|
|
|
|
message: (error as Error).message || '生成分享码失败',
|
|
|
|
|
error: 'SHARE_CODE_GENERATION_FAILED'
|
|
|
|
|
},
|
|
|
|
|
HttpStatus.INTERNAL_SERVER_ERROR
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-21 17:25:39 +08:00
|
|
|
|
@Post('filename')
|
|
|
|
|
async saveFileName(@Body() data: { fileId: string; fileName: string }) {
|
|
|
|
|
try {
|
|
|
|
|
console.log('收到保存文件名请求:', data);
|
|
|
|
|
|
|
|
|
|
// 检查参数
|
|
|
|
|
if (!data.fileId || !data.fileName) {
|
|
|
|
|
throw new HttpException(
|
|
|
|
|
{ message: '缺少必要参数' },
|
|
|
|
|
HttpStatus.BAD_REQUEST
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
// 保存文件名
|
|
|
|
|
await this.resourceService.saveFileName(data.fileId, data.fileName);
|
|
|
|
|
console.log('文件名保存成功:', data.fileName, '对应文件ID:', data.fileId);
|
|
|
|
|
|
|
|
|
|
return { success: true };
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('保存文件名失败:', error);
|
|
|
|
|
throw new HttpException(
|
|
|
|
|
{
|
|
|
|
|
message: '保存文件名失败',
|
|
|
|
|
error: (error instanceof Error) ? error.message : String(error)
|
|
|
|
|
},
|
|
|
|
|
HttpStatus.INTERNAL_SERVER_ERROR
|
|
|
|
|
);
|
2025-03-21 10:55:44 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-21 17:25:39 +08:00
|
|
|
|
@Get('download/:fileId')
|
|
|
|
|
async downloadFile(@Param('fileId') fileId: string, @Res() res: Response) {
|
|
|
|
|
try {
|
|
|
|
|
// 获取文件信息
|
|
|
|
|
const resource = await this.resourceService.findUnique({
|
|
|
|
|
where: { fileId },
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (!resource) {
|
|
|
|
|
throw new NotFoundException('文件不存在');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取原始文件名
|
|
|
|
|
const fileName = await this.resourceService.getFileName(fileId) || 'downloaded-file';
|
|
|
|
|
|
|
|
|
|
// 设置响应头,包含原始文件名
|
|
|
|
|
res.setHeader(
|
|
|
|
|
'Content-Disposition',
|
|
|
|
|
`attachment; filename="${encodeURIComponent(fileName)}"`
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// 其他下载逻辑...
|
|
|
|
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
// 错误处理...
|
2025-03-21 10:55:44 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-27 22:43:31 +08:00
|
|
|
|
}
|