Просмотр исходного кода

三方订单兼容旧 p+md5 玩家账号,补齐会员信息

2026-08-24 之前三方账号为 p + md5(GAME_SN_member_id) 前10位,之后改为 u + users.id,
同步只识别新格式,历史订单的 user_id、member_id、用户名、昵称为空。
同步时按旧算法反查会员,并新增迁移补齐已入库的空会员订单。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
doge 22 часов назад
Родитель
Сommit
0a77e96219

+ 56 - 2
app/Services/ThirdGameOrderService.php

@@ -284,8 +284,10 @@ class ThirdGameOrderService
                 $requested[(int) $userId][$playerId] = true;
             }
         }
+
+        $result = $this->usersByLegacyPlayerId($playerIds);
         if ($requested === []) {
-            return [];
+            return $result;
         }
 
         $rows = DB::table('users')
@@ -293,7 +295,6 @@ class ThirdGameOrderService
             ->whereIn('id', array_keys($requested))
             ->get();
 
-        $result = [];
         foreach ($rows as $row) {
             foreach (array_keys($requested[(int) $row->id] ?? []) as $playerId) {
                 $result[$playerId] = $row;
@@ -303,6 +304,59 @@ class ThirdGameOrderService
         return $result;
     }
 
+    /**
+     * 2026-08-24 之前的三方账号为 p + md5(sn_member_id) 前10位,历史订单仍使用该账号。
+     *
+     * @return array<string, object>
+     */
+    private function usersByLegacyPlayerId(array $playerIds): array
+    {
+        $legacy = [];
+        foreach ($playerIds as $playerId) {
+            $playerId = trim((string) $playerId);
+            if (preg_match('/^p[0-9a-f]{10}$/D', $playerId)) $legacy[$playerId] = true;
+        }
+        if ($legacy === []) {
+            return [];
+        }
+
+        $sn = (string) config('third_game.sn');
+        $expression = "CONCAT('p', SUBSTRING(MD5(CONCAT(?, '_', `member_id`)), 1, 10))";
+        $placeholders = implode(',', array_fill(0, count($legacy), '?'));
+        $rows = DB::table('users')
+            ->select(['id', 'member_id', 'username', 'first_name'])
+            ->selectRaw($expression . ' AS legacy_player_id', [$sn])
+            ->whereRaw($expression . " IN ({$placeholders})", array_merge([$sn], array_keys($legacy)))
+            ->get();
+
+        $result = [];
+        foreach ($rows as $row) {
+            $result[(string) $row->legacy_player_id] = $row;
+        }
+
+        return $result;
+    }
+
+    /** 补齐同步时未能识别旧账号而缺少会员信息的订单。 */
+    public function backfillLegacyPlayers(): int
+    {
+        $updated = 0;
+        $playerIds = ThirdGameOrderModel::query()->whereNull('user_id')->where('player_id', 'like', 'p%')
+            ->distinct()->pluck('player_id')->all();
+        foreach (array_chunk($playerIds, 200) as $chunk) {
+            foreach ($this->usersByLegacyPlayerId($chunk) as $playerId => $user) {
+                $updated += ThirdGameOrderModel::query()->whereNull('user_id')->where('player_id', $playerId)->update([
+                    'user_id' => $user->id,
+                    'member_id' => $user->member_id,
+                    'username' => (string) ($user->username ?? ''),
+                    'first_name' => (string) ($user->first_name ?? ''),
+                ]);
+            }
+        }
+
+        return $updated;
+    }
+
     /**
      * @return array<string, ThirdGameOrderModel>
      */

+ 18 - 0
database/migrations/2026_10_31_150000_backfill_legacy_third_game_order_players.php

@@ -0,0 +1,18 @@
+<?php
+
+use App\Services\ThirdGameOrderService;
+use Illuminate\Database\Migrations\Migration;
+
+/** 历史 p+md5 账号的三方订单在同步时未识别会员,补齐 user_id、member_id、用户名和昵称。 */
+return new class extends Migration
+{
+    public function up(): void
+    {
+        app(ThirdGameOrderService::class)->backfillLegacyPlayers();
+    }
+
+    public function down(): void
+    {
+        // 补齐的是原本就该有的会员信息,不回退。
+    }
+};