更新
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\command;
|
||||
|
||||
use app\common\service\wechat\QywxMsgArchiveService;
|
||||
use think\console\Command;
|
||||
use think\console\Input;
|
||||
use think\console\input\Option;
|
||||
use think\console\Output;
|
||||
use think\facade\Log;
|
||||
|
||||
/**
|
||||
* 企业微信会话内容存档同步
|
||||
*
|
||||
* 使用方法:
|
||||
* php think qywx:sync-msg-archive # 只拉消息
|
||||
* php think qywx:sync-msg-archive --download # 拉完后同时下载 pending 媒体
|
||||
* php think qywx:sync-msg-archive --only-media # 仅下载已登记的 pending 媒体
|
||||
*
|
||||
* crontab 建议:每 30 秒拉一次(用 sleep 模拟半分钟级)
|
||||
* * * * * * cd /path/to/project && php think qywx:sync-msg-archive --download >> /dev/null 2>&1
|
||||
* * * * * * cd /path/to/project && sleep 30 && php think qywx:sync-msg-archive --download >> /dev/null 2>&1
|
||||
*
|
||||
* 并发控制:通过文件锁,同一时刻只会跑一个,多开直接退出。
|
||||
*/
|
||||
class QywxSyncMsgArchive extends Command
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('qywx:sync-msg-archive')
|
||||
->addOption('download', 'd', Option::VALUE_NONE, '拉完消息后顺便下载 pending 媒体')
|
||||
->addOption('only-media', null, Option::VALUE_NONE, '仅下载已登记的 pending 媒体')
|
||||
->addOption('max-batches', 'b', Option::VALUE_REQUIRED, '单次运行最多拉多少批 (默认 20)', 20)
|
||||
->addOption('max-media', 'm', Option::VALUE_REQUIRED, '单次最多下载多少条媒体 (默认 200)', 200)
|
||||
->setDescription('拉取企业微信会话内容存档');
|
||||
}
|
||||
|
||||
protected function execute(Input $input, Output $output)
|
||||
{
|
||||
$lockFile = runtime_path() . 'lock' . DIRECTORY_SEPARATOR . 'qywx_msg_archive.lock';
|
||||
$lockDir = dirname($lockFile);
|
||||
if (!is_dir($lockDir)) {
|
||||
@mkdir($lockDir, 0755, true);
|
||||
}
|
||||
$fp = @fopen($lockFile, 'c');
|
||||
if ($fp === false) {
|
||||
$output->writeln('<error>无法创建锁文件: ' . $lockFile . '</error>');
|
||||
|
||||
return 1;
|
||||
}
|
||||
if (!flock($fp, LOCK_EX | LOCK_NB)) {
|
||||
fclose($fp);
|
||||
$output->writeln('另一个会话存档同步进程正在运行,跳过本次。');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
try {
|
||||
$onlyMedia = (bool) $input->getOption('only-media');
|
||||
$download = (bool) $input->getOption('download');
|
||||
$maxBatches = max(1, (int) $input->getOption('max-batches'));
|
||||
$maxMedia = max(1, (int) $input->getOption('max-media'));
|
||||
|
||||
if (!$onlyMedia) {
|
||||
$pull = QywxMsgArchiveService::pullLoop($maxBatches);
|
||||
if (!$pull['enabled']) {
|
||||
$output->writeln('<comment>会话存档未启用或 SDK 不可用:' . implode('; ', $pull['errors']) . '</comment>');
|
||||
|
||||
return 0;
|
||||
}
|
||||
$output->writeln(sprintf(
|
||||
'消息拉取:batches=%d pulled=%d inserted=%d updated=%d media_pending=%d last_seq=%d',
|
||||
$pull['batches'],
|
||||
$pull['pulled'],
|
||||
$pull['inserted'],
|
||||
$pull['updated'],
|
||||
$pull['media_pending'],
|
||||
$pull['last_seq']
|
||||
));
|
||||
if (!empty($pull['errors'])) {
|
||||
foreach ($pull['errors'] as $err) {
|
||||
Log::warning('qywx:sync-msg-archive pull error: ' . $err);
|
||||
$output->writeln('<comment>error: ' . $err . '</comment>');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($onlyMedia || $download) {
|
||||
$media = QywxMsgArchiveService::downloadPendingMedia($maxMedia);
|
||||
if (!$media['enabled']) {
|
||||
$output->writeln('<comment>媒体下载-SDK 未启用</comment>');
|
||||
} else {
|
||||
$output->writeln(sprintf(
|
||||
'媒体下载:ok=%d failed=%d skipped=%d',
|
||||
$media['ok'],
|
||||
$media['failed'],
|
||||
$media['skipped']
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
} catch (\Throwable $e) {
|
||||
$output->writeln('<error>同步异常: ' . $e->getMessage() . '</error>');
|
||||
Log::error('qywx:sync-msg-archive 异常: ' . $e->getMessage());
|
||||
|
||||
return 1;
|
||||
} finally {
|
||||
flock($fp, LOCK_UN);
|
||||
fclose($fp);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user