feat: 付费体系重构 P0 - 配额独立化/简历付费下载/PDF生成

This commit is contained in:
yuzhiran
2026-06-12 09:31:11 +08:00
parent 5d407b4f79
commit 065fe7a186
23 changed files with 965 additions and 106 deletions
@@ -1,10 +1,17 @@
import { Controller, Post, Get, Delete, Param, Body } from '@nestjs/common'
import { Controller, Post, Get, Delete, Param, Body, Res, HttpException, HttpStatus } from '@nestjs/common'
import { Response } from 'express'
import { ResumeService } from './resume.service'
import { ResumePdfService } from './resume-pdf.service'
import { QuotaService } from '../user/quota.service'
import { CurrentUser } from '../../common/decorators/current-user.decorator'
@Controller('resume')
export class ResumeController {
constructor(private resumeService: ResumeService) {}
constructor(
private resumeService: ResumeService,
private resumePdfService: ResumePdfService,
private quotaService: QuotaService,
) {}
@Post('create')
async create(
@@ -21,6 +28,31 @@ export class ResumeController {
return this.resumeService.list(userId)
}
@Post(':id/download')
async download(@Param('id') id: string, @CurrentUser('userId') userId: string, @Res() res: Response) {
const resume = await this.resumeService.getDetail(id, userId)
const canDownload = await this.quotaService.checkDownload(userId, resume)
if (!canDownload) {
throw new HttpException('请先付费下载', HttpStatus.PAYMENT_REQUIRED)
}
await this.quotaService.deductDownload(userId, resume)
if (!resume.paidDownload) {
await this.resumeService.markPaid(id, userId)
}
const pdf = await this.resumePdfService.generatePdf({
title: resume.title,
content: resume.content,
targetPosition: resume.targetPosition,
})
res.setHeader('Content-Type', 'application/pdf')
res.setHeader('Content-Disposition', `attachment; filename="${encodeURIComponent(resume.title)}.pdf"`)
res.send(pdf)
}
@Get(':id')
async getDetail(@Param('id') id: string, @CurrentUser('userId') userId: string) {
return this.resumeService.getDetail(id, userId)