setName('migrate:money_log') ->setDescription('批量迁移fa_vs_user_money_log数据到金币/钻石日志表'); } // 执行逻辑 protected function execute(Input $input, Output $output) { $output->writeln('========== 开始迁移资金日志数据 =========='); // 配置参数(可根据服务器性能调整) $batchSize = 1000; // 每批处理1000条,服务器性能好可调大(如2000) $lastLogId = 0; // 从最小的log_id开始(自增主键,避免重复处理) $total = 0; // 累计处理条数 // 循环分批处理,直到没有数据 while (true) { // 1. 分批查询未处理的数据(exp=0),按log_id递增取,避免重复 $list = Db::name('vs_user_money_log') ->where('exp', 0) ->where('log_id', '>', $lastLogId) ->field('log_id,user_id,room_id,change_type,money_type,change_value,from_id,remarks,createtime') ->order('log_id ASC') ->limit($batchSize) ->select(); // 没有数据则退出循环 if (empty($list)) { break; } // 2. 收集批量插入的数据 $coinData = []; // 金币日志待插入数据 $earData = []; // 钻石日志待插入数据 $logIds = []; // 本次处理的log_id集合(用于批量更新exp) foreach ($list as $v) { $logIds[] = $v['log_id']; $createtime = $v['createtime'] ?: time(); // 处理空创建时间 // 金币类型(money_type=1) if ($v['money_type'] == 1) { $coinData[] = [ 'user_id' => $v['user_id'] ?: 0, 'room_id' => $v['from_id'] ?: 0, // 按你原有逻辑,room_id对应from_id 'coin' => $v['change_value'] ?: 0, 'before' => $v['change_value'] ?: 0, // 按你原有逻辑赋值 'after' => $v['change_value'] ?: 0, // 按你原有逻辑赋值 'change_type' => $v['change_type'] ?: 0, 'remarks' => $v['remarks'] ?: '', 'createtime' => $createtime ]; } // 钻石类型(money_type=2) if ($v['money_type'] == 2) { $earData[] = [ 'user_id' => $v['user_id'] ?: 0, 'room_id' => $v['from_id'] ?: 0, // 按你原有逻辑,room_id对应from_id 'earnings' => $v['change_value'] ?: 0.0000, 'before' => $v['change_value'] ?: 0.0000, // 按你原有逻辑赋值 'after' => $v['change_value'] ?: 0.0000, // 按你原有逻辑赋值 'change_type' => $v['change_type'] ?: 0, 'remarks' => $v['remarks'] ?: '', 'createtime' => $createtime ]; } } // 3. 批量插入数据(开启事务,保证数据一致性) Db::startTrans(); try { // 批量插入金币日志(有数据才插入) if (!empty($coinData)) { Db::name('user_coin_log')->insertAll($coinData); } // 批量插入钻石日志(有数据才插入) if (!empty($earData)) { Db::name('user_earnings_log')->insertAll($earData); } // 4. 批量更新已处理的记录(exp=1) if (!empty($logIds)) { Db::name('vs_user_money_log') ->whereIn('log_id', $logIds) ->update(['exp' => 1]); } Db::commit(); // 提交事务 // 更新统计和最后处理的log_id $batchCount = count($list); $total += $batchCount; $lastLogId = end($list)['log_id']; // 输出进度 $output->writeln("成功处理第 {$total} 条数据 | 本次处理 {$batchCount} 条 | 最后处理log_id: {$lastLogId}"); // 清空数组,释放内存 unset($list, $coinData, $earData, $logIds); } catch (\Exception $e) { Db::rollback(); // 回滚事务 $output->error("处理失败:{$e->getMessage()} | 失败批次log_id范围:{$lastLogId} ~ {($lastLogId + $batchSize)}"); break; // 出错则停止,避免数据混乱 } } $output->writeln("========== 迁移完成!累计处理 {$total} 条数据 =========="); } }