用户流水拆分 分金币和钻石存储
This commit is contained in:
131
application/common/command/MigrateMoneyLog.php
Normal file
131
application/common/command/MigrateMoneyLog.php
Normal file
@@ -0,0 +1,131 @@
|
||||
<?php
|
||||
|
||||
namespace app\common\command;
|
||||
/**
|
||||
* 资金日志批量迁移脚本(命令行运行)
|
||||
* 执行命令:php think migrate:money_log
|
||||
*/
|
||||
|
||||
|
||||
use think\console\Command;
|
||||
use think\console\Input;
|
||||
use think\console\Output;
|
||||
use think\Db;
|
||||
|
||||
class MigrateMoneyLog extends Command
|
||||
{
|
||||
|
||||
// 配置命令
|
||||
protected function configure()
|
||||
{
|
||||
$this->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} 条数据 ==========");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user