refactor: 移除Variation实体及相关引用
删除Variation实体及其在服务、DTO和配置中的引用 添加产品表重命名的迁移脚本
This commit is contained in:
parent
e1891df4f6
commit
2df777b73e
|
|
@ -1,7 +1,6 @@
|
||||||
import { MidwayConfig } from '@midwayjs/core';
|
import { MidwayConfig } from '@midwayjs/core';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
import { Product } from '../entity/product.entity';
|
import { Product } from '../entity/product.entity';
|
||||||
import { Variation } from '../entity/variation.entity';
|
|
||||||
import { User } from '../entity/user.entity';
|
import { User } from '../entity/user.entity';
|
||||||
import { PurchaseOrder } from '../entity/purchase_order.entity';
|
import { PurchaseOrder } from '../entity/purchase_order.entity';
|
||||||
import { PurchaseOrderItem } from '../entity/purchase_order_item.entity';
|
import { PurchaseOrderItem } from '../entity/purchase_order_item.entity';
|
||||||
|
|
@ -52,7 +51,6 @@ export default {
|
||||||
Product,
|
Product,
|
||||||
ProductStockComponent,
|
ProductStockComponent,
|
||||||
ProductSiteSku,
|
ProductSiteSku,
|
||||||
Variation,
|
|
||||||
User,
|
User,
|
||||||
PurchaseOrder,
|
PurchaseOrder,
|
||||||
PurchaseOrderItem,
|
PurchaseOrderItem,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,91 @@
|
||||||
|
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||||
|
|
||||||
|
export class UpdateProductTableName1765358400000 implements MigrationInterface {
|
||||||
|
name = 'UpdateProductTableName1765358400000'
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
// 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<void> {
|
||||||
|
// 回滚操作
|
||||||
|
// 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.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
// WooCommerce 平台原始数据类型定义
|
// WooCommerce 平台原始数据类型定义
|
||||||
// 仅包含当前映射逻辑所需字段以保持简洁与类型安全
|
// 仅包含当前映射逻辑所需字段以保持简洁与类型安全
|
||||||
|
|
||||||
import { Variation } from "../entity/variation.entity";
|
|
||||||
|
|
||||||
// 产品类型
|
// 产品类型
|
||||||
export interface WooProduct {
|
export interface WooProduct {
|
||||||
|
|
@ -126,7 +125,7 @@ export interface WooProduct {
|
||||||
// 元数据
|
// 元数据
|
||||||
meta_data?: Array<{ id?: number; key: string; value: any }>;
|
meta_data?: Array<{ id?: number; key: string; value: any }>;
|
||||||
}
|
}
|
||||||
export interface WooVariation extends Variation{
|
export interface WooVariation{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,10 +9,14 @@ import {
|
||||||
PrimaryGeneratedColumn,
|
PrimaryGeneratedColumn,
|
||||||
UpdateDateColumn,
|
UpdateDateColumn,
|
||||||
} from 'typeorm';
|
} from 'typeorm';
|
||||||
|
// import { Product } from './product.entity';
|
||||||
|
|
||||||
@Entity('order_sale')
|
@Entity('order_sale')
|
||||||
@Exclude()
|
@Exclude()
|
||||||
export class OrderSale {
|
export class OrderSale {
|
||||||
|
// @ManyToOne(() => Product, { onDelete: 'CASCADE' })
|
||||||
|
// @JoinColumn({ name: 'productId' })
|
||||||
|
// product: Product;
|
||||||
@ApiProperty()
|
@ApiProperty()
|
||||||
@PrimaryGeneratedColumn()
|
@PrimaryGeneratedColumn()
|
||||||
@Expose()
|
@Expose()
|
||||||
|
|
|
||||||
|
|
@ -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<string, any>; // 变体的属性
|
|
||||||
|
|
||||||
@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;
|
|
||||||
}
|
|
||||||
|
|
@ -20,7 +20,6 @@ import {
|
||||||
OrderStatus,
|
OrderStatus,
|
||||||
StockRecordOperationType,
|
StockRecordOperationType,
|
||||||
} from '../enums/base.enum';
|
} from '../enums/base.enum';
|
||||||
import { Variation } from '../entity/variation.entity';
|
|
||||||
import { CreateOrderNoteDTO, QueryOrderSalesDTO } from '../dto/order.dto';
|
import { CreateOrderNoteDTO, QueryOrderSalesDTO } from '../dto/order.dto';
|
||||||
import dayjs = require('dayjs');
|
import dayjs = require('dayjs');
|
||||||
import { OrderDetailRes } from '../dto/reponse.dto';
|
import { OrderDetailRes } from '../dto/reponse.dto';
|
||||||
|
|
@ -56,9 +55,6 @@ export class OrderService {
|
||||||
@InjectEntityModel(OrderSale)
|
@InjectEntityModel(OrderSale)
|
||||||
orderSaleModel: Repository<OrderSale>;
|
orderSaleModel: Repository<OrderSale>;
|
||||||
|
|
||||||
@InjectEntityModel(Variation)
|
|
||||||
variationModel: Repository<Variation>;
|
|
||||||
|
|
||||||
@InjectEntityModel(Product)
|
@InjectEntityModel(Product)
|
||||||
productModel: Repository<Product>;
|
productModel: Repository<Product>;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,6 @@ import {
|
||||||
SizePaginatedResponse,
|
SizePaginatedResponse,
|
||||||
} from '../dto/reponse.dto';
|
} from '../dto/reponse.dto';
|
||||||
import { InjectEntityModel } from '@midwayjs/typeorm';
|
import { InjectEntityModel } from '@midwayjs/typeorm';
|
||||||
import { Variation } from '../entity/variation.entity';
|
|
||||||
import { Dict } from '../entity/dict.entity';
|
import { Dict } from '../entity/dict.entity';
|
||||||
import { DictItem } from '../entity/dict_item.entity';
|
import { DictItem } from '../entity/dict_item.entity';
|
||||||
import { Context } from '@midwayjs/koa';
|
import { Context } from '@midwayjs/koa';
|
||||||
|
|
@ -52,9 +51,6 @@ export class ProductService {
|
||||||
@InjectEntityModel(DictItem)
|
@InjectEntityModel(DictItem)
|
||||||
dictItemModel: Repository<DictItem>;
|
dictItemModel: Repository<DictItem>;
|
||||||
|
|
||||||
@InjectEntityModel(Variation)
|
|
||||||
variationModel: Repository<Variation>;
|
|
||||||
|
|
||||||
@InjectEntityModel(Stock)
|
@InjectEntityModel(Stock)
|
||||||
stockModel: Repository<Stock>;
|
stockModel: Repository<Stock>;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@
|
||||||
import { Inject, Provide } from '@midwayjs/core';
|
import { Inject, Provide } from '@midwayjs/core';
|
||||||
import axios, { AxiosRequestConfig } from 'axios';
|
import axios, { AxiosRequestConfig } from 'axios';
|
||||||
import WooCommerceRestApi, { WooCommerceRestApiVersion } from '@woocommerce/woocommerce-rest-api';
|
import WooCommerceRestApi, { WooCommerceRestApiVersion } from '@woocommerce/woocommerce-rest-api';
|
||||||
import { Variation } from '../entity/variation.entity';
|
|
||||||
import { SiteService } from './site.service';
|
import { SiteService } from './site.service';
|
||||||
import { IPlatformService } from '../interface/platform.interface';
|
import { IPlatformService } from '../interface/platform.interface';
|
||||||
import { BatchOperationDTO, BatchOperationResultDTO } from '../dto/batch.dto';
|
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<any> {
|
async getVariations(site: any, productId: number, page: number = 1, pageSize: number = 100): Promise<any> {
|
||||||
const api = this.createApi(site, 'wc/v3');
|
const api = this.createApi(site, 'wc/v3');
|
||||||
return await this.sdkGetPage<Variation>(api, `products/${productId}/variations`, { page, per_page: pageSize });
|
return await this.sdkGetPage<WooVariation>(api, `products/${productId}/variations`, { page, per_page: pageSize });
|
||||||
}
|
}
|
||||||
|
|
||||||
async getVariation(
|
async getVariation(
|
||||||
site: any,
|
site: any,
|
||||||
productId: number,
|
productId: number,
|
||||||
variationId: number
|
variationId: number
|
||||||
): Promise<Variation> {
|
): Promise<WooVariation> {
|
||||||
const api = this.createApi(site, 'wc/v3');
|
const api = this.createApi(site, 'wc/v3');
|
||||||
const res = await api.get(`products/${productId}/variations/${variationId}`);
|
const res = await api.get(`products/${productId}/variations/${variationId}`);
|
||||||
return res.data as Variation;
|
return res.data as WooVariation;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getOrder(
|
async getOrder(
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue