浏览代码

修复:分润事实同步跳过无子注单的历史彩票订单

lhc_order id 1–2095(2026-04-30 至 2026-06-12)没有对应的 lhc_order_item,
每次同步都报 "Lottery order has no identifiable child bets",导致
share:sync-facts 每分钟以退出码 1 失败,且 lhc_order 游标永不推进、每次全表扫描。

新增 config/sharing.php 的 lottery_legacy_max_id(默认 2095,可用
SHARE_LOTTERY_LEGACY_MAX_ID 覆盖),同步时只读取大于该 id 的彩票订单。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
doge 19 小时之前
父节点
当前提交
dffd62c089
共有 3 个文件被更改,包括 23 次插入 和 0 次删除
  1. 3 0
      app/Services/Sharing/BetFactSynchronizer.php
  2. 6 0
      config/sharing.php
  3. 14 0
      tests/Integration/SharingBetFactsTest.php

+ 3 - 0
app/Services/Sharing/BetFactSynchronizer.php

@@ -44,6 +44,9 @@ class BetFactSynchronizer
             $highestIdAtStart = $cursorEnabled ? (int) DB::table($table)->max('id') : 0;
             $errorCount = count($result['errors']);
             $query = DB::table($table);
+            if ($table === 'lhc_order' && ($legacyMaxId = (int) config('sharing.lottery_legacy_max_id', 0)) > 0) {
+                $query->where('id', '>', $legacyMaxId);
+            }
             if ($cursorEnabled) {
                 $lastRun = DB::table('share_system_state')->where('key', 'facts_cursor:' . $table)->value('value');
                 if ($lastRun) {

+ 6 - 0
config/sharing.php

@@ -0,0 +1,6 @@
+<?php
+
+return [
+    // Lottery orders up to this id predate the sharing system and have no child bets; never import them.
+    'lottery_legacy_max_id' => (int) env('SHARE_LOTTERY_LEGACY_MAX_ID', 2095),
+];

+ 14 - 0
tests/Integration/SharingBetFactsTest.php

@@ -228,6 +228,20 @@ class SharingBetFactsTest extends TestCase
         $this->assertSame(['2026-10-01'], json_decode(DB::table('share_system_state')->where('key', 'facts_dirty_dates')->value('value'), true));
     }
 
+    public function test_legacy_lottery_orders_without_child_bets_are_skipped_and_cursor_advances(): void
+    {
+        $time = Carbon::parse('2026-05-01 10:00:00', 'Asia/Shanghai')->timestamp;
+        DB::table('lhc_order')->insert(['id' => 5, 'member_id' => '10001', 'ordernum' => 'legacy-lottery', 'type' => 5,
+            'lottery_status' => 2, 'amount' => 100, 'created_at' => $time, 'updated_at' => $time]);
+        $this->lottery();
+        $sync = new BetFactSynchronizer();
+        $this->assertSame('Lottery order has no identifiable child bets', $sync->sync()['errors'][0]['reason']);
+        app('config')->set('sharing.lottery_legacy_max_id', 5);
+        $result = $sync->sync(null, null, true);
+        $this->assertSame([], $result['errors']); $this->assertSame(1, $result['scanned']); $this->assertSame(2, $result['created']);
+        $this->assertNotNull(DB::table('share_system_state')->where('key', 'facts_cursor:lhc_order')->value('value'));
+    }
+
     public function test_second_child_failure_rolls_back_all_facts_dirty_dates_and_source_cursor(): void
     {
         $this->lottery();