feat: 实现模板执行记录系统和完整的CRUD API接口
- 新增TemplateExecutionEntity实体替代原有的GenerationTask方式 - 实现模板执行记录的完整生命周期管理,包含状态跟踪和性能指标 - 添加模板管理的完整CRUD操作API(创建、更新、删除、查询) - 更新数据库迁移文件,包含n8n_templates和template_executions表 - 完善模板工厂服务,支持执行记录管理和统计分析 - 重构DynamicN8nImageTemplate和DynamicN8nVideoTemplate类名 - 添加用户相关实体:User、PlatformUser、ExtensionData、UserCredit等 - 实现完整的数据库表结构和索引优化
This commit is contained in:
@@ -198,10 +198,9 @@ import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, UpdateDateCol
|
||||
import { PlatformUser } from './platform-user.entity';
|
||||
import { ExtensionData } from './extension-data.entity';
|
||||
import { UserCredit } from './user-credit.entity';
|
||||
import { GenerationTask } from './generation-task.entity';
|
||||
import { TemplateExecutionEntity } from './template-execution.entity';
|
||||
import { UserSubscription } from './user-subscription.entity';
|
||||
import { AdWatch } from './ad-watch.entity';
|
||||
// import { TemplateExecution } from './template-execution.entity'; // 已移除,使用面向对象模板系统
|
||||
|
||||
@Entity('users')
|
||||
export class User {
|
||||
@@ -241,8 +240,8 @@ export class User {
|
||||
@OneToMany(() => UserCredit, userCredit => userCredit.user)
|
||||
credits: UserCredit[];
|
||||
|
||||
@OneToMany(() => GenerationTask, generationTask => generationTask.user)
|
||||
generationTasks: GenerationTask[];
|
||||
@OneToMany(() => TemplateExecutionEntity, execution => execution.userId)
|
||||
templateExecutions: TemplateExecutionEntity[];
|
||||
|
||||
@OneToMany(() => UserSubscription, userSubscription => userSubscription.user)
|
||||
subscriptions: UserSubscription[];
|
||||
@@ -250,7 +249,7 @@ export class User {
|
||||
@OneToMany(() => AdWatch, adWatch => adWatch.user)
|
||||
adWatches: AdWatch[];
|
||||
|
||||
// 注意: 模板执行记录通过面向对象方式管理,不存储在数据库中
|
||||
// 注意: 现在使用 TemplateExecutionEntity 实体管理模板执行记录
|
||||
}
|
||||
```
|
||||
|
||||
@@ -675,37 +674,51 @@ export class AdWatch {
|
||||
}
|
||||
```
|
||||
|
||||
### 8. AI生成任务与模板系统集成说明
|
||||
### 8. 模板执行记录系统说明
|
||||
|
||||
**重要说明**: 本项目采用面向对象的模板管理系统,不使用数据库存储模板定义和执行记录。
|
||||
**重要说明**: 本项目采用混合式模板管理系统,使用数据库存储模板配置和执行记录。
|
||||
|
||||
#### 8.1 模板系统架构
|
||||
- **模板定义**: 通过TypeScript类定义,编译时类型检查
|
||||
- **模板管理**: 通过TemplateManager内存管理,支持动态注册/卸载
|
||||
- **执行记录**: 通过GenerationTask表记录AI生成任务,模板信息作为metadata存储
|
||||
- **模板定义**: 通过 N8nTemplateEntity 存储模板配置
|
||||
- **模板管理**: 通过 N8nTemplateFactoryService 管理模板实例化
|
||||
- **执行记录**: 通过 TemplateExecutionEntity 表记录AI生成任务的完整过程
|
||||
|
||||
#### 8.2 与GenerationTask的关系
|
||||
#### 8.2 TemplateExecutionEntity 实体结构
|
||||
```typescript
|
||||
// GenerationTask实体中存储模板相关信息
|
||||
@Entity('generation_tasks')
|
||||
export class GenerationTask {
|
||||
// ... 其他字段
|
||||
// 现在使用专门的模板执行记录实体
|
||||
@Entity('template_executions')
|
||||
export class TemplateExecutionEntity {
|
||||
@PrimaryGeneratedColumn()
|
||||
id: number;
|
||||
|
||||
@Column({ type: 'json', nullable: true })
|
||||
parameters: any; // 存储模板执行参数
|
||||
@Column({ name: 'template_id' })
|
||||
templateId: number;
|
||||
|
||||
@Column({ type: 'json', nullable: true })
|
||||
metadata: any; // 存储模板代码、版本等信息
|
||||
@Column({ name: 'user_id' })
|
||||
userId: string;
|
||||
|
||||
@Column({ type: 'enum', enum: PlatformType })
|
||||
platform: PlatformType;
|
||||
|
||||
@Column({ type: 'enum', enum: ExecutionType })
|
||||
type: ExecutionType;
|
||||
|
||||
@Column({ type: 'text' })
|
||||
prompt: string;
|
||||
|
||||
@Column({ name: 'output_url', length: 500, nullable: true })
|
||||
outputUrl: string;
|
||||
|
||||
@Column({ type: 'enum', enum: ExecutionStatus, default: ExecutionStatus.PENDING })
|
||||
status: ExecutionStatus;
|
||||
|
||||
@Column({ name: 'credit_cost', default: 0 })
|
||||
creditCost: number;
|
||||
|
||||
@ManyToOne(() => N8nTemplateEntity)
|
||||
@JoinColumn({ name: 'template_id' })
|
||||
template: N8nTemplateEntity;
|
||||
}
|
||||
|
||||
// 使用示例
|
||||
const task = new GenerationTask();
|
||||
task.metadata = {
|
||||
templateCode: 'outfit_change_v1',
|
||||
templateName: '智能换装',
|
||||
templateVersion: '1.0.0',
|
||||
executionId: 'exec_123456789'
|
||||
};
|
||||
```
|
||||
|
||||
### 4. TypeORM配置
|
||||
@@ -923,8 +936,72 @@ export class CreateInitialTables1703001000000 implements MigrationInterface {
|
||||
)
|
||||
`);
|
||||
|
||||
// 注意: AI模板系统采用面向对象设计,不需要数据库表
|
||||
// 模板定义通过TypeScript类管理,执行记录通过GenerationTask表的metadata字段存储
|
||||
// 创建N8N模板配置表
|
||||
await queryRunner.query(`
|
||||
CREATE TABLE "n8n_templates" (
|
||||
"id" bigint NOT NULL AUTO_INCREMENT,
|
||||
"code" varchar(100) NOT NULL UNIQUE,
|
||||
"name" varchar(200) NOT NULL,
|
||||
"description" text,
|
||||
"creditCost" int NOT NULL DEFAULT 0,
|
||||
"version" varchar(50) NOT NULL,
|
||||
"inputExampleUrl" text,
|
||||
"outputExampleUrl" text,
|
||||
"tags" json,
|
||||
"templateType" enum('image', 'video') NOT NULL,
|
||||
"templateClass" varchar(100) NOT NULL,
|
||||
"imageModel" varchar(100),
|
||||
"imagePrompt" text,
|
||||
"videoModel" varchar(100),
|
||||
"videoPrompt" text,
|
||||
"duration" int,
|
||||
"aspectRatio" varchar(20),
|
||||
"isActive" boolean DEFAULT TRUE,
|
||||
"sortOrder" int DEFAULT 0,
|
||||
"createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
CONSTRAINT "PK_n8n_templates_id" PRIMARY KEY ("id")
|
||||
)
|
||||
`);
|
||||
|
||||
// 创建模板执行记录表
|
||||
await queryRunner.query(`
|
||||
CREATE TYPE "execution_status" AS ENUM('pending', 'processing', 'completed', 'failed', 'cancelled')
|
||||
`);
|
||||
|
||||
await queryRunner.query(`
|
||||
CREATE TYPE "execution_type" AS ENUM('image', 'video')
|
||||
`);
|
||||
|
||||
await queryRunner.query(`
|
||||
CREATE TABLE "template_executions" (
|
||||
"id" bigint NOT NULL AUTO_INCREMENT,
|
||||
"templateId" bigint NOT NULL,
|
||||
"userId" uuid NOT NULL,
|
||||
"platform" "platform_type" NOT NULL,
|
||||
"type" "execution_type" NOT NULL,
|
||||
"prompt" text NOT NULL,
|
||||
"inputImageUrl" varchar(500),
|
||||
"outputUrl" varchar(500),
|
||||
"thumbnailUrl" varchar(500),
|
||||
"status" "execution_status" DEFAULT 'pending',
|
||||
"progress" int DEFAULT 0,
|
||||
"errorMessage" text,
|
||||
"executionResult" json,
|
||||
"creditCost" int DEFAULT 0,
|
||||
"creditTransactionId" varchar(100),
|
||||
"inputParams" json,
|
||||
"executionConfig" json,
|
||||
"startedAt" TIMESTAMP NULL,
|
||||
"completedAt" TIMESTAMP NULL,
|
||||
"executionDuration" int,
|
||||
"createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
CONSTRAINT "PK_template_executions_id" PRIMARY KEY ("id"),
|
||||
CONSTRAINT "FK_template_executions_templateId" FOREIGN KEY ("templateId") REFERENCES "n8n_templates"("id") ON DELETE CASCADE,
|
||||
CONSTRAINT "FK_template_executions_userId" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE CASCADE
|
||||
)
|
||||
`);
|
||||
|
||||
// 创建索引
|
||||
await queryRunner.query(`CREATE INDEX "IDX_platform_users_platform" ON "platform_users" ("platform")`);
|
||||
@@ -963,23 +1040,36 @@ export class CreateInitialTables1703001000000 implements MigrationInterface {
|
||||
await queryRunner.query(`CREATE INDEX "IDX_ad_watches_status" ON "ad_watches" ("status")`);
|
||||
await queryRunner.query(`CREATE INDEX "IDX_ad_watches_createdAt" ON "ad_watches" ("createdAt")`);
|
||||
|
||||
// 注意: 模板系统索引已移除,使用面向对象管理
|
||||
// N8n模板表索引
|
||||
await queryRunner.query(`CREATE INDEX "IDX_n8n_templates_code" ON "n8n_templates" ("code")`);
|
||||
await queryRunner.query(`CREATE INDEX "IDX_n8n_templates_templateType" ON "n8n_templates" ("templateType")`);
|
||||
await queryRunner.query(`CREATE INDEX "IDX_n8n_templates_templateClass" ON "n8n_templates" ("templateClass")`);
|
||||
await queryRunner.query(`CREATE INDEX "IDX_n8n_templates_isActive" ON "n8n_templates" ("isActive")`);
|
||||
|
||||
// 模板执行记录表索引
|
||||
await queryRunner.query(`CREATE INDEX "IDX_template_executions_templateId" ON "template_executions" ("templateId")`);
|
||||
await queryRunner.query(`CREATE INDEX "IDX_template_executions_userId" ON "template_executions" ("userId")`);
|
||||
await queryRunner.query(`CREATE INDEX "IDX_template_executions_platform" ON "template_executions" ("platform")`);
|
||||
await queryRunner.query(`CREATE INDEX "IDX_template_executions_status" ON "template_executions" ("status")`);
|
||||
await queryRunner.query(`CREATE INDEX "IDX_template_executions_type" ON "template_executions" ("type")`);
|
||||
await queryRunner.query(`CREATE INDEX "IDX_template_executions_creditTransactionId" ON "template_executions" ("creditTransactionId")`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`DROP TABLE "template_executions"`);
|
||||
await queryRunner.query(`DROP TABLE "n8n_templates"`);
|
||||
await queryRunner.query(`DROP TABLE "ad_watches"`);
|
||||
await queryRunner.query(`DROP TABLE "user_subscriptions"`);
|
||||
await queryRunner.query(`DROP TABLE "generation_tasks"`);
|
||||
await queryRunner.query(`DROP TABLE "user_credits"`);
|
||||
await queryRunner.query(`DROP TABLE "extension_data"`);
|
||||
await queryRunner.query(`DROP TABLE "platform_users"`);
|
||||
await queryRunner.query(`DROP TABLE "users"`);
|
||||
await queryRunner.query(`DROP TYPE "execution_type"`);
|
||||
await queryRunner.query(`DROP TYPE "execution_status"`);
|
||||
await queryRunner.query(`DROP TYPE "ad_status"`);
|
||||
await queryRunner.query(`DROP TYPE "ad_type"`);
|
||||
await queryRunner.query(`DROP TYPE "subscription_status"`);
|
||||
await queryRunner.query(`DROP TYPE "subscription_plan"`);
|
||||
await queryRunner.query(`DROP TYPE "task_status"`);
|
||||
await queryRunner.query(`DROP TYPE "generation_type"`);
|
||||
await queryRunner.query(`DROP TYPE "credit_source"`);
|
||||
await queryRunner.query(`DROP TYPE "credit_type"`);
|
||||
await queryRunner.query(`DROP TYPE "platform_type"`);
|
||||
|
||||
Reference in New Issue
Block a user