新版流量池提交

This commit is contained in:
wong
2026-02-04 11:02:33 +08:00
parent a20794366a
commit 2855ab80fb
68 changed files with 8957 additions and 714 deletions

View 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;
}
}