新版流量池提交
This commit is contained in:
235
application/command/MigrateTrafficPoolV2Command.php
Normal file
235
application/command/MigrateTrafficPoolV2Command.php
Normal file
@@ -0,0 +1,235 @@
|
||||
<?php
|
||||
|
||||
namespace app\command;
|
||||
|
||||
use think\facade\Log;
|
||||
use think\console\Input;
|
||||
use think\console\Output;
|
||||
use think\console\Command;
|
||||
use think\console\input\Option;
|
||||
use think\facade\App;
|
||||
use WeChatDeviceApi\Adapters\ChuKeBao\Adapter as ChuKeBaoAdapter;
|
||||
|
||||
/**
|
||||
* V2 流量池数据迁移命令
|
||||
*
|
||||
* 使用方法:
|
||||
* php think migrate:trafficPoolV2 # 执行完整迁移
|
||||
* php think migrate:trafficPoolV2 --step=1 # 只执行第1步:好友同步到流量池总表
|
||||
* php think migrate:trafficPoolV2 --step=2 # 只执行第2步:好友同步到公司流量详情表
|
||||
* php think migrate:trafficPoolV2 --step=3 # 只执行第3步:好友同步到流量来源表
|
||||
* php think migrate:trafficPoolV2 --step=4 # 只执行第4步:群成员同步到流量池总表
|
||||
* php think migrate:trafficPoolV2 --step=5 # 只执行第5步:群成员同步到公司流量详情表
|
||||
* php think migrate:trafficPoolV2 --step=6 # 只执行第6步:群成员同步到流量来源表
|
||||
* php think migrate:trafficPoolV2 --step=7 # 只执行第7步:同步微信标签
|
||||
*
|
||||
* 执行前请确保已运行 SQL 迁移脚本创建了 V2 版本的表
|
||||
*/
|
||||
class MigrateTrafficPoolV2Command extends Command
|
||||
{
|
||||
protected $lockFile;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->lockFile = App::getRuntimePath() . 'migrate_traffic_pool_v2.lock';
|
||||
}
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('migrate:trafficPoolV2')
|
||||
->setDescription('迁移数据到 V2 流量池系统')
|
||||
->addOption('step', 's', Option::VALUE_OPTIONAL, '执行指定步骤(1-7),不指定则执行全部', null);
|
||||
}
|
||||
|
||||
protected function execute(Input $input, Output $output)
|
||||
{
|
||||
// 检查锁文件
|
||||
if (file_exists($this->lockFile)) {
|
||||
$lockTime = filectime($this->lockFile);
|
||||
if (time() - $lockTime < 7200) { // 2小时内
|
||||
$output->writeln('<error>迁移任务已在运行中,跳过本次执行</error>');
|
||||
return false;
|
||||
}
|
||||
unlink($this->lockFile);
|
||||
}
|
||||
|
||||
file_put_contents($this->lockFile, time());
|
||||
|
||||
try {
|
||||
$step = $input->getOption('step');
|
||||
$adapter = new ChuKeBaoAdapter();
|
||||
|
||||
$output->writeln('<info>====================================</info>');
|
||||
$output->writeln('<info> V2 流量池数据迁移开始</info>');
|
||||
$output->writeln('<info>====================================</info>');
|
||||
$output->writeln('');
|
||||
|
||||
$startTime = microtime(true);
|
||||
|
||||
if ($step === null) {
|
||||
// 执行完整迁移
|
||||
$results = $this->runFullMigration($adapter, $output);
|
||||
} else {
|
||||
// 执行指定步骤
|
||||
$results = $this->runStep((int)$step, $adapter, $output);
|
||||
}
|
||||
|
||||
$endTime = microtime(true);
|
||||
$duration = round($endTime - $startTime, 2);
|
||||
|
||||
$output->writeln('');
|
||||
$output->writeln('<info>====================================</info>');
|
||||
$output->writeln('<info> 迁移完成</info>');
|
||||
$output->writeln('<info>====================================</info>');
|
||||
$output->writeln("耗时: {$duration} 秒");
|
||||
$output->writeln('');
|
||||
$output->writeln('<comment>结果统计:</comment>');
|
||||
foreach ($results as $key => $value) {
|
||||
$output->writeln(" - {$key}: {$value} 条");
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
} catch (\Exception $e) {
|
||||
$output->writeln('<error>迁移异常: ' . $e->getMessage() . '</error>');
|
||||
Log::error('V2流量池迁移异常:' . $e->getMessage() . "\n" . $e->getTraceAsString());
|
||||
return false;
|
||||
} finally {
|
||||
if (file_exists($this->lockFile)) {
|
||||
unlink($this->lockFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行完整迁移
|
||||
*/
|
||||
protected function runFullMigration(ChuKeBaoAdapter $adapter, Output $output)
|
||||
{
|
||||
$results = [
|
||||
'friend_pool' => 0,
|
||||
'friend_pool_company' => 0,
|
||||
'friend_pool_source' => 0,
|
||||
'chatroom_pool' => 0,
|
||||
'chatroom_pool_company' => 0,
|
||||
'chatroom_pool_source' => 0,
|
||||
'pool_tags' => 0,
|
||||
];
|
||||
|
||||
// === 好友数据迁移 ===
|
||||
$output->writeln('<comment>【好友数据迁移】</comment>');
|
||||
|
||||
// Step 1: 好友同步到流量池总表
|
||||
$output->writeln('<comment>[1/7] 同步好友到流量池总表 ck_traffic_pool ...</comment>');
|
||||
$results['friend_pool'] = $adapter->syncToTrafficPoolV2();
|
||||
$output->writeln("<info> 完成,影响行数: {$results['friend_pool']}</info>");
|
||||
|
||||
// Step 2: 好友同步到公司流量详情表
|
||||
$output->writeln('<comment>[2/7] 同步好友到公司流量详情表 ck_traffic_pool_company ...</comment>');
|
||||
$results['friend_pool_company'] = $adapter->syncToTrafficPoolCompanyV2();
|
||||
$output->writeln("<info> 完成,影响行数: {$results['friend_pool_company']}</info>");
|
||||
|
||||
// Step 3: 好友同步到流量来源表
|
||||
$output->writeln('<comment>[3/7] 同步好友到流量来源表 ck_traffic_pool_source ...</comment>');
|
||||
$results['friend_pool_source'] = $adapter->syncToTrafficPoolSourceV2();
|
||||
$output->writeln("<info> 完成,影响行数: {$results['friend_pool_source']}</info>");
|
||||
|
||||
// === 群成员数据迁移 ===
|
||||
$output->writeln('');
|
||||
$output->writeln('<comment>【群成员数据迁移】</comment>');
|
||||
|
||||
// Step 4: 群成员同步到流量池总表
|
||||
$output->writeln('<comment>[4/7] 同步群成员到流量池总表 ck_traffic_pool ...</comment>');
|
||||
$results['chatroom_pool'] = $adapter->syncChatroomMembersToTrafficPoolV2();
|
||||
$output->writeln("<info> 完成,影响行数: {$results['chatroom_pool']}</info>");
|
||||
|
||||
// Step 5: 群成员同步到公司流量详情表
|
||||
$output->writeln('<comment>[5/7] 同步群成员到公司流量详情表 ck_traffic_pool_company ...</comment>');
|
||||
$results['chatroom_pool_company'] = $adapter->syncChatroomMembersToTrafficPoolCompanyV2();
|
||||
$output->writeln("<info> 完成,影响行数: {$results['chatroom_pool_company']}</info>");
|
||||
|
||||
// Step 6: 群成员同步到流量来源表
|
||||
$output->writeln('<comment>[6/7] 同步群成员到流量来源表 ck_traffic_pool_source ...</comment>');
|
||||
$results['chatroom_pool_source'] = $adapter->syncChatroomMembersToTrafficPoolSourceV2();
|
||||
$output->writeln("<info> 完成,影响行数: {$results['chatroom_pool_source']}</info>");
|
||||
|
||||
// === 标签数据迁移 ===
|
||||
$output->writeln('');
|
||||
$output->writeln('<comment>【标签数据迁移】</comment>');
|
||||
|
||||
// Step 7: 同步微信标签
|
||||
$output->writeln('<comment>[7/7] 同步微信标签 ck_traffic_pool_tag ...</comment>');
|
||||
$results['pool_tags'] = $adapter->syncWechatTagsToV2();
|
||||
$output->writeln("<info> 完成,影响行数: {$results['pool_tags']}</info>");
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行指定步骤
|
||||
*/
|
||||
protected function runStep(int $step, ChuKeBaoAdapter $adapter, Output $output)
|
||||
{
|
||||
$results = [];
|
||||
|
||||
switch ($step) {
|
||||
case 1:
|
||||
$output->writeln('<comment>[Step 1] 同步好友到流量池总表 ck_traffic_pool ...</comment>');
|
||||
$results['friend_pool'] = $adapter->syncToTrafficPoolV2();
|
||||
$output->writeln("<info> 完成,影响行数: {$results['friend_pool']}</info>");
|
||||
break;
|
||||
|
||||
case 2:
|
||||
$output->writeln('<comment>[Step 2] 同步好友到公司流量详情表 ck_traffic_pool_company ...</comment>');
|
||||
$results['friend_pool_company'] = $adapter->syncToTrafficPoolCompanyV2();
|
||||
$output->writeln("<info> 完成,影响行数: {$results['friend_pool_company']}</info>");
|
||||
break;
|
||||
|
||||
case 3:
|
||||
$output->writeln('<comment>[Step 3] 同步好友到流量来源表 ck_traffic_pool_source ...</comment>');
|
||||
$results['friend_pool_source'] = $adapter->syncToTrafficPoolSourceV2();
|
||||
$output->writeln("<info> 完成,影响行数: {$results['friend_pool_source']}</info>");
|
||||
break;
|
||||
|
||||
case 4:
|
||||
$output->writeln('<comment>[Step 4] 同步群成员到流量池总表 ck_traffic_pool ...</comment>');
|
||||
$results['chatroom_pool'] = $adapter->syncChatroomMembersToTrafficPoolV2();
|
||||
$output->writeln("<info> 完成,影响行数: {$results['chatroom_pool']}</info>");
|
||||
break;
|
||||
|
||||
case 5:
|
||||
$output->writeln('<comment>[Step 5] 同步群成员到公司流量详情表 ck_traffic_pool_company ...</comment>');
|
||||
$results['chatroom_pool_company'] = $adapter->syncChatroomMembersToTrafficPoolCompanyV2();
|
||||
$output->writeln("<info> 完成,影响行数: {$results['chatroom_pool_company']}</info>");
|
||||
break;
|
||||
|
||||
case 6:
|
||||
$output->writeln('<comment>[Step 6] 同步群成员到流量来源表 ck_traffic_pool_source ...</comment>');
|
||||
$results['chatroom_pool_source'] = $adapter->syncChatroomMembersToTrafficPoolSourceV2();
|
||||
$output->writeln("<info> 完成,影响行数: {$results['chatroom_pool_source']}</info>");
|
||||
break;
|
||||
|
||||
case 7:
|
||||
$output->writeln('<comment>[Step 7] 同步微信标签 ck_traffic_pool_tag ...</comment>');
|
||||
$results['pool_tags'] = $adapter->syncWechatTagsToV2();
|
||||
$output->writeln("<info> 完成,影响行数: {$results['pool_tags']}</info>");
|
||||
break;
|
||||
|
||||
default:
|
||||
$output->writeln('<error>无效的步骤编号,请输入 1-7</error>');
|
||||
$output->writeln('');
|
||||
$output->writeln('步骤说明:');
|
||||
$output->writeln(' 1 - 同步好友到流量池总表');
|
||||
$output->writeln(' 2 - 同步好友到公司流量详情表');
|
||||
$output->writeln(' 3 - 同步好友到流量来源表');
|
||||
$output->writeln(' 4 - 同步群成员到流量池总表');
|
||||
$output->writeln(' 5 - 同步群成员到公司流量详情表');
|
||||
$output->writeln(' 6 - 同步群成员到流量来源表');
|
||||
$output->writeln(' 7 - 同步微信标签');
|
||||
break;
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user