diff --git a/src/config/config.default.ts b/src/config/config.default.ts index de114e0..9d86ff2 100644 --- a/src/config/config.default.ts +++ b/src/config/config.default.ts @@ -1,7 +1,6 @@ import { MidwayConfig } from '@midwayjs/core'; import { join } from 'path'; import { Product } from '../entity/product.entity'; -import { Variation } from '../entity/variation.entity'; import { User } from '../entity/user.entity'; import { PurchaseOrder } from '../entity/purchase_order.entity'; import { PurchaseOrderItem } from '../entity/purchase_order_item.entity'; @@ -52,7 +51,6 @@ export default { Product, ProductStockComponent, ProductSiteSku, - Variation, User, PurchaseOrder, PurchaseOrderItem, diff --git a/src/db/migrations/1765358400000-update-product-table-name.ts b/src/db/migrations/1765358400000-update-product-table-name.ts new file mode 100644 index 0000000..51deefd --- /dev/null +++ b/src/db/migrations/1765358400000-update-product-table-name.ts @@ -0,0 +1,91 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class UpdateProductTableName1765358400000 implements MigrationInterface { + name = 'UpdateProductTableName1765358400000' + + public async up(queryRunner: QueryRunner): Promise { + // 1. 使用 try-catch 方式删除外键约束,避免因外键不存在导致迁移失败 + try { + await queryRunner.query("ALTER TABLE `product_attributes_dict_item` DROP FOREIGN KEY `FK_592cdbdaebfec346c202ffb82ca`"); + } catch (error) { + // 忽略外键不存在的错误 + console.log('Warning: Failed to drop foreign key on product_attributes_dict_item. It may not exist.'); + } + + try { + await queryRunner.query("ALTER TABLE `product_stock_component` DROP FOREIGN KEY `FK_6fe75663083f572a49e7f46909b`"); + } catch (error) { + console.log('Warning: Failed to drop foreign key on product_stock_component. It may not exist.'); + } + + try { + await queryRunner.query("ALTER TABLE `product_site_sku` DROP FOREIGN KEY `FK_3b9b7f3d8a6d9f3e2c0b1a4d5e6`"); + } catch (error) { + console.log('Warning: Failed to drop foreign key on product_site_sku. It may not exist.'); + } + + try { + await queryRunner.query("ALTER TABLE `order_sale` DROP FOREIGN KEY `FK_order_sale_product`"); + } catch (error) { + console.log('Warning: Failed to drop foreign key on order_sale. It may not exist.'); + } + + // 2. 将 product 表重命名为 product_v2 + await queryRunner.query("ALTER TABLE `product` RENAME TO `product_v2`"); + + // 3. 重新创建所有外键约束,引用新的 product_v2 表 + await queryRunner.query("ALTER TABLE `product_attributes_dict_item` ADD CONSTRAINT `FK_592cdbdaebfec346c202ffb82ca` FOREIGN KEY (`productId`) REFERENCES `product_v2`(`id`) ON DELETE CASCADE ON UPDATE CASCADE"); + await queryRunner.query("ALTER TABLE `product_stock_component` ADD CONSTRAINT `FK_6fe75663083f572a49e7f46909b` FOREIGN KEY (`productId`) REFERENCES `product_v2`(`id`) ON DELETE CASCADE"); + await queryRunner.query("ALTER TABLE `product_site_sku` ADD CONSTRAINT `FK_3b9b7f3d8a6d9f3e2c0b1a4d5e6` FOREIGN KEY (`productId`) REFERENCES `product_v2`(`id`) ON DELETE CASCADE"); + + // 4. 为 order_sale 表添加外键约束 + try { + await queryRunner.query("ALTER TABLE `order_sale` ADD CONSTRAINT `FK_order_sale_product` FOREIGN KEY (`productId`) REFERENCES `product_v2`(`id`) ON DELETE CASCADE"); + } catch (error) { + console.log('Warning: Failed to add foreign key on order_sale. It may already exist.'); + } + } + + public async down(queryRunner: QueryRunner): Promise { + // 回滚操作 + // 1. 删除外键约束 + try { + await queryRunner.query("ALTER TABLE `product_attributes_dict_item` DROP FOREIGN KEY `FK_592cdbdaebfec346c202ffb82ca`"); + } catch (error) { + console.log('Warning: Failed to drop foreign key on product_attributes_dict_item during rollback.'); + } + + try { + await queryRunner.query("ALTER TABLE `product_stock_component` DROP FOREIGN KEY `FK_6fe75663083f572a49e7f46909b`"); + } catch (error) { + console.log('Warning: Failed to drop foreign key on product_stock_component during rollback.'); + } + + try { + await queryRunner.query("ALTER TABLE `product_site_sku` DROP FOREIGN KEY `FK_3b9b7f3d8a6d9f3e2c0b1a4d5e6`"); + } catch (error) { + console.log('Warning: Failed to drop foreign key on product_site_sku during rollback.'); + } + + try { + await queryRunner.query("ALTER TABLE `order_sale` DROP FOREIGN KEY `FK_order_sale_product`"); + } catch (error) { + console.log('Warning: Failed to drop foreign key on order_sale during rollback.'); + } + + // 2. 将 product_v2 表重命名回 product + await queryRunner.query("ALTER TABLE `product_v2` RENAME TO `product`"); + + // 3. 重新创建外键约束,引用回原来的 product 表 + await queryRunner.query("ALTER TABLE `product_attributes_dict_item` ADD CONSTRAINT `FK_592cdbdaebfec346c202ffb82ca` FOREIGN KEY (`productId`) REFERENCES `product`(`id`) ON DELETE CASCADE ON UPDATE CASCADE"); + await queryRunner.query("ALTER TABLE `product_stock_component` ADD CONSTRAINT `FK_6fe75663083f572a49e7f46909b` FOREIGN KEY (`productId`) REFERENCES `product`(`id`) ON DELETE CASCADE"); + await queryRunner.query("ALTER TABLE `product_site_sku` ADD CONSTRAINT `FK_3b9b7f3d8a6d9f3e2c0b1a4d5e6` FOREIGN KEY (`productId`) REFERENCES `product`(`id`) ON DELETE CASCADE"); + + // 4. 为 order_sale 表重新创建外键约束 + try { + await queryRunner.query("ALTER TABLE `order_sale` ADD CONSTRAINT `FK_order_sale_product` FOREIGN KEY (`productId`) REFERENCES `product`(`id`) ON DELETE CASCADE"); + } catch (error) { + console.log('Warning: Failed to add foreign key on order_sale during rollback. It may already exist.'); + } + } +} \ No newline at end of file diff --git a/src/dto/woocommerce.dto.ts b/src/dto/woocommerce.dto.ts index 12e4ec2..9686ee5 100644 --- a/src/dto/woocommerce.dto.ts +++ b/src/dto/woocommerce.dto.ts @@ -1,7 +1,6 @@ // WooCommerce 平台原始数据类型定义 // 仅包含当前映射逻辑所需字段以保持简洁与类型安全 -import { Variation } from "../entity/variation.entity"; // 产品类型 export interface WooProduct { @@ -126,7 +125,7 @@ export interface WooProduct { // 元数据 meta_data?: Array<{ id?: number; key: string; value: any }>; } -export interface WooVariation extends Variation{ +export interface WooVariation{ } diff --git a/src/entity/order_sale.entity.ts b/src/entity/order_sale.entity.ts index eec088f..552a96c 100644 --- a/src/entity/order_sale.entity.ts +++ b/src/entity/order_sale.entity.ts @@ -9,10 +9,14 @@ import { PrimaryGeneratedColumn, UpdateDateColumn, } from 'typeorm'; +// import { Product } from './product.entity'; @Entity('order_sale') @Exclude() export class OrderSale { + // @ManyToOne(() => Product, { onDelete: 'CASCADE' }) + // @JoinColumn({ name: 'productId' }) + // product: Product; @ApiProperty() @PrimaryGeneratedColumn() @Expose() diff --git a/src/entity/variation.entity.ts b/src/entity/variation.entity.ts deleted file mode 100644 index b3232f5..0000000 --- a/src/entity/variation.entity.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { - Entity, - Column, - PrimaryGeneratedColumn, - Unique, - CreateDateColumn, - UpdateDateColumn, -} from 'typeorm'; -import { ApiProperty } from '@midwayjs/swagger'; - -@Entity('variation') -@Unique(['siteId', 'externalProductId', 'externalVariationId']) // 确保变体的唯一性 -export class Variation { - @ApiProperty({ - example: '1', - description: 'ID', - type: 'number', - required: true, - }) - @PrimaryGeneratedColumn() - id: number; - - @ApiProperty({ - description: '站点 id', - example: 1, - required: false - }) - @Column({ nullable: true }) - siteId: number; - - @ApiProperty({ - example: '1', - description: 'wp产品ID', - type: 'string', - required: true, - }) - @Column() - externalProductId: string; // WooCommerce 产品 ID - - @ApiProperty({ - example: '1', - description: 'wp变体ID', - type: 'string', - required: true, - }) - @Column() - externalVariationId: string; // WooCommerce 变体 ID - - @ApiProperty({ - example: '1', - description: '对应WP产品表的ID', - type: 'number', - required: true, - }) - @Column() - productId: number; // 对应WP产品表的 ID - - @ApiProperty({ description: 'sku', type: 'string' }) - @Column({ nullable: true }) - sku?: string; // sku 编码 - - @ApiProperty({ - description: '变体名称', - type: 'string', - required: true, - }) - @Column() - name: string; - - @ApiProperty({ description: '常规价格', type: Number }) - @Column('decimal', { precision: 10, scale: 2, nullable: true }) - regular_price: number; // 常规价格 - - @ApiProperty({ description: '销售价格', type: Number }) - @Column('decimal', { precision: 10, scale: 2, nullable: true }) - sale_price: number; // 销售价格 - - @ApiProperty({ description: '是否促销中', type: Boolean }) - @Column({ nullable: true, type: Boolean }) - on_sale: boolean; // 是否促销中 - - @ApiProperty({ description: '是否删除', type: Boolean }) - @Column({ nullable: true, type: Boolean , default: false }) - on_delete: boolean; // 是否删除 - - @Column({ type: 'json', nullable: true }) - attributes: Record; // 变体的属性 - - @ApiProperty({ - example: '2022-12-12 11:11:11', - description: '创建时间', - required: true, - }) - @CreateDateColumn() - createdAt: Date; - - @ApiProperty({ - example: '2022-12-12 11:11:11', - description: '更新时间', - required: true, - }) - @UpdateDateColumn() - updatedAt: Date; -} diff --git a/src/service/order.service.ts b/src/service/order.service.ts index fe7564e..1cde6b4 100644 --- a/src/service/order.service.ts +++ b/src/service/order.service.ts @@ -20,7 +20,6 @@ import { OrderStatus, StockRecordOperationType, } from '../enums/base.enum'; -import { Variation } from '../entity/variation.entity'; import { CreateOrderNoteDTO, QueryOrderSalesDTO } from '../dto/order.dto'; import dayjs = require('dayjs'); import { OrderDetailRes } from '../dto/reponse.dto'; @@ -56,9 +55,6 @@ export class OrderService { @InjectEntityModel(OrderSale) orderSaleModel: Repository; - @InjectEntityModel(Variation) - variationModel: Repository; - @InjectEntityModel(Product) productModel: Repository; diff --git a/src/service/product.service.ts b/src/service/product.service.ts index 40e5b5f..1ea6e34 100644 --- a/src/service/product.service.ts +++ b/src/service/product.service.ts @@ -19,7 +19,6 @@ import { SizePaginatedResponse, } from '../dto/reponse.dto'; import { InjectEntityModel } from '@midwayjs/typeorm'; -import { Variation } from '../entity/variation.entity'; import { Dict } from '../entity/dict.entity'; import { DictItem } from '../entity/dict_item.entity'; import { Context } from '@midwayjs/koa'; @@ -52,9 +51,6 @@ export class ProductService { @InjectEntityModel(DictItem) dictItemModel: Repository; - @InjectEntityModel(Variation) - variationModel: Repository; - @InjectEntityModel(Stock) stockModel: Repository; diff --git a/src/service/wp.service.ts b/src/service/wp.service.ts index c99e66c..9eff41c 100644 --- a/src/service/wp.service.ts +++ b/src/service/wp.service.ts @@ -5,7 +5,6 @@ import { Inject, Provide } from '@midwayjs/core'; import axios, { AxiosRequestConfig } from 'axios'; import WooCommerceRestApi, { WooCommerceRestApiVersion } from '@woocommerce/woocommerce-rest-api'; -import { Variation } from '../entity/variation.entity'; import { SiteService } from './site.service'; import { IPlatformService } from '../interface/platform.interface'; import { BatchOperationDTO, BatchOperationResultDTO } from '../dto/batch.dto'; @@ -264,17 +263,17 @@ export class WPService implements IPlatformService { async getVariations(site: any, productId: number, page: number = 1, pageSize: number = 100): Promise { const api = this.createApi(site, 'wc/v3'); - return await this.sdkGetPage(api, `products/${productId}/variations`, { page, per_page: pageSize }); + return await this.sdkGetPage(api, `products/${productId}/variations`, { page, per_page: pageSize }); } async getVariation( site: any, productId: number, variationId: number - ): Promise { + ): Promise { const api = this.createApi(site, 'wc/v3'); const res = await api.get(`products/${productId}/variations/${variationId}`); - return res.data as Variation; + return res.data as WooVariation; } async getOrder(