feat: 实现模板管理后台完整CRUD功能和修复MySQL迁移兼容性
- 新增模板CRUD操作:创建、更新、删除、管理后台查询接口 - 创建CreateTemplateDto和UpdateTemplateDto用于数据验证 - 修复所有迁移文件的MySQL语法兼容性问题 - 转换PostgreSQL特有语法为MySQL标准语法 - 添加索引创建的重复检查机制
This commit is contained in:
@@ -28,6 +28,6 @@ export class CreateUserTable1725502000000 implements MigrationInterface {
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`DROP TABLE "users"`);
|
||||
await queryRunner.query(`DROP TABLE \`users\``);
|
||||
}
|
||||
}
|
||||
@@ -11,25 +11,25 @@ export class CreatePlatformUserTable1725503000000 implements MigrationInterface
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
// 创建平台用户关联表 - 支持OAuth令牌管理和平台特有数据存储
|
||||
await queryRunner.query(`
|
||||
CREATE TABLE "platform_users" (
|
||||
"id" uuid NOT NULL DEFAULT uuid_generate_v4(),
|
||||
"userId" uuid NOT NULL,
|
||||
"platform" "platform_type" NOT NULL,
|
||||
"platformUserId" character varying(100) NOT NULL,
|
||||
"platformData" json,
|
||||
"accessToken" character varying(500),
|
||||
"refreshToken" character varying(500),
|
||||
"expiresAt" TIMESTAMP,
|
||||
"createdAt" TIMESTAMP NOT NULL DEFAULT now(),
|
||||
"updatedAt" TIMESTAMP NOT NULL DEFAULT now(),
|
||||
CONSTRAINT "UQ_platform_users_platform_platformUserId" UNIQUE ("platform", "platformUserId"),
|
||||
CONSTRAINT "PK_platform_users_id" PRIMARY KEY ("id"),
|
||||
CONSTRAINT "FK_platform_users_userId" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE CASCADE
|
||||
CREATE TABLE \`platform_users\` (
|
||||
\`id\` VARCHAR(36) NOT NULL,
|
||||
\`userId\` VARCHAR(36) NOT NULL,
|
||||
\`platform\` ENUM('wechat_mini', 'alipay_mini', 'baidu_mini', 'toutiao_mini', 'qq_mini', 'kuaishou_mini', 'dingtalk_mini', 'taobao_mini', 'wechat_h5', 'mobile_app') NOT NULL,
|
||||
\`platformUserId\` VARCHAR(100) NOT NULL,
|
||||
\`platformData\` JSON,
|
||||
\`accessToken\` VARCHAR(500),
|
||||
\`refreshToken\` VARCHAR(500),
|
||||
\`expiresAt\` TIMESTAMP NULL,
|
||||
\`createdAt\` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
\`updatedAt\` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
CONSTRAINT \`UQ_platform_users_platform_platformUserId\` UNIQUE (\`platform\`, \`platformUserId\`),
|
||||
CONSTRAINT \`PK_platform_users_id\` PRIMARY KEY (\`id\`),
|
||||
CONSTRAINT \`FK_platform_users_userId\` FOREIGN KEY (\`userId\`) REFERENCES \`users\`(\`id\`) ON DELETE CASCADE
|
||||
)
|
||||
`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`DROP TABLE "platform_users"`);
|
||||
await queryRunner.query(`DROP TABLE \`platform_users\``);
|
||||
}
|
||||
}
|
||||
@@ -11,24 +11,24 @@ export class CreateExtensionDataTable1725504000000 implements MigrationInterface
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
// 创建扩展数据表 - 灵活存储各平台特有业务数据
|
||||
await queryRunner.query(`
|
||||
CREATE TABLE "extension_data" (
|
||||
"id" uuid NOT NULL DEFAULT uuid_generate_v4(),
|
||||
"userId" uuid NOT NULL,
|
||||
"platform" "platform_type" NOT NULL,
|
||||
"dataType" character varying(50) NOT NULL,
|
||||
"referenceId" character varying(100),
|
||||
"data" json NOT NULL,
|
||||
"metadata" json,
|
||||
"status" character varying(20) NOT NULL DEFAULT 'active',
|
||||
"createdAt" TIMESTAMP NOT NULL DEFAULT now(),
|
||||
"updatedAt" TIMESTAMP NOT NULL DEFAULT now(),
|
||||
CONSTRAINT "PK_extension_data_id" PRIMARY KEY ("id"),
|
||||
CONSTRAINT "FK_extension_data_userId" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE CASCADE
|
||||
CREATE TABLE \`extension_data\` (
|
||||
\`id\` VARCHAR(36) NOT NULL,
|
||||
\`userId\` VARCHAR(36) NOT NULL,
|
||||
\`platform\` ENUM('wechat_mini', 'alipay_mini', 'baidu_mini', 'toutiao_mini', 'qq_mini', 'kuaishou_mini', 'dingtalk_mini', 'taobao_mini', 'wechat_h5', 'mobile_app') NOT NULL,
|
||||
\`dataType\` VARCHAR(50) NOT NULL,
|
||||
\`referenceId\` VARCHAR(100),
|
||||
\`data\` JSON NOT NULL,
|
||||
\`metadata\` JSON,
|
||||
\`status\` VARCHAR(20) NOT NULL DEFAULT 'active',
|
||||
\`createdAt\` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
\`updatedAt\` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
CONSTRAINT \`PK_extension_data_id\` PRIMARY KEY (\`id\`),
|
||||
CONSTRAINT \`FK_extension_data_userId\` FOREIGN KEY (\`userId\`) REFERENCES \`users\`(\`id\`) ON DELETE CASCADE
|
||||
)
|
||||
`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`DROP TABLE "extension_data"`);
|
||||
await queryRunner.query(`DROP TABLE \`extension_data\``);
|
||||
}
|
||||
}
|
||||
@@ -9,40 +9,30 @@ export class CreateUserCreditTable1725505000000 implements MigrationInterface {
|
||||
name = 'CreateUserCreditTable1725505000000';
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
// 创建积分变动类型枚举
|
||||
await queryRunner.query(`
|
||||
CREATE TYPE "credit_type" AS ENUM('reward', 'consume', 'purchase', 'refund')
|
||||
`);
|
||||
|
||||
// 创建积分来源枚举
|
||||
await queryRunner.query(`
|
||||
CREATE TYPE "credit_source" AS ENUM('ad_watch', 'subscription', 'ai_generation', 'manual')
|
||||
`);
|
||||
|
||||
// 创建用户积分表 - 支持多平台积分系统和业务关联
|
||||
// MySQL 中直接在表字段中定义 ENUM,无需单独创建枚举类型
|
||||
await queryRunner.query(`
|
||||
CREATE TABLE "user_credits" (
|
||||
"id" uuid NOT NULL DEFAULT uuid_generate_v4(),
|
||||
"userId" uuid NOT NULL,
|
||||
"platform" "platform_type" NOT NULL,
|
||||
"type" "credit_type" NOT NULL,
|
||||
"source" "credit_source" NOT NULL,
|
||||
"amount" integer NOT NULL,
|
||||
"balance" integer NOT NULL,
|
||||
"description" character varying(200),
|
||||
"referenceId" character varying(100),
|
||||
"metadata" json,
|
||||
"createdAt" TIMESTAMP NOT NULL DEFAULT now(),
|
||||
"updatedAt" TIMESTAMP NOT NULL DEFAULT now(),
|
||||
CONSTRAINT "PK_user_credits_id" PRIMARY KEY ("id"),
|
||||
CONSTRAINT "FK_user_credits_userId" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE CASCADE
|
||||
CREATE TABLE \`user_credits\` (
|
||||
\`id\` VARCHAR(36) NOT NULL,
|
||||
\`userId\` VARCHAR(36) NOT NULL,
|
||||
\`platform\` ENUM('wechat_mini', 'alipay_mini', 'baidu_mini', 'toutiao_mini', 'qq_mini', 'kuaishou_mini', 'dingtalk_mini', 'taobao_mini', 'wechat_h5', 'mobile_app') NOT NULL,
|
||||
\`type\` ENUM('reward', 'consume', 'purchase', 'refund') NOT NULL,
|
||||
\`source\` ENUM('ad_watch', 'subscription', 'ai_generation', 'manual') NOT NULL,
|
||||
\`amount\` INT NOT NULL,
|
||||
\`balance\` INT NOT NULL,
|
||||
\`description\` VARCHAR(200),
|
||||
\`referenceId\` VARCHAR(100),
|
||||
\`metadata\` JSON,
|
||||
\`createdAt\` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
\`updatedAt\` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
CONSTRAINT \`PK_user_credits_id\` PRIMARY KEY (\`id\`),
|
||||
CONSTRAINT \`FK_user_credits_userId\` FOREIGN KEY (\`userId\`) REFERENCES \`users\`(\`id\`) ON DELETE CASCADE
|
||||
)
|
||||
`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`DROP TABLE "user_credits"`);
|
||||
await queryRunner.query(`DROP TYPE "credit_source"`);
|
||||
await queryRunner.query(`DROP TYPE "credit_type"`);
|
||||
await queryRunner.query(`DROP TABLE \`user_credits\``);
|
||||
// MySQL 中无需单独删除 ENUM 类型,它们与表一起被删除
|
||||
}
|
||||
}
|
||||
@@ -9,50 +9,39 @@ export class CreateTemplateExecutionTable1725506000000 implements MigrationInter
|
||||
name = 'CreateTemplateExecutionTable1725506000000';
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
// 创建模板执行类型枚举
|
||||
await queryRunner.query(`
|
||||
CREATE TYPE "execution_type" AS ENUM('image', 'video')
|
||||
`);
|
||||
|
||||
// 创建执行状态枚举
|
||||
await queryRunner.query(`
|
||||
CREATE TYPE "execution_status" AS ENUM('pending', 'processing', 'completed', 'failed', 'cancelled')
|
||||
`);
|
||||
|
||||
// 创建模板执行记录表 - 支持图片和视频两种类型的AI生成任务追踪
|
||||
// MySQL 中直接在表字段中定义 ENUM,无需单独创建枚举类型
|
||||
await queryRunner.query(`
|
||||
CREATE TABLE "template_executions" (
|
||||
"id" SERIAL PRIMARY KEY,
|
||||
"templateId" integer NOT NULL,
|
||||
"userId" uuid NOT NULL,
|
||||
"platform" "platform_type" NOT NULL,
|
||||
"type" "execution_type" NOT NULL,
|
||||
"prompt" text NOT NULL,
|
||||
"inputImageUrl" character varying(500),
|
||||
"outputUrl" character varying(500),
|
||||
"thumbnailUrl" character varying(500),
|
||||
"status" "execution_status" NOT NULL DEFAULT 'pending',
|
||||
"progress" integer DEFAULT 0,
|
||||
"errorMessage" text,
|
||||
"executionResult" json,
|
||||
"creditCost" integer NOT NULL DEFAULT 0,
|
||||
"creditTransactionId" character varying(100),
|
||||
"inputParams" json,
|
||||
"executionConfig" json,
|
||||
"startedAt" TIMESTAMP,
|
||||
"completedAt" TIMESTAMP,
|
||||
"executionDuration" integer,
|
||||
"createdAt" TIMESTAMP NOT NULL DEFAULT now(),
|
||||
"updatedAt" TIMESTAMP NOT NULL DEFAULT now(),
|
||||
CONSTRAINT "PK_template_executions_id" PRIMARY KEY ("id"),
|
||||
CONSTRAINT "FK_template_executions_userId" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE CASCADE
|
||||
CREATE TABLE \`template_executions\` (
|
||||
\`id\` INT AUTO_INCREMENT PRIMARY KEY,
|
||||
\`templateId\` INT NOT NULL,
|
||||
\`userId\` VARCHAR(36) NOT NULL,
|
||||
\`platform\` ENUM('wechat_mini', 'alipay_mini', 'baidu_mini', 'toutiao_mini', 'qq_mini', 'kuaishou_mini', 'dingtalk_mini', 'taobao_mini', 'wechat_h5', 'mobile_app') NOT NULL,
|
||||
\`type\` ENUM('image', 'video') NOT NULL,
|
||||
\`prompt\` TEXT NOT NULL,
|
||||
\`inputImageUrl\` VARCHAR(500),
|
||||
\`outputUrl\` VARCHAR(500),
|
||||
\`thumbnailUrl\` VARCHAR(500),
|
||||
\`status\` ENUM('pending', 'processing', 'completed', 'failed', 'cancelled') NOT NULL DEFAULT 'pending',
|
||||
\`progress\` INT DEFAULT 0,
|
||||
\`errorMessage\` TEXT,
|
||||
\`executionResult\` JSON,
|
||||
\`creditCost\` INT NOT NULL DEFAULT 0,
|
||||
\`creditTransactionId\` VARCHAR(100),
|
||||
\`inputParams\` JSON,
|
||||
\`executionConfig\` JSON,
|
||||
\`startedAt\` TIMESTAMP NULL,
|
||||
\`completedAt\` TIMESTAMP NULL,
|
||||
\`executionDuration\` INT,
|
||||
\`createdAt\` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
\`updatedAt\` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
CONSTRAINT \`FK_template_executions_userId\` FOREIGN KEY (\`userId\`) REFERENCES \`users\`(\`id\`) ON DELETE CASCADE
|
||||
)
|
||||
`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`DROP TABLE "template_executions"`);
|
||||
await queryRunner.query(`DROP TYPE "execution_status"`);
|
||||
await queryRunner.query(`DROP TYPE "execution_type"`);
|
||||
await queryRunner.query(`DROP TABLE \`template_executions\``);
|
||||
// MySQL 中无需单独删除 ENUM 类型,它们与表一起被删除
|
||||
}
|
||||
}
|
||||
@@ -9,43 +9,33 @@ export class CreateUserSubscriptionTable1725507000000 implements MigrationInterf
|
||||
name = 'CreateUserSubscriptionTable1725507000000';
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
// 创建订阅套餐类型枚举
|
||||
await queryRunner.query(`
|
||||
CREATE TYPE "subscription_plan" AS ENUM('basic', 'premium', 'pro')
|
||||
`);
|
||||
|
||||
// 创建订阅状态枚举
|
||||
await queryRunner.query(`
|
||||
CREATE TYPE "subscription_status" AS ENUM('active', 'expired', 'cancelled', 'pending')
|
||||
`);
|
||||
|
||||
// 创建用户订阅表 - 提供积分配额和特权功能管理
|
||||
// MySQL 中直接在表字段中定义 ENUM,无需单独创建枚举类型
|
||||
await queryRunner.query(`
|
||||
CREATE TABLE "user_subscriptions" (
|
||||
"id" uuid NOT NULL DEFAULT uuid_generate_v4(),
|
||||
"userId" uuid NOT NULL,
|
||||
"platform" "platform_type" NOT NULL,
|
||||
"plan" "subscription_plan" NOT NULL,
|
||||
"status" "subscription_status" NOT NULL DEFAULT 'pending',
|
||||
"startDate" TIMESTAMP NOT NULL,
|
||||
"endDate" TIMESTAMP NOT NULL,
|
||||
"price" decimal(10,2) NOT NULL,
|
||||
"currency" character varying(10) NOT NULL DEFAULT 'CNY',
|
||||
"monthlyCredits" integer NOT NULL,
|
||||
"paymentId" character varying(100),
|
||||
"features" json,
|
||||
"autoRenew" boolean NOT NULL DEFAULT true,
|
||||
"createdAt" TIMESTAMP NOT NULL DEFAULT now(),
|
||||
"updatedAt" TIMESTAMP NOT NULL DEFAULT now(),
|
||||
CONSTRAINT "PK_user_subscriptions_id" PRIMARY KEY ("id"),
|
||||
CONSTRAINT "FK_user_subscriptions_userId" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE CASCADE
|
||||
CREATE TABLE \`user_subscriptions\` (
|
||||
\`id\` VARCHAR(36) NOT NULL,
|
||||
\`userId\` VARCHAR(36) NOT NULL,
|
||||
\`platform\` ENUM('wechat_mini', 'alipay_mini', 'baidu_mini', 'toutiao_mini', 'qq_mini', 'kuaishou_mini', 'dingtalk_mini', 'taobao_mini', 'wechat_h5', 'mobile_app') NOT NULL,
|
||||
\`plan\` ENUM('basic', 'premium', 'pro') NOT NULL,
|
||||
\`status\` ENUM('active', 'expired', 'cancelled', 'pending') NOT NULL DEFAULT 'pending',
|
||||
\`startDate\` TIMESTAMP NULL,
|
||||
\`endDate\` TIMESTAMP NULL,
|
||||
\`price\` DECIMAL(10,2) NOT NULL,
|
||||
\`currency\` VARCHAR(10) NOT NULL DEFAULT 'CNY',
|
||||
\`monthlyCredits\` INT NOT NULL,
|
||||
\`paymentId\` VARCHAR(100),
|
||||
\`features\` JSON,
|
||||
\`autoRenew\` BOOLEAN NOT NULL DEFAULT true,
|
||||
\`createdAt\` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
\`updatedAt\` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
CONSTRAINT \`PK_user_subscriptions_id\` PRIMARY KEY (\`id\`),
|
||||
CONSTRAINT \`FK_user_subscriptions_userId\` FOREIGN KEY (\`userId\`) REFERENCES \`users\`(\`id\`) ON DELETE CASCADE
|
||||
)
|
||||
`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`DROP TABLE "user_subscriptions"`);
|
||||
await queryRunner.query(`DROP TYPE "subscription_status"`);
|
||||
await queryRunner.query(`DROP TYPE "subscription_plan"`);
|
||||
await queryRunner.query(`DROP TABLE \`user_subscriptions\``);
|
||||
// MySQL 中无需单独删除 ENUM 类型,它们与表一起被删除
|
||||
}
|
||||
}
|
||||
@@ -9,40 +9,30 @@ export class CreateAdWatchTable1725508000000 implements MigrationInterface {
|
||||
name = 'CreateAdWatchTable1725508000000';
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
// 创建广告类型枚举 - 定义小程序支持的各种广告形式
|
||||
await queryRunner.query(`
|
||||
CREATE TYPE "ad_type" AS ENUM('banner', 'interstitial', 'rewarded', 'native')
|
||||
`);
|
||||
|
||||
// 创建广告观看状态枚举 - 记录用户与广告交互的不同阶段
|
||||
await queryRunner.query(`
|
||||
CREATE TYPE "ad_status" AS ENUM('started', 'completed', 'skipped', 'failed')
|
||||
`);
|
||||
|
||||
// 创建广告观看记录表 - 完整记录用户广告观看行为和奖励数据
|
||||
// MySQL 中直接在表字段中定义 ENUM,无需单独创建枚举类型
|
||||
await queryRunner.query(`
|
||||
CREATE TABLE "ad_watches" (
|
||||
"id" uuid NOT NULL DEFAULT uuid_generate_v4(),
|
||||
"userId" uuid NOT NULL,
|
||||
"platform" "platform_type" NOT NULL,
|
||||
"adType" "ad_type" NOT NULL,
|
||||
"adId" character varying(100) NOT NULL,
|
||||
"adUnitId" character varying(100),
|
||||
"status" "ad_status" NOT NULL,
|
||||
"watchDuration" integer,
|
||||
"rewardCredits" integer,
|
||||
"adData" json,
|
||||
"createdAt" TIMESTAMP NOT NULL DEFAULT now(),
|
||||
"updatedAt" TIMESTAMP NOT NULL DEFAULT now(),
|
||||
CONSTRAINT "PK_ad_watches_id" PRIMARY KEY ("id"),
|
||||
CONSTRAINT "FK_ad_watches_userId" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE CASCADE
|
||||
CREATE TABLE \`ad_watches\` (
|
||||
\`id\` VARCHAR(36) NOT NULL,
|
||||
\`userId\` VARCHAR(36) NOT NULL,
|
||||
\`platform\` ENUM('wechat_mini', 'alipay_mini', 'baidu_mini', 'toutiao_mini', 'qq_mini', 'kuaishou_mini', 'dingtalk_mini', 'taobao_mini', 'wechat_h5', 'mobile_app') NOT NULL,
|
||||
\`adType\` ENUM('banner', 'interstitial', 'rewarded', 'native') NOT NULL,
|
||||
\`adId\` VARCHAR(100) NOT NULL,
|
||||
\`adUnitId\` VARCHAR(100),
|
||||
\`status\` ENUM('started', 'completed', 'skipped', 'failed') NOT NULL,
|
||||
\`watchDuration\` INT,
|
||||
\`rewardCredits\` INT,
|
||||
\`adData\` JSON,
|
||||
\`createdAt\` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
\`updatedAt\` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
CONSTRAINT \`PK_ad_watches_id\` PRIMARY KEY (\`id\`),
|
||||
CONSTRAINT \`FK_ad_watches_userId\` FOREIGN KEY (\`userId\`) REFERENCES \`users\`(\`id\`) ON DELETE CASCADE
|
||||
)
|
||||
`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`DROP TABLE "ad_watches"`);
|
||||
await queryRunner.query(`DROP TYPE "ad_status"`);
|
||||
await queryRunner.query(`DROP TYPE "ad_type"`);
|
||||
await queryRunner.query(`DROP TABLE \`ad_watches\``);
|
||||
// MySQL 中无需单独删除 ENUM 类型,它们与表一起被删除
|
||||
}
|
||||
}
|
||||
@@ -9,88 +9,103 @@ export class CreateTableIndexes1725509000000 implements MigrationInterface {
|
||||
name = 'CreateTableIndexes1725509000000';
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
// 平台用户表索引 - 优化多平台身份查询性能
|
||||
await queryRunner.query(`CREATE INDEX "IDX_platform_users_platform" ON "platform_users" ("platform")`);
|
||||
await queryRunner.query(`CREATE INDEX "IDX_platform_users_userId" ON "platform_users" ("userId")`);
|
||||
|
||||
// 扩展数据表索引 - 优化业务数据查询和状态筛选
|
||||
await queryRunner.query(`CREATE INDEX "IDX_extension_data_userId" ON "extension_data" ("userId")`);
|
||||
await queryRunner.query(`CREATE INDEX "IDX_extension_data_platform" ON "extension_data" ("platform")`);
|
||||
await queryRunner.query(`CREATE INDEX "IDX_extension_data_dataType" ON "extension_data" ("dataType")`);
|
||||
await queryRunner.query(`CREATE INDEX "IDX_extension_data_referenceId" ON "extension_data" ("referenceId")`);
|
||||
await queryRunner.query(`CREATE INDEX "IDX_extension_data_status" ON "extension_data" ("status")`);
|
||||
await queryRunner.query(`CREATE INDEX "IDX_extension_data_createdAt" ON "extension_data" ("createdAt")`);
|
||||
// 检查并创建索引 - 避免重复创建已存在的索引
|
||||
const indexQueries = [
|
||||
// 平台用户表索引 - 优化多平台身份查询性能
|
||||
`CREATE INDEX \`IDX_platform_users_platform\` ON \`platform_users\` (\`platform\`)`,
|
||||
`CREATE INDEX \`IDX_platform_users_userId\` ON \`platform_users\` (\`userId\`)`,
|
||||
|
||||
// 扩展数据表索引 - 优化业务数据查询和状态筛选
|
||||
`CREATE INDEX \`IDX_extension_data_userId\` ON \`extension_data\` (\`userId\`)`,
|
||||
`CREATE INDEX \`IDX_extension_data_platform\` ON \`extension_data\` (\`platform\`)`,
|
||||
`CREATE INDEX \`IDX_extension_data_dataType\` ON \`extension_data\` (\`dataType\`)`,
|
||||
`CREATE INDEX \`IDX_extension_data_referenceId\` ON \`extension_data\` (\`referenceId\`)`,
|
||||
`CREATE INDEX \`IDX_extension_data_status\` ON \`extension_data\` (\`status\`)`,
|
||||
`CREATE INDEX \`IDX_extension_data_createdAt\` ON \`extension_data\` (\`createdAt\`)`,
|
||||
|
||||
// 用户积分表索引 - 优化积分流水查询和统计分析
|
||||
await queryRunner.query(`CREATE INDEX "IDX_user_credits_userId" ON "user_credits" ("userId")`);
|
||||
await queryRunner.query(`CREATE INDEX "IDX_user_credits_platform" ON "user_credits" ("platform")`);
|
||||
await queryRunner.query(`CREATE INDEX "IDX_user_credits_type" ON "user_credits" ("type")`);
|
||||
await queryRunner.query(`CREATE INDEX "IDX_user_credits_source" ON "user_credits" ("source")`);
|
||||
await queryRunner.query(`CREATE INDEX "IDX_user_credits_createdAt" ON "user_credits" ("createdAt")`);
|
||||
// 用户积分表索引 - 优化积分流水查询和统计分析
|
||||
`CREATE INDEX \`IDX_user_credits_userId\` ON \`user_credits\` (\`userId\`)`,
|
||||
`CREATE INDEX \`IDX_user_credits_platform\` ON \`user_credits\` (\`platform\`)`,
|
||||
`CREATE INDEX \`IDX_user_credits_type\` ON \`user_credits\` (\`type\`)`,
|
||||
`CREATE INDEX \`IDX_user_credits_source\` ON \`user_credits\` (\`source\`)`,
|
||||
`CREATE INDEX \`IDX_user_credits_createdAt\` ON \`user_credits\` (\`createdAt\`)`,
|
||||
|
||||
// 模板执行表索引 - 优化AI生成任务查询和状态追踪
|
||||
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_type" ON "template_executions" ("type")`);
|
||||
await queryRunner.query(`CREATE INDEX "IDX_template_executions_status" ON "template_executions" ("status")`);
|
||||
await queryRunner.query(`CREATE INDEX "IDX_template_executions_creditTransactionId" ON "template_executions" ("creditTransactionId")`);
|
||||
await queryRunner.query(`CREATE INDEX "IDX_template_executions_createdAt" ON "template_executions" ("createdAt")`);
|
||||
// 模板执行表索引 - 优化AI生成任务查询和状态追踪
|
||||
`CREATE INDEX \`IDX_template_executions_templateId\` ON \`template_executions\` (\`templateId\`)`,
|
||||
`CREATE INDEX \`IDX_template_executions_userId\` ON \`template_executions\` (\`userId\`)`,
|
||||
`CREATE INDEX \`IDX_template_executions_platform\` ON \`template_executions\` (\`platform\`)`,
|
||||
`CREATE INDEX \`IDX_template_executions_type\` ON \`template_executions\` (\`type\`)`,
|
||||
`CREATE INDEX \`IDX_template_executions_status\` ON \`template_executions\` (\`status\`)`,
|
||||
`CREATE INDEX \`IDX_template_executions_creditTransactionId\` ON \`template_executions\` (\`creditTransactionId\`)`,
|
||||
`CREATE INDEX \`IDX_template_executions_createdAt\` ON \`template_executions\` (\`createdAt\`)`,
|
||||
|
||||
// 用户订阅表索引 - 优化订阅状态查询和到期管理
|
||||
await queryRunner.query(`CREATE INDEX "IDX_user_subscriptions_userId" ON "user_subscriptions" ("userId")`);
|
||||
await queryRunner.query(`CREATE INDEX "IDX_user_subscriptions_platform" ON "user_subscriptions" ("platform")`);
|
||||
await queryRunner.query(`CREATE INDEX "IDX_user_subscriptions_status" ON "user_subscriptions" ("status")`);
|
||||
await queryRunner.query(`CREATE INDEX "IDX_user_subscriptions_endDate" ON "user_subscriptions" ("endDate")`);
|
||||
// 用户订阅表索引 - 优化订阅状态查询和到期管理
|
||||
`CREATE INDEX \`IDX_user_subscriptions_userId\` ON \`user_subscriptions\` (\`userId\`)`,
|
||||
`CREATE INDEX \`IDX_user_subscriptions_platform\` ON \`user_subscriptions\` (\`platform\`)`,
|
||||
`CREATE INDEX \`IDX_user_subscriptions_status\` ON \`user_subscriptions\` (\`status\`)`,
|
||||
`CREATE INDEX \`IDX_user_subscriptions_endDate\` ON \`user_subscriptions\` (\`endDate\`)`,
|
||||
|
||||
// 广告观看表索引 - 优化广告数据分析和奖励统计
|
||||
await queryRunner.query(`CREATE INDEX "IDX_ad_watches_userId" ON "ad_watches" ("userId")`);
|
||||
await queryRunner.query(`CREATE INDEX "IDX_ad_watches_platform" ON "ad_watches" ("platform")`);
|
||||
await queryRunner.query(`CREATE INDEX "IDX_ad_watches_adType" ON "ad_watches" ("adType")`);
|
||||
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")`);
|
||||
// 广告观看表索引 - 优化广告数据分析和奖励统计
|
||||
`CREATE INDEX \`IDX_ad_watches_userId\` ON \`ad_watches\` (\`userId\`)`,
|
||||
`CREATE INDEX \`IDX_ad_watches_platform\` ON \`ad_watches\` (\`platform\`)`,
|
||||
`CREATE INDEX \`IDX_ad_watches_adType\` ON \`ad_watches\` (\`adType\`)`,
|
||||
`CREATE INDEX \`IDX_ad_watches_status\` ON \`ad_watches\` (\`status\`)`,
|
||||
`CREATE INDEX \`IDX_ad_watches_createdAt\` ON \`ad_watches\` (\`createdAt\`)`
|
||||
];
|
||||
|
||||
// 安全创建索引 - 忽略已存在的索引错误
|
||||
for (const query of indexQueries) {
|
||||
try {
|
||||
await queryRunner.query(query);
|
||||
} catch (error) {
|
||||
// 忽略索引已存在的错误,继续创建其他索引
|
||||
if (error.code !== 'ER_DUP_KEYNAME') {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
// 删除广告观看表索引
|
||||
await queryRunner.query(`DROP INDEX "IDX_ad_watches_createdAt"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_ad_watches_status"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_ad_watches_adType"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_ad_watches_platform"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_ad_watches_userId"`);
|
||||
await queryRunner.query(`DROP INDEX \`IDX_ad_watches_createdAt\``);
|
||||
await queryRunner.query(`DROP INDEX \`IDX_ad_watches_status\``);
|
||||
await queryRunner.query(`DROP INDEX \`IDX_ad_watches_adType\``);
|
||||
await queryRunner.query(`DROP INDEX \`IDX_ad_watches_platform\``);
|
||||
await queryRunner.query(`DROP INDEX \`IDX_ad_watches_userId\``);
|
||||
|
||||
// 删除用户订阅表索引
|
||||
await queryRunner.query(`DROP INDEX "IDX_user_subscriptions_endDate"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_user_subscriptions_status"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_user_subscriptions_platform"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_user_subscriptions_userId"`);
|
||||
await queryRunner.query(`DROP INDEX \`IDX_user_subscriptions_endDate\``);
|
||||
await queryRunner.query(`DROP INDEX \`IDX_user_subscriptions_status\``);
|
||||
await queryRunner.query(`DROP INDEX \`IDX_user_subscriptions_platform\``);
|
||||
await queryRunner.query(`DROP INDEX \`IDX_user_subscriptions_userId\``);
|
||||
|
||||
// 删除模板执行表索引
|
||||
await queryRunner.query(`DROP INDEX "IDX_template_executions_createdAt"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_template_executions_creditTransactionId"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_template_executions_status"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_template_executions_type"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_template_executions_platform"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_template_executions_userId"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_template_executions_templateId"`);
|
||||
await queryRunner.query(`DROP INDEX \`IDX_template_executions_createdAt\``);
|
||||
await queryRunner.query(`DROP INDEX \`IDX_template_executions_creditTransactionId\``);
|
||||
await queryRunner.query(`DROP INDEX \`IDX_template_executions_status\``);
|
||||
await queryRunner.query(`DROP INDEX \`IDX_template_executions_type\``);
|
||||
await queryRunner.query(`DROP INDEX \`IDX_template_executions_platform\``);
|
||||
await queryRunner.query(`DROP INDEX \`IDX_template_executions_userId\``);
|
||||
await queryRunner.query(`DROP INDEX \`IDX_template_executions_templateId\``);
|
||||
|
||||
// 删除用户积分表索引
|
||||
await queryRunner.query(`DROP INDEX "IDX_user_credits_createdAt"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_user_credits_source"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_user_credits_type"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_user_credits_platform"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_user_credits_userId"`);
|
||||
await queryRunner.query(`DROP INDEX \`IDX_user_credits_createdAt\``);
|
||||
await queryRunner.query(`DROP INDEX \`IDX_user_credits_source\``);
|
||||
await queryRunner.query(`DROP INDEX \`IDX_user_credits_type\``);
|
||||
await queryRunner.query(`DROP INDEX \`IDX_user_credits_platform\``);
|
||||
await queryRunner.query(`DROP INDEX \`IDX_user_credits_userId\``);
|
||||
|
||||
// 删除扩展数据表索引
|
||||
await queryRunner.query(`DROP INDEX "IDX_extension_data_createdAt"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_extension_data_status"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_extension_data_referenceId"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_extension_data_dataType"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_extension_data_platform"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_extension_data_userId"`);
|
||||
await queryRunner.query(`DROP INDEX \`IDX_extension_data_createdAt\``);
|
||||
await queryRunner.query(`DROP INDEX \`IDX_extension_data_status\``);
|
||||
await queryRunner.query(`DROP INDEX \`IDX_extension_data_referenceId\``);
|
||||
await queryRunner.query(`DROP INDEX \`IDX_extension_data_dataType\``);
|
||||
await queryRunner.query(`DROP INDEX \`IDX_extension_data_platform\``);
|
||||
await queryRunner.query(`DROP INDEX \`IDX_extension_data_userId\``);
|
||||
|
||||
// 删除平台用户表索引
|
||||
await queryRunner.query(`DROP INDEX "IDX_platform_users_userId"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_platform_users_platform"`);
|
||||
await queryRunner.query(`DROP INDEX \`IDX_platform_users_userId\``);
|
||||
await queryRunner.query(`DROP INDEX \`IDX_platform_users_platform\``);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user