Procházet zdrojové kódy

修复变体 SKU 改名时跨批次占用旧 SKU 导致的唯一键冲突。

Co-authored-by: Cursor <cursoragent@cursor.com>
chengwl před 3 dny
rodič
revize
b17c9bdb49

+ 4 - 3
app/Console/Commands/RepairMigratedVariantSkus.php

@@ -278,18 +278,19 @@ class RepairMigratedVariantSkus extends Command
         $now = now()->toDateTimeString();
         $now = now()->toDateTimeString();
 
 
         DB::transaction(function () use ($planned, $previous, $now) {
         DB::transaction(function () use ($planned, $previous, $now) {
-            foreach (array_chunk($planned, 200, true) as $chunk) {
-                $ids = array_keys($chunk);
-
+            foreach (array_chunk(array_keys($planned), 200) as $ids) {
                 DB::table('product_variants')
                 DB::table('product_variants')
                     ->whereIn('id', $ids)
                     ->whereIn('id', $ids)
                     ->update([
                     ->update([
                         'sku'        => DB::raw("CONCAT('__sku_repair_', id)"),
                         'sku'        => DB::raw("CONCAT('__sku_repair_', id)"),
                         'updated_at' => $now,
                         'updated_at' => $now,
                     ]);
                     ]);
+            }
 
 
+            foreach (array_chunk($planned, 200, true) as $chunk) {
                 $case = 'CASE id';
                 $case = 'CASE id';
                 $bindings = [];
                 $bindings = [];
+                $ids = array_keys($chunk);
 
 
                 foreach ($chunk as $variantId => $newSku) {
                 foreach ($chunk as $variantId => $newSku) {
                     $case .= ' WHEN ? THEN ?';
                     $case .= ' WHEN ? THEN ?';

+ 75 - 0
packages/Webkul/BagistoApi/tests/Unit/Migration/RepairMigratedVariantSkusCommandTest.php

@@ -163,6 +163,81 @@ class RepairMigratedVariantSkusCommandTest extends BagistoApiTestCase
         $this->assertArrayNotHasKey('variant_sku', $migratedAdditional);
         $this->assertArrayNotHasKey('variant_sku', $migratedAdditional);
     }
     }
 
 
+    public function test_it_can_reuse_a_sku_held_by_a_variant_renamed_in_a_later_batch(): void
+    {
+        $now = now();
+        $product = new Product;
+        $product->sku = 'SWAP';
+        $product->type = 'flexible_variant';
+        $product->migrated_from_asteria_id = 991900201;
+        $product->save();
+
+        $option = ProductOption::query()->create([
+            'label' => 'Length',
+            'type'  => 'select',
+            'code'  => 'swap_length',
+        ]);
+
+        DB::table('product_product_options')->insert([
+            'product_id'        => $product->id,
+            'product_option_id' => $option->id,
+            'position'          => 0,
+            'is_required'       => 1,
+            'created_at'        => $now,
+            'updated_at'        => $now,
+        ]);
+
+        $count = 201;
+        $valueIds = [];
+
+        for ($i = 0; $i < $count; $i++) {
+            $valueIds[] = DB::table('product_option_values')->insertGetId([
+                'product_option_id' => $option->id,
+                'label'             => 'L'.$i,
+                'code'              => 'N'.$i,
+                'position'          => $i,
+                'created_at'        => $now,
+                'updated_at'        => $now,
+            ]);
+        }
+
+        $variantIds = [];
+
+        for ($i = 0; $i < $count; $i++) {
+            $current = $i === $count - 1 ? 'SWAP-N0' : 'OLD-'.$i;
+            $variantIds[] = DB::table('product_variants')->insertGetId([
+                'product_id' => $product->id,
+                'sku'        => $current,
+                'price'      => 10,
+                'quantity'   => 1,
+                'status'     => 1,
+                'sort_order' => $i,
+                'created_at' => $now,
+                'updated_at' => $now,
+            ]);
+        }
+
+        $pivots = [];
+
+        foreach ($variantIds as $i => $variantId) {
+            $pivots[] = [
+                'product_variant_id'      => $variantId,
+                'product_option_value_id' => $valueIds[$i],
+                'created_at'              => $now,
+                'updated_at'              => $now,
+            ];
+        }
+
+        DB::table('product_variant_option_values')->insert($pivots);
+
+        $this->artisan('products:repair-variant-skus', [
+            '--sku' => 'SWAP',
+        ])->assertSuccessful();
+
+        $this->assertSame('SWAP-N0', DB::table('product_variants')->where('id', $variantIds[0])->value('sku'));
+        $this->assertSame('SWAP-N200', DB::table('product_variants')->where('id', $variantIds[$count - 1])->value('sku'));
+    }
+
     /**
     /**
      * @return array{0: Product, 1: ProductVariant}
      * @return array{0: Product, 1: ProductVariant}
      */
      */