feat(r4): POST /api/sketch + Upload 归属记录 + 派单状态后台同步与大小校验
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
import {
|
||||
Controller,
|
||||
Post,
|
||||
UploadedFile,
|
||||
UseInterceptors,
|
||||
} from '@nestjs/common';
|
||||
import { FileInterceptor } from '@nestjs/platform-express';
|
||||
import { ApiBearerAuth, ApiConsumes, ApiOperation, ApiTags } from '@nestjs/swagger';
|
||||
import { CurrentUser, JwtPayload } from '../common/decorators/current-user.decorator';
|
||||
import { SketchService } from './sketch.service';
|
||||
|
||||
// 单张贴纸/底图 ≤ 10MB
|
||||
const MAX_IMAGE_BYTES = 10 * 1024 * 1024;
|
||||
|
||||
@ApiTags('线稿')
|
||||
@ApiBearerAuth()
|
||||
@Controller('sketch')
|
||||
export class SketchController {
|
||||
constructor(private readonly sketchService: SketchService) {}
|
||||
|
||||
@Post()
|
||||
@ApiOperation({ summary: '线稿处理(贴纸图 → 处理后 URL)' })
|
||||
@ApiConsumes('multipart/form-data')
|
||||
@UseInterceptors(FileInterceptor('image', { limits: { fileSize: MAX_IMAGE_BYTES } }))
|
||||
sketch(@CurrentUser() user: JwtPayload, @UploadedFile() file: Express.Multer.File) {
|
||||
return this.sketchService.process(user.sub, file);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { SketchController } from './sketch.controller';
|
||||
import { SketchService } from './sketch.service';
|
||||
import { CosModule } from '../cos/cos.module';
|
||||
|
||||
@Module({
|
||||
imports: [CosModule],
|
||||
controllers: [SketchController],
|
||||
providers: [SketchService],
|
||||
})
|
||||
export class SketchModule {}
|
||||
@@ -0,0 +1,26 @@
|
||||
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
|
||||
import { randomUUID } from 'crypto';
|
||||
import { CosService } from '../cos/cos.service';
|
||||
|
||||
// 线稿处理:接收贴纸图,转存 COS 返回可访问 URL(真实 AI 线稿外部服务接入后可替换内部实现)
|
||||
@Injectable()
|
||||
export class SketchService {
|
||||
constructor(private readonly cos: CosService) {}
|
||||
|
||||
async process(userId: string, file: Express.Multer.File) {
|
||||
if (!file?.buffer) {
|
||||
throw new HttpException('缺少图片', HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
const mime = file.mimetype ?? 'image/png';
|
||||
if (!/^image\/(png|jpe?g|webp)$/i.test(mime)) {
|
||||
throw new HttpException('仅支持 png/jpg/jpeg/webp 图片', HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
if (!this.cos.configured) {
|
||||
throw new HttpException('图床未配置', HttpStatus.SERVICE_UNAVAILABLE);
|
||||
}
|
||||
|
||||
const key = `uploads/sketch/${userId}/${randomUUID()}.png`;
|
||||
await this.cos.putObject(key, file.buffer, mime);
|
||||
return { imageUrl: this.cos.publicUrl(key) };
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user