From a009ec9dfd1cec225929d5d9296875c2b03f6a32 Mon Sep 17 00:00:00 2001 From: Nick Zeng Date: Tue, 10 Feb 2026 12:59:21 +0800 Subject: [PATCH] add refund items table --- ...02_10_110000_create_refund_items_table.php | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 backend/migrations/2026_02_10_110000_create_refund_items_table.php diff --git a/backend/migrations/2026_02_10_110000_create_refund_items_table.php b/backend/migrations/2026_02_10_110000_create_refund_items_table.php new file mode 100644 index 0000000..1220687 --- /dev/null +++ b/backend/migrations/2026_02_10_110000_create_refund_items_table.php @@ -0,0 +1,83 @@ +bigIncrements('id')->comment('主键'); + $table->integer('company_id')->comment('公司 ID'); + $table->integer('platform_id')->comment('平台 ID'); + $table->integer('store_id')->comment('店铺 ID'); + $table->bigInteger('refund_id')->comment('关联本地 refunds 表 ID,业务层保证约束'); + $table->text('platform_parent_refund_id')->default('')->comment('平台父退款 ID, Tmall 售后单体系中的无此信息,使用默认值'); + $table->text('platform_refund_id')->comment('平台退款子项 ID,如 Tmall 售后单 ID'); + $table->integer('refund_status_id')->comment('退款状态 ID'); + $table->integer('refund_type_id')->default(1)->comment('退款类型:1 仅退款 2 退货退款 3 补偿退款'); + $table->text('reason')->nullable()->default(null)->comment('退款原因'); + $table->text('currency')->default('CNY')->comment('币种'); + $table->text('buyer_user_id')->nullable()->default(null)->comment('平台买家 ID'); + $table->text('platform_order_id')->comment('平台订单 ID'); + $table->text('platform_sub_order_id')->nullable()->default(null)->comment('平台子订单 ID'); + $table->text('platform_product_id')->nullable()->default(null)->comment('平台商品 ID'); + $table->integer('quantity')->default(0)->comment('退款商品数量'); + $table->double('refund_amount', 10, 2)->default(0)->comment('该子项退款金额'); + $table->timestampTz('order_created_date')->comment('关联订单的创建时间'); + $table->timestampTz('order_paid_date')->comment('关联订单的付款时间'); + $table->timestampTz('created_date')->comment('退款单在平台的创建时间'); + $table->timestampTz('updated_date')->nullable()->default(null)->comment('退款单在平台的更新时间'); + $table->timestampTz('completed_date')->nullable()->default(null)->comment('退款完成时间'); + $table->jsonb('raw')->comment('平台返回的原始子项数据'); + $table->jsonb('ext')->nullable()->default(null)->comment('扩展字段'); + $table->timestampsTz(); + + // 索引 + // store_id 已被 unique(store_id, platform_parent_refund_id, platform_refund_id) 覆盖 + // company_id 已被 (company_id, currency, created_date) 复合索引覆盖 + // refund_status_id、refund_type_id 已被聚合复合索引的最左前缀覆盖 + $table->index('platform_id'); + $table->index('refund_id'); + $table->index('platform_parent_refund_id'); + $table->index('platform_refund_id'); + $table->index('platform_order_id'); + $table->index('platform_product_id'); + $table->index('created_date'); + $table->index('updated_date'); + $table->index('completed_date'); + + // 联合唯一索引:店铺 + 平台父退款ID + 平台退款子项ID + $table->unique(['store_id', 'platform_parent_refund_id', 'platform_refund_id'], 'refund_items_store_parent_refund_unique'); + + // 复合索引:优化按公司+币种查询退款子项列表并按时间排序 + $table->index(['company_id', 'currency', 'created_date'], 'refund_items_company_currency_created_idx'); + + }); + + // 复合索引:优化按状态+类型+时间维度的金额聚合查询,INCLUDE(refund_amount) 实现 Index-Only Scan + Schema::getConnection()->statement('CREATE INDEX refund_items_status_type_currency_order_created_idx ON refund_items (refund_status_id, refund_type_id, currency, order_created_date) INCLUDE (refund_amount)'); + Schema::getConnection()->statement('CREATE INDEX refund_items_status_type_currency_order_paid_idx ON refund_items (refund_status_id, refund_type_id, currency, order_paid_date) INCLUDE (refund_amount)'); + Schema::getConnection()->statement('CREATE INDEX refund_items_status_type_currency_completed_idx ON refund_items (refund_status_id, refund_type_id, currency, completed_date) INCLUDE (refund_amount)'); + + // 为 jsonb 字段创建 GIN 索引(PostgreSQL) + Schema::getConnection()->statement('CREATE INDEX refund_items_raw_gin_idx ON refund_items USING gin (raw)'); + Schema::getConnection()->statement('CREATE INDEX refund_items_ext_gin_idx ON refund_items USING gin (ext)'); + + // 表注释 + Schema::getConnection()->statement("COMMENT ON TABLE refund_items IS '退款子项表,记录退款单中的商品明细,无数据库外键约束,由业务层保证与 refunds 表的关联完整性'"); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('refund_items'); + } +};