refactor: 移除executeTemplateByCode接口的后端图片审核功能

- 简化执行流程,直接执行模板跳过后端审核
- 支持前端传递auditTaskId参数用于审核追踪
- 移除UnifiedContentService依赖和相关审核逻辑
- 删除handleAuditComplete和startTemplateExecution方法
- 更新API文档说明前端审核职责
- 修改测试用例适配新的执行流程
- 保持数据库字段兼容性,auditTaskId改为前端传入

变更影响:
- executeTemplateByCode接口不再执行后端图片审核
- 执行记录状态直接设为PROCESSING
- 前端需要在调用接口前完成图片审核
This commit is contained in:
imeepos 2025-09-08 11:01:30 +08:00
parent 6ef0fe5bb1
commit fe0aa0a9c5
3 changed files with 55 additions and 84 deletions

View File

@ -190,28 +190,23 @@ describe('TemplateController', () => {
);
mockTemplate.execute.mockResolvedValue('task123');
unifiedContentService.auditImage.mockResolvedValue({
taskId: 'audit123',
status: AuditStatus.COMPLETED,
conclusion: AuditConclusion.PASS,
confidence: 99,
details: [],
riskLevel: RiskLevel.LOW,
suggestion: AuditSuggestion.PASS,
timestamp: new Date(),
} as any);
const result = await controller.executeTemplateByCode(
'test_template_v1',
{ imageUrl: 'http://example.com/input.jpg' },
{ imageUrl: 'http://example.com/input.jpg', auditTaskId: 'audit123' },
mockRequest,
);
expect(result.code).toBe(200);
expect(result.data?.executionId).toBe(1);
expect(result.data?.taskId).toBe('task123');
expect(result.data?.auditTaskId).toBe('audit123');
expect(result.data?.status).toBe('processing');
expect(unifiedContentService.auditImage).toHaveBeenCalled();
expect(templateFactory.createTemplateByCode).toHaveBeenCalledWith(
'test_template_v1',
);
expect(mockTemplate.execute).toHaveBeenCalledWith(
'http://example.com/input.jpg',
);
});
it('should throw error when template not found', async () => {
@ -228,37 +223,24 @@ describe('TemplateController', () => {
);
});
it('should throw error when image audit fails', async () => {
it('should execute template without audit when auditTaskId is not provided', async () => {
templateFactory.getTemplateByCode.mockResolvedValue(mockTemplate as any);
// Reset the mock to ensure it returns the correct audit failure response
unifiedContentService.auditImage.mockResolvedValue({
taskId: 'audit123',
status: AuditStatus.COMPLETED,
conclusion: AuditConclusion.REJECT,
confidence: 95,
details: [
{
type: 'inappropriate_content',
label: 'blocked',
confidence: 95,
description: '包含不当内容',
},
],
riskLevel: RiskLevel.HIGH,
suggestion: AuditSuggestion.BLOCK,
timestamp: new Date(),
} as any);
await expect(
controller.executeTemplateByCode(
'test_template_v1',
{ imageUrl: 'http://example.com/input.jpg' },
mockRequest,
),
).rejects.toThrow(
new HttpException('图片审核未通过: 包含不当内容', HttpStatus.FORBIDDEN),
templateFactory.createTemplateByCode.mockResolvedValue(
mockTemplate as any,
);
mockTemplate.execute.mockResolvedValue('task123');
const result = await controller.executeTemplateByCode(
'test_template_v1',
{ imageUrl: 'http://example.com/input.jpg' },
mockRequest,
);
expect(result.code).toBe(200);
expect(result.data?.executionId).toBe(1);
expect(result.data?.taskId).toBe('task123');
expect(result.data?.auditTaskId).toBeNull();
expect(result.data?.status).toBe('processing');
});
it('should throw error when user has too many tasks', async () => {
@ -278,7 +260,7 @@ describe('TemplateController', () => {
),
).rejects.toThrow(
new HttpException(
'有4个任务正在进行中请稍后再试',
'当前账号有4个任务正在进行中且距开始时间不足5分钟,请稍后再试',
HttpStatus.TOO_MANY_REQUESTS,
),
);

View File

@ -119,14 +119,16 @@ export class TemplateController {
@ApiOperation({
summary: '通过代码执行模板',
description: `
AI生成任务
- executionId taskId
- executionId auditTaskId
AI生成任务
ID说明
- imageUrl: 输入图片URL
- auditTaskId: 前端审核任务ID
ID说明
- executionId: 数据库执行记录主键
- taskId: 外部服务(N8N)ID
- auditTaskId: 审核服务任务ID
- taskId: 外部服务(N8N)ID
- auditTaskId: 前端传入的审核任务ID
`,
})
@ApiParam({
@ -144,35 +146,11 @@ export class TemplateController {
message: '模板执行已启动',
data: {
executionId: 123,
taskId: 'n8n_task_456', // 同步模式
status: 'processing'
}
}
}
})
@SwaggerApiResponse({
status: 200,
description: '异步审核模式',
schema: {
example: {
code: 200,
message: '模板执行已提交,正在进行图片审核',
data: {
executionId: 124,
auditTaskId: 'audit_task_789', // 异步模式
status: 'pending_audit'
}
}
}
})
@SwaggerApiResponse({
status: 403,
description: '图片审核未通过',
schema: {
example: {
code: 403,
message: '图片审核未通过: 包含不当内容',
data: null,
taskId: 'n8n_task_456',
auditTaskId: 'audit_task_789',
status: 'processing',
message: '模板执行已启动',
},
},
},
})
@ -590,10 +568,10 @@ export class TemplateController {
outputUrl: null,
errorMessage: null,
createdAt: '2025-01-01T00:00:00Z',
updatedAt: '2025-01-01T00:05:00Z'
}
}
}
updatedAt: '2025-01-01T00:05:00Z',
},
},
},
})
@SwaggerApiResponse({
status: 404,
@ -881,7 +859,6 @@ export class TemplateController {
}
}
/**
*
*/
@ -899,7 +876,10 @@ export class TemplateController {
updateData.errorMessage = errorMessage;
}
if (status === ExecutionStatus.FAILED || status === ExecutionStatus.AUDIT_FAILED) {
if (
status === ExecutionStatus.FAILED ||
status === ExecutionStatus.AUDIT_FAILED
) {
updateData.completedAt = new Date();
}

View File

@ -284,6 +284,15 @@ export class TemplateExecuteDto {
})
@IsString()
imageUrl: string;
@ApiProperty({
description: '审核任务ID可选',
required: false,
example: 'audit_task_12345',
})
@IsString()
@IsOptional()
auditTaskId?: string;
}
export class TemplateExecuteResponseDto {