修复发货镜像字段校准与合并列表耗时 #283
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
$connection = (string) config('jushuitan.connection', 'jushuitan_local');
|
||||
// 旧迁移可能在目标表不存在时跳过,却已记为完成。用独立版本校准实际结构。
|
||||
if (! Schema::connection($connection)->hasTable('jst_oms_shipping')) {
|
||||
throw new RuntimeException('发货镜像表不存在,不能将合并字段迁移标为完成。');
|
||||
}
|
||||
$migration = require base_path('modules/EcommerceFinance/Database/Migrations/2026_10_05_000001_add_merged_cols_to_jst_oms_shipping.php');
|
||||
$migration->up();
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
// 字段属于原迁移;校准回滚保留原迁移及镜像数据。
|
||||
}
|
||||
};
|
||||
@ -61,7 +61,9 @@ class SyncJushuitanShipping extends Command
|
||||
|
||||
$expressRows = (int) ($result['processed'] ?? 0);
|
||||
$autoRows = (int) ($result['autoship'] ?? 0);
|
||||
$summary = sprintf('发货明细 %d 条,代发仓 %d 条,合计处理 %d 条明细', $expressRows, $autoRows, $expressRows + $autoRows);
|
||||
$outboundRows = (int) ($result['outbound'] ?? 0);
|
||||
$purchaseOutRows = (int) ($result['purchase_out'] ?? 0);
|
||||
$summary = sprintf('发货明细 %d 条,代发仓 %d 条,销售出库补漏 %d 条,采购出库补漏 %d 条,合计处理 %d 条明细', $expressRows, $autoRows, $outboundRows, $purchaseOutRows, $expressRows + $autoRows + $outboundRows + $purchaseOutRows);
|
||||
$packageSummary = isset($result['unique_packages'])
|
||||
? sprintf('唯一包裹源键 %d 个,包裹记录处理 %d 次;', $result['unique_packages'], $result['packages'] ?? 0)
|
||||
: '';
|
||||
|
||||
@ -49,12 +49,18 @@ class ShippingOrderRepository
|
||||
// 合并:按包裹(source_id)归并
|
||||
$base = $this->filteredQuery($filters);
|
||||
$total = (clone $base)->distinct()->count('source_id');
|
||||
$pageKeys = (clone $base)->select('source_id')->selectRaw('MAX(ship_time) as ship_time')
|
||||
->groupBy('source_id')->orderByDesc('ship_time')->orderByDesc('source_id')
|
||||
->forPage($page, $perPage)->pluck('source_id')->all();
|
||||
if ($pageKeys === []) {
|
||||
return ['data' => [], 'total' => $total];
|
||||
}
|
||||
$rows = (clone $base)
|
||||
->whereIn('source_id', $pageKeys)
|
||||
->groupBy('source_id')
|
||||
->selectRaw($this->mergedSelectRaw())
|
||||
->orderByDesc('ship_time')
|
||||
->orderByDesc('source_id')
|
||||
->forPage($page, $perPage)
|
||||
->get()->map(fn ($r) => (array) $r)->all();
|
||||
|
||||
return ['data' => $rows, 'total' => $total];
|
||||
@ -157,7 +163,12 @@ class ShippingOrderRepository
|
||||
if ($last !== null) {
|
||||
$query->where('source_id', '>', $last);
|
||||
}
|
||||
$rows = $query->groupBy('source_id')->selectRaw($this->mergedSelectRaw())
|
||||
$keys = (clone $query)->select('source_id')->distinct()
|
||||
->orderBy('source_id')->limit($batchSize)->pluck('source_id')->all();
|
||||
if ($keys === []) {
|
||||
return;
|
||||
}
|
||||
$rows = $query->whereIn('source_id', $keys)->groupBy('source_id')->selectRaw($this->mergedSelectRaw())
|
||||
->orderBy('source_id')->limit($batchSize)->get()->all();
|
||||
if ($rows === []) {
|
||||
return;
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Unit\EcommerceFinance;
|
||||
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Tests\TestCase;
|
||||
|
||||
class ShippingMergedColumnsMigrationTest extends TestCase
|
||||
{
|
||||
public function test_reconciliation_repairs_missing_columns_and_can_run_again(): void
|
||||
{
|
||||
$schema = DB::connection('business_mirror')->getSchemaBuilder();
|
||||
$columns = ['m_name', 'm_volume_cm3', 'm_length_cm', 'm_width_cm', 'm_height_cm'];
|
||||
$schema->table('jst_oms_shipping', fn ($table) => $table->dropColumn($columns));
|
||||
$migration = require base_path('database/migrations/2026_10_07_150000_reconcile_shipping_merged_columns.php');
|
||||
$migration->up();
|
||||
$migration->up();
|
||||
foreach ($columns as $column) {
|
||||
$this->assertTrue($schema->hasColumn('jst_oms_shipping', $column));
|
||||
}
|
||||
}
|
||||
|
||||
public function test_missing_target_is_reported_instead_of_marked_complete(): void
|
||||
{
|
||||
DB::connection('business_mirror')->getSchemaBuilder()->drop('jst_oms_shipping');
|
||||
$migration = require base_path('database/migrations/2026_10_07_150000_reconcile_shipping_merged_columns.php');
|
||||
$this->expectException(\RuntimeException::class);
|
||||
$this->expectExceptionMessage('发货镜像表不存在');
|
||||
$migration->up();
|
||||
}
|
||||
}
|
||||
@ -844,7 +844,7 @@ class ShippingReplicaSynchronizerTest extends TestCase
|
||||
|
||||
$this->artisan('jushuitan:sync-shipping', [
|
||||
'--from' => '2026-09-01', '--to' => '2026-09-05', '--skip-freight' => true,
|
||||
])->expectsOutputToContain('唯一包裹源键 2 个,包裹记录处理 2 次;发货明细 1 条,代发仓 1 条,合计处理 2 条明细')
|
||||
])->expectsOutputToContain('唯一包裹源键 2 个,包裹记录处理 2 次;发货明细 1 条,代发仓 1 条,销售出库补漏 0 条,采购出库补漏 0 条,合计处理 2 条明细')
|
||||
->assertExitCode(0);
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user