diff --git a/Server/README_scheduler.md b/Server/README_scheduler.md
new file mode 100644
index 00000000..4c485684
--- /dev/null
+++ b/Server/README_scheduler.md
@@ -0,0 +1,254 @@
+# 统一任务调度器使用说明
+
+## 概述
+
+统一任务调度器(TaskSchedulerCommand)是一个集中管理所有定时任务的调度系统,支持:
+- ✅ 单条 crontab 配置管理所有任务
+- ✅ 多进程并发执行任务
+- ✅ 自动根据 cron 表达式判断任务执行时间
+- ✅ 任务锁机制,防止重复执行
+- ✅ 完善的日志记录
+
+## 安装配置
+
+### 1. 配置文件
+
+任务配置位于 `config/task_scheduler.php`,格式如下:
+
+```php
+'任务标识' => [
+ 'command' => '命令名称', // 必填:执行的命令
+ 'schedule' => 'cron表达式', // 必填:cron表达式
+ 'options' => ['--option=value'], // 可选:命令参数
+ 'enabled' => true, // 可选:是否启用
+ 'max_concurrent' => 1, // 可选:最大并发数
+ 'timeout' => 3600, // 可选:超时时间(秒)
+ 'log_file' => 'custom.log', // 可选:自定义日志文件
+]
+```
+
+### 2. Cron 表达式格式
+
+标准 cron 格式:`分钟 小时 日 月 星期`
+
+示例:
+- `*/1 * * * *` - 每分钟执行
+- `*/5 * * * *` - 每5分钟执行
+- `*/30 * * * *` - 每30分钟执行
+- `0 2 * * *` - 每天凌晨2点执行
+- `0 3 */3 * *` - 每3天的3点执行
+
+### 3. Crontab 配置
+
+**只需要在 crontab 中添加一条任务:**
+
+```bash
+# 每分钟执行一次调度器(调度器内部会根据 cron 表达式判断哪些任务需要执行)
+* * * * * cd /www/wwwroot/mckb_quwanzhi_com/Server && php think scheduler:run >> /www/wwwroot/mckb_quwanzhi_com/Server/runtime/log/scheduler.log 2>&1
+```
+
+### 4. 系统要求
+
+- PHP >= 5.6.0
+- 推荐启用 `pcntl` 扩展以支持多进程并发(非必需,未启用时使用单进程顺序执行)
+
+检查 pcntl 扩展:
+```bash
+php -m | grep pcntl
+```
+
+## 使用方法
+
+### 手动执行调度器
+
+```bash
+# 执行调度器(会自动判断当前时间需要执行的任务)
+php think scheduler:run
+```
+
+### 查看任务配置
+
+```bash
+# 查看所有已注册的命令
+php think list
+```
+
+### 启用/禁用任务
+
+编辑 `config/task_scheduler.php`,设置 `'enabled' => false` 即可禁用任务。
+
+## 功能特性
+
+### 1. 多进程并发执行
+
+- 默认最大并发数:10 个进程
+- 自动管理进程池
+- 自动清理僵尸进程
+
+### 2. 任务锁机制
+
+- 每个任务在执行时会设置锁(5分钟内不重复执行)
+- 防止任务重复执行
+- 锁存储在缓存中,自动过期
+
+### 3. 日志记录
+
+- 调度器日志:`runtime/log/scheduler.log`
+- 每个任务的日志:`runtime/log/{log_file}`
+- 任务执行开始和结束都有标记
+
+### 4. 超时控制
+
+- 默认超时时间:3600 秒(1小时)
+- 可在配置中为每个任务单独设置超时时间
+- 超时后自动终止任务
+
+## 配置示例
+
+### 高频任务(每分钟)
+
+```php
+'wechat_friends_active' => [
+ 'command' => 'wechatFriends:list',
+ 'schedule' => '*/1 * * * *',
+ 'options' => ['--isDel=0'],
+ 'enabled' => true,
+],
+```
+
+### 中频任务(每5分钟)
+
+```php
+'device_active' => [
+ 'command' => 'device:list',
+ 'schedule' => '*/5 * * * *',
+ 'options' => ['--isDel=0'],
+ 'enabled' => true,
+],
+```
+
+### 每日任务
+
+```php
+'wechat_calculate_score' => [
+ 'command' => 'wechat:calculate-score',
+ 'schedule' => '0 2 * * *', // 每天凌晨2点
+ 'options' => [],
+ 'enabled' => true,
+],
+```
+
+### 定期任务(每3天)
+
+```php
+'sync_all_friends' => [
+ 'command' => 'sync:allFriends',
+ 'schedule' => '0 3 */3 * *', // 每3天的3点
+ 'options' => [],
+ 'enabled' => true,
+],
+```
+
+## 从旧配置迁移
+
+### 旧配置(多条 crontab)
+
+```bash
+*/5 * * * * cd /path && php think device:list --isDel=0 >> log1.log 2>&1
+*/1 * * * * cd /path && php think wechatFriends:list >> log2.log 2>&1
+```
+
+### 新配置(单条 crontab + 配置文件)
+
+**Crontab:**
+```bash
+* * * * * cd /path && php think scheduler:run >> scheduler.log 2>&1
+```
+
+**config/task_scheduler.php:**
+```php
+'device_active' => [
+ 'command' => 'device:list',
+ 'schedule' => '*/5 * * * *',
+ 'options' => ['--isDel=0'],
+ 'log_file' => 'log1.log',
+],
+'wechat_friends' => [
+ 'command' => 'wechatFriends:list',
+ 'schedule' => '*/1 * * * *',
+ 'log_file' => 'log2.log',
+],
+```
+
+## 监控和调试
+
+### 查看调度器日志
+
+```bash
+tail -f runtime/log/scheduler.log
+```
+
+### 查看任务执行日志
+
+```bash
+tail -f runtime/log/crontab_device_active.log
+```
+
+### 检查任务是否在执行
+
+```bash
+# 查看进程
+ps aux | grep "php think"
+```
+
+### 手动测试任务
+
+```bash
+# 直接执行某个任务
+php think device:list --isDel=0
+```
+
+## 注意事项
+
+1. **时间同步**:确保服务器时间准确,调度器依赖系统时间判断任务执行时间
+2. **资源限制**:根据服务器性能调整 `maxConcurrent` 参数
+3. **日志清理**:定期清理日志文件,避免占用过多磁盘空间
+4. **任务冲突**:如果任务执行时间较长,建议调整执行频率或增加并发数
+5. **缓存依赖**:任务锁使用缓存,确保缓存服务正常运行
+
+## 故障排查
+
+### 任务未执行
+
+1. 检查任务是否启用:`'enabled' => true`
+2. 检查 cron 表达式是否正确
+3. 检查调度器是否正常运行:查看 `scheduler.log`
+4. 检查任务锁:任务可能在5分钟内重复执行被跳过
+
+### 任务执行失败
+
+1. 查看任务日志:`runtime/log/{log_file}`
+2. 检查命令是否正确:手动执行命令测试
+3. 检查权限:确保有执行权限和日志写入权限
+
+### 多进程不工作
+
+1. 检查 pcntl 扩展:`php -m | grep pcntl`
+2. 检查系统限制:`ulimit -u` 查看最大进程数
+3. 查看调度器日志中的错误信息
+
+## 性能优化建议
+
+1. **合理设置并发数**:根据服务器 CPU 核心数和内存大小调整
+2. **错开高频任务**:避免所有任务在同一分钟执行
+3. **优化任务执行时间**:减少任务执行时长
+4. **使用队列**:对于耗时任务,建议使用队列异步处理
+
+## 更新日志
+
+### v1.0.0 (2024-01-XX)
+- 初始版本
+- 支持多进程并发执行
+- 支持 cron 表达式调度
+- 支持任务锁机制
+
diff --git a/Server/application/command.php b/Server/application/command.php
index b5c4d0e5..ce06453b 100644
--- a/Server/application/command.php
+++ b/Server/application/command.php
@@ -42,4 +42,7 @@ return [
'wechat:calculate-score' => 'app\command\CalculateWechatAccountScoreCommand', // 统一计算微信账号健康分
'wechat:update-score' => 'app\command\UpdateWechatAccountScoreCommand', // 更新微信账号评分记录
+
+ // 统一任务调度器
+ 'scheduler:run' => 'app\command\TaskSchedulerCommand', // 统一任务调度器,支持多进程并发执行
];
diff --git a/Server/application/command/TaskSchedulerCommand.php b/Server/application/command/TaskSchedulerCommand.php
new file mode 100644
index 00000000..06a1dbaf
--- /dev/null
+++ b/Server/application/command/TaskSchedulerCommand.php
@@ -0,0 +1,457 @@
+> /path/to/log/scheduler.log 2>&1
+ */
+class TaskSchedulerCommand extends Command
+{
+ /**
+ * 任务配置
+ */
+ protected $tasks = [];
+
+ /**
+ * 最大并发进程数
+ */
+ protected $maxConcurrent = 10;
+
+ /**
+ * 当前运行的进程数
+ */
+ protected $runningProcesses = [];
+
+ /**
+ * 日志目录
+ */
+ protected $logDir = '';
+
+ protected function configure()
+ {
+ $this->setName('scheduler:run')
+ ->setDescription('统一任务调度器,支持多进程并发执行所有定时任务');
+ }
+
+ protected function execute(Input $input, Output $output)
+ {
+ $output->writeln('==========================================');
+ $output->writeln('任务调度器启动');
+ $output->writeln('时间: ' . date('Y-m-d H:i:s'));
+ $output->writeln('==========================================');
+
+ // 检查是否支持 pcntl 扩展
+ if (!function_exists('pcntl_fork')) {
+ $output->writeln('错误:系统不支持 pcntl 扩展,无法使用多进程功能');
+ $output->writeln('提示:将使用单进程顺序执行任务');
+ $this->maxConcurrent = 1;
+ }
+
+ // 加载任务配置
+ $this->tasks = Config::get('task_scheduler', []);
+ if (empty($this->tasks)) {
+ $output->writeln('错误:未找到任务配置');
+ return false;
+ }
+
+ // 设置日志目录
+ $this->logDir = runtime_path() . 'log' . DIRECTORY_SEPARATOR;
+ if (!is_dir($this->logDir)) {
+ mkdir($this->logDir, 0755, true);
+ }
+
+ // 获取当前时间
+ $currentTime = time();
+ $currentMinute = date('i', $currentTime);
+ $currentHour = date('H', $currentTime);
+ $currentDay = date('d', $currentTime);
+ $currentMonth = date('m', $currentTime);
+ $currentWeekday = date('w', $currentTime); // 0=Sunday, 6=Saturday
+
+ $output->writeln("当前时间: {$currentHour}:{$currentMinute}");
+ $output->writeln("已加载 " . count($this->tasks) . " 个任务配置");
+
+ // 筛选需要执行的任务
+ $tasksToRun = [];
+ foreach ($this->tasks as $taskId => $task) {
+ if (!isset($task['enabled']) || !$task['enabled']) {
+ continue;
+ }
+
+ if ($this->shouldRun($task['schedule'], $currentMinute, $currentHour, $currentDay, $currentMonth, $currentWeekday)) {
+ $tasksToRun[$taskId] = $task;
+ }
+ }
+
+ if (empty($tasksToRun)) {
+ $output->writeln('当前时间没有需要执行的任务');
+ return true;
+ }
+
+ $output->writeln("找到 " . count($tasksToRun) . " 个需要执行的任务");
+
+ // 执行任务
+ if ($this->maxConcurrent > 1 && function_exists('pcntl_fork')) {
+ $this->executeConcurrent($tasksToRun, $output);
+ } else {
+ $this->executeSequential($tasksToRun, $output);
+ }
+
+ // 清理僵尸进程
+ $this->cleanupZombieProcesses();
+
+ $output->writeln('==========================================');
+ $output->writeln('任务调度器执行完成');
+ $output->writeln('==========================================');
+
+ return true;
+ }
+
+ /**
+ * 判断任务是否应该执行
+ *
+ * @param string $schedule cron表达式,格式:分钟 小时 日 月 星期
+ * @param int $minute 当前分钟
+ * @param int $hour 当前小时
+ * @param int $day 当前日期
+ * @param int $month 当前月份
+ * @param int $weekday 当前星期
+ * @return bool
+ */
+ protected function shouldRun($schedule, $minute, $hour, $day, $month, $weekday)
+ {
+ $parts = preg_split('/\s+/', trim($schedule));
+ if (count($parts) < 5) {
+ return false;
+ }
+
+ list($scheduleMinute, $scheduleHour, $scheduleDay, $scheduleMonth, $scheduleWeekday) = $parts;
+
+ // 解析分钟
+ if (!$this->matchCronField($scheduleMinute, $minute)) {
+ return false;
+ }
+
+ // 解析小时
+ if (!$this->matchCronField($scheduleHour, $hour)) {
+ return false;
+ }
+
+ // 解析日期
+ if (!$this->matchCronField($scheduleDay, $day)) {
+ return false;
+ }
+
+ // 解析月份
+ if (!$this->matchCronField($scheduleMonth, $month)) {
+ return false;
+ }
+
+ // 解析星期(注意:cron中0和7都表示星期日)
+ if ($scheduleWeekday !== '*') {
+ $scheduleWeekday = str_replace('7', '0', $scheduleWeekday);
+ if (!$this->matchCronField($scheduleWeekday, $weekday)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * 匹配cron字段
+ *
+ * @param string $field cron字段表达式
+ * @param int $value 当前值
+ * @return bool
+ */
+ protected function matchCronField($field, $value)
+ {
+ // 通配符
+ if ($field === '*') {
+ return true;
+ }
+
+ // 列表(逗号分隔)
+ if (strpos($field, ',') !== false) {
+ $values = explode(',', $field);
+ foreach ($values as $v) {
+ if ($this->matchCronField(trim($v), $value)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // 范围(如 1-5)
+ if (strpos($field, '-') !== false) {
+ list($start, $end) = explode('-', $field);
+ return $value >= (int)$start && $value <= (int)$end;
+ }
+
+ // 步长(如 */5 或 0-59/5)
+ if (strpos($field, '/') !== false) {
+ $parts = explode('/', $field);
+ $base = $parts[0];
+ $step = (int)$parts[1];
+
+ if ($base === '*') {
+ return $value % $step === 0;
+ } else {
+ // 处理范围步长,如 0-59/5
+ if (strpos($base, '-') !== false) {
+ list($start, $end) = explode('-', $base);
+ if ($value >= (int)$start && $value <= (int)$end) {
+ return ($value - (int)$start) % $step === 0;
+ }
+ return false;
+ } else {
+ return $value % $step === 0;
+ }
+ }
+ }
+
+ // 精确匹配
+ return (int)$field === $value;
+ }
+
+ /**
+ * 并发执行任务(多进程)
+ *
+ * @param array $tasks 任务列表
+ * @param Output $output 输出对象
+ */
+ protected function executeConcurrent($tasks, Output $output)
+ {
+ $output->writeln('使用多进程并发执行任务(最大并发数:' . $this->maxConcurrent . ')');
+
+ foreach ($tasks as $taskId => $task) {
+ // 等待可用进程槽
+ while (count($this->runningProcesses) >= $this->maxConcurrent) {
+ $this->waitForProcesses();
+ usleep(100000); // 等待100ms
+ }
+
+ // 检查任务是否已经在运行(防止重复执行)
+ $lockKey = "scheduler_task_lock:{$taskId}";
+ $lockTime = Cache::get($lockKey);
+ if ($lockTime && (time() - $lockTime) < 300) { // 5分钟内不重复执行
+ $output->writeln("任务 {$taskId} 正在运行中,跳过");
+ continue;
+ }
+
+ // 创建子进程
+ $pid = pcntl_fork();
+
+ if ($pid == -1) {
+ // 创建进程失败
+ $output->writeln("创建子进程失败:{$taskId}");
+ Log::error("任务调度器:创建子进程失败", ['task' => $taskId]);
+ continue;
+ } elseif ($pid == 0) {
+ // 子进程:执行任务
+ $this->runTask($taskId, $task);
+ exit(0);
+ } else {
+ // 父进程:记录子进程PID
+ $this->runningProcesses[$pid] = [
+ 'task_id' => $taskId,
+ 'start_time' => time(),
+ ];
+ $output->writeln("启动任务:{$taskId} (PID: {$pid})");
+
+ // 设置任务锁
+ Cache::set($lockKey, time(), 600); // 10分钟过期
+ }
+ }
+
+ // 等待所有子进程完成
+ while (!empty($this->runningProcesses)) {
+ $this->waitForProcesses();
+ usleep(500000); // 等待500ms
+ }
+ }
+
+ /**
+ * 顺序执行任务(单进程)
+ *
+ * @param array $tasks 任务列表
+ * @param Output $output 输出对象
+ */
+ protected function executeSequential($tasks, Output $output)
+ {
+ $output->writeln('使用单进程顺序执行任务');
+
+ foreach ($tasks as $taskId => $task) {
+ $output->writeln("执行任务:{$taskId}");
+ $this->runTask($taskId, $task);
+ }
+ }
+
+ /**
+ * 执行单个任务
+ *
+ * @param string $taskId 任务ID
+ * @param array $task 任务配置
+ */
+ protected function runTask($taskId, $task)
+ {
+ $startTime = microtime(true);
+ $logFile = $this->logDir . ($task['log_file'] ?? "scheduler_{$taskId}.log");
+
+ // 确保日志目录存在
+ $logDir = dirname($logFile);
+ if (!is_dir($logDir)) {
+ mkdir($logDir, 0755, true);
+ }
+
+ // 构建命令
+ $thinkPath = root_path() . 'think';
+ $command = "php {$thinkPath} {$task['command']}";
+ if (!empty($task['options'])) {
+ foreach ($task['options'] as $option) {
+ $command .= ' ' . escapeshellarg($option);
+ }
+ }
+
+ // 添加日志重定向
+ $command .= " >> " . escapeshellarg($logFile) . " 2>&1";
+
+ // 记录任务开始
+ $logMessage = "\n" . str_repeat('=', 60) . "\n";
+ $logMessage .= "任务开始执行: {$taskId}\n";
+ $logMessage .= "执行时间: " . date('Y-m-d H:i:s') . "\n";
+ $logMessage .= "命令: {$command}\n";
+ $logMessage .= str_repeat('=', 60) . "\n";
+ file_put_contents($logFile, $logMessage, FILE_APPEND);
+
+ // 执行命令
+ $descriptorspec = [
+ 0 => ['file', (PHP_OS_FAMILY === 'Windows' ? 'NUL' : '/dev/null'), 'r'], // stdin
+ 1 => ['file', $logFile, 'a'], // stdout
+ 2 => ['file', $logFile, 'a'], // stderr
+ ];
+
+ $process = @proc_open($command, $descriptorspec, $pipes, root_path());
+
+ if (is_resource($process)) {
+ // 关闭管道
+ if (isset($pipes[0])) @fclose($pipes[0]);
+ if (isset($pipes[1])) @fclose($pipes[1]);
+ if (isset($pipes[2])) @fclose($pipes[2]);
+
+ // 设置超时
+ $timeout = $task['timeout'] ?? 3600;
+ $startWaitTime = time();
+
+ // 等待进程完成或超时
+ while (true) {
+ $status = proc_get_status($process);
+
+ if (!$status['running']) {
+ break;
+ }
+
+ // 检查超时
+ if ((time() - $startWaitTime) > $timeout) {
+ if (function_exists('proc_terminate')) {
+ proc_terminate($process, SIGTERM);
+ // 等待进程终止
+ sleep(2);
+ $status = proc_get_status($process);
+ if ($status['running']) {
+ // 强制终止
+ proc_terminate($process, SIGKILL);
+ }
+ }
+ Log::warning("任务执行超时", [
+ 'task' => $taskId,
+ 'timeout' => $timeout,
+ ]);
+ break;
+ }
+
+ usleep(500000); // 等待500ms
+ }
+
+ // 关闭进程
+ proc_close($process);
+ } else {
+ // 如果 proc_open 失败,尝试直接执行(后台执行)
+ if (PHP_OS_FAMILY === 'Windows') {
+ pclose(popen("start /B " . $command, "r"));
+ } else {
+ exec($command . ' > /dev/null 2>&1 &');
+ }
+ }
+
+ $endTime = microtime(true);
+ $duration = round($endTime - $startTime, 2);
+
+ // 记录任务完成
+ $logMessage = "\n" . str_repeat('=', 60) . "\n";
+ $logMessage .= "任务执行完成: {$taskId}\n";
+ $logMessage .= "完成时间: " . date('Y-m-d H:i:s') . "\n";
+ $logMessage .= "执行时长: {$duration} 秒\n";
+ $logMessage .= str_repeat('=', 60) . "\n";
+ file_put_contents($logFile, $logMessage, FILE_APPEND);
+
+ Log::info("任务执行完成", [
+ 'task' => $taskId,
+ 'duration' => $duration,
+ ]);
+ }
+
+ /**
+ * 等待进程完成
+ */
+ protected function waitForProcesses()
+ {
+ foreach ($this->runningProcesses as $pid => $info) {
+ $status = 0;
+ $result = pcntl_waitpid($pid, $status, WNOHANG);
+
+ if ($result == $pid || $result == -1) {
+ // 进程已结束
+ unset($this->runningProcesses[$pid]);
+
+ $duration = time() - $info['start_time'];
+ Log::info("子进程执行完成", [
+ 'pid' => $pid,
+ 'task' => $info['task_id'],
+ 'duration' => $duration,
+ ]);
+ }
+ }
+ }
+
+ /**
+ * 清理僵尸进程
+ */
+ protected function cleanupZombieProcesses()
+ {
+ if (!function_exists('pcntl_waitpid')) {
+ return;
+ }
+
+ $status = 0;
+ while (($pid = pcntl_waitpid(-1, $status, WNOHANG)) > 0) {
+ // 清理僵尸进程
+ }
+ }
+}
+
diff --git a/Server/config/task_scheduler.php b/Server/config/task_scheduler.php
new file mode 100644
index 00000000..7fa7ea37
--- /dev/null
+++ b/Server/config/task_scheduler.php
@@ -0,0 +1,301 @@
+ [
+ // 'command' => '命令名称', // 必填:执行的 ThinkPHP 命令(见 application/command.php)
+ // 'schedule' => 'cron表达式', // 必填:cron 表达式,如 '*/5 * * * *' 表示每5分钟
+ // 'options' => ['--option=value'], // 可选:命令参数(原来 crontab 里的 --xxx=yyy)
+ // 'enabled' => true, // 可选:是否启用,默认 true
+ // 'max_concurrent'=> 1, // 可选:单任务最大并发数(目前由调度器统一控制,可预留)
+ // 'timeout' => 3600, // 可选:超时时间(秒),默认 3600
+ // 'log_file' => 'custom.log', // 可选:日志文件名,默认使用任务标识
+ // ]
+
+ // ===========================
+ // 高频任务(每分钟或更频繁)
+ // ===========================
+
+ // 同步微信好友列表(未删除好友),用于保持系统中好友数据实时更新
+ 'wechat_friends_active' => [
+ 'command' => 'wechatFriends:list',
+ 'schedule' => '*/1 * * * *', // 每1分钟
+ 'options' => ['--isDel=0'],
+ 'enabled' => true,
+ 'max_concurrent' => 1,
+ 'log_file' => 'crontab_wechatFriends_active.log',
+ ],
+
+ // 拉取“添加好友任务”列表,驱动自动加好友的任务队列
+ 'friend_task' => [
+ 'command' => 'friendTask:list',
+ 'schedule' => '*/1 * * * *', // 每1分钟
+ 'options' => [],
+ 'enabled' => true,
+ 'max_concurrent' => 1,
+ 'log_file' => 'crontab_friendTask.log',
+ ],
+
+ // 同步微信好友私聊消息列表,写入消息表,供客服工作台使用
+ 'message_friends' => [
+ 'command' => 'message:friendsList',
+ 'schedule' => '*/1 * * * *', // 每1分钟
+ 'options' => [],
+ 'enabled' => true,
+ 'max_concurrent' => 1,
+ 'log_file' => 'crontab_messageFriends.log',
+ ],
+
+ // 同步微信群聊消息列表,写入消息表,供群聊记录与风控分析
+ 'message_chatroom' => [
+ 'command' => 'message:chatroomList',
+ 'schedule' => '*/1 * * * *', // 每1分钟
+ 'options' => [],
+ 'enabled' => true,
+ 'max_concurrent' => 1,
+ 'log_file' => 'crontab_messageChatroom.log',
+ ],
+
+ // 客服端消息提醒任务,负责给在线客服推送新消息通知
+ 'kf_notice' => [
+ 'command' => 'kf:notice',
+ 'schedule' => '*/1 * * * *', // 每1分钟
+ 'options' => [],
+ 'enabled' => true,
+ 'max_concurrent' => 1,
+ 'log_file' => 'kf_notice.log',
+ ],
+
+ // ===========================
+ // 中频任务(每 2-5 分钟)
+ // ===========================
+
+ // 同步微信设备列表(未删除设备),用于设备管理与监控
+ 'device_active' => [
+ 'command' => 'device:list',
+ 'schedule' => '*/5 * * * *', // 每5分钟
+ 'options' => ['--isDel=0'],
+ 'enabled' => true,
+ 'max_concurrent' => 1,
+ 'log_file' => 'crontab_device_active.log',
+ ],
+
+ // 同步微信群聊列表(未删除群),用于群管理与后续任务分配
+ 'wechat_chatroom_active' => [
+ 'command' => 'wechatChatroom:list',
+ 'schedule' => '*/5 * * * *', // 每5分钟
+ 'options' => ['--isDel=0'],
+ 'enabled' => true,
+ 'max_concurrent' => 1,
+ 'log_file' => 'crontab_wechatChatroom_active.log',
+ ],
+
+ // 同步微信群成员列表(群好友),维持群成员明细数据
+ 'group_friends' => [
+ 'command' => 'groupFriends:list',
+ 'schedule' => '*/5 * * * *', // 每5分钟
+ 'options' => [],
+ 'enabled' => true,
+ 'max_concurrent' => 1,
+ 'log_file' => 'crontab_groupFriends.log',
+ ],
+
+ // 同步“微信客服列表”,获取绑定到公司的微信号,用于工作台与分配规则
+ 'wechat_list' => [
+ 'command' => 'wechatList:list',
+ 'schedule' => '*/5 * * * *', // 每5分钟
+ 'options' => [],
+ 'enabled' => true,
+ 'max_concurrent' => 1,
+ 'log_file' => 'crontab_wechatList.log',
+ ],
+
+ // 同步公司账号列表(企业/租户账号),供后台管理与统计
+ 'account_list' => [
+ 'command' => 'account:list',
+ 'schedule' => '*/5 * * * *', // 每5分钟
+ 'options' => [],
+ 'enabled' => true,
+ 'max_concurrent' => 1,
+ 'log_file' => 'crontab_account.log',
+ ],
+
+ // 内容采集任务,将外部或设备内容同步到系统内容库
+ 'content_collect' => [
+ 'command' => 'content:collect',
+ 'schedule' => '*/5 * * * *', // 每5分钟
+ 'options' => [],
+ 'enabled' => true,
+ 'max_concurrent' => 1,
+ 'log_file' => 'crontab_contentCollect.log',
+ ],
+
+ // 工作台:自动点赞好友/客户朋友圈,提高账号活跃度
+ 'workbench_auto_like' => [
+ 'command' => 'workbench:autoLike',
+ 'schedule' => '*/6 * * * *', // 每6分钟
+ 'options' => [],
+ 'enabled' => true,
+ 'max_concurrent' => 1,
+ 'log_file' => 'crontab_workbench_autoLike.log',
+ ],
+
+ // 工作台:自动建群任务,按规则批量创建微信群
+ 'workbench_group_create' => [
+ 'command' => 'workbench:groupCreate',
+ 'schedule' => '*/5 * * * *', // 每5分钟
+ 'options' => [],
+ 'enabled' => true,
+ 'max_concurrent' => 1,
+ 'log_file' => 'workbench_groupCreate.log',
+ ],
+
+ // 工作台:自动导入通讯录到系统,生成加粉/建群等任务
+ 'workbench_import_contact' => [
+ 'command' => 'workbench:import-contact',
+ 'schedule' => '*/5 * * * *', // 每5分钟
+ 'options' => [],
+ 'enabled' => true,
+ 'max_concurrent' => 1,
+ 'log_file' => 'import_contact.log',
+ ],
+
+ // ===========================
+ // 低频任务(每 2 分钟)
+ // ===========================
+
+ // 清洗并同步微信原始数据到存客宝业务表(数据治理任务)
+ 'sync_wechat_data' => [
+ 'command' => 'sync:wechatData',
+ 'schedule' => '*/2 * * * *', // 每2分钟
+ 'options' => [],
+ 'enabled' => true,
+ 'max_concurrent' => 1,
+ 'log_file' => 'sync_wechat_data.log',
+ ],
+
+ // 工作台:流量分发任务,把流量池中的线索按规则分配给微信号或员工
+ 'workbench_traffic_distribute' => [
+ 'command' => 'workbench:trafficDistribute',
+ 'schedule' => '*/2 * * * *', // 每2分钟
+ 'options' => [],
+ 'enabled' => true,
+ 'max_concurrent' => 1,
+ 'log_file' => 'traffic_distribute.log',
+ ],
+
+ // 工作台:朋友圈同步任务,拉取并落库朋友圈内容
+ 'workbench_moments' => [
+ 'command' => 'workbench:moments',
+ 'schedule' => '*/2 * * * *', // 每2分钟
+ 'options' => [],
+ 'enabled' => true,
+ 'max_concurrent' => 1,
+ 'log_file' => 'workbench_moments.log',
+ ],
+
+ // 预防性切换好友任务,监控频繁/风控风险,自动切换加人对象,保护微信号
+ 'switch_friends' => [
+ 'command' => 'switch:friends',
+ 'schedule' => '*/2 * * * *', // 每2分钟
+ 'options' => [],
+ 'enabled' => true,
+ 'max_concurrent' => 1,
+ 'log_file' => 'switch_friends.log',
+ ],
+
+ // ===========================
+ // 低频任务(每 30 分钟)
+ // ===========================
+
+ // 拉取设备通话记录(语音/电话),用于质检、统计或标签打分
+ 'call_recording' => [
+ 'command' => 'call-recording:list',
+ 'schedule' => '*/30 * * * *', // 每30分钟
+ 'options' => [],
+ 'enabled' => true,
+ 'max_concurrent' => 1,
+ 'log_file' => 'call_recording.log',
+ ],
+
+ // ===========================
+ // 每日 / 每几天任务
+ // ===========================
+
+ // 每日 1:00 同步“已删除设备”列表,补齐历史状态
+ 'device_deleted' => [
+ 'command' => 'device:list',
+ 'schedule' => '0 1 * * *', // 每天1点
+ 'options' => ['--isDel=1'],
+ 'enabled' => true,
+ 'max_concurrent' => 1,
+ 'log_file' => 'crontab_device_deleted.log',
+ ],
+
+ // 每日 1:10 同步“已停用设备”列表,更新停用状态
+ 'device_stopped' => [
+ 'command' => 'device:list',
+ 'schedule' => '10 1 * * *', // 每天1:10
+ 'options' => ['--isDel=2'],
+ 'enabled' => true,
+ 'max_concurrent' => 1,
+ 'log_file' => 'crontab_device_stopped.log',
+ ],
+
+ // 每日 1:30 同步“已删除微信好友”,用于历史恢复与报表
+ 'wechat_friends_deleted' => [
+ 'command' => 'wechatFriends:list',
+ 'schedule' => '30 1 * * *', // 每天1:30
+ 'options' => ['--isDel=1'],
+ 'enabled' => true,
+ 'max_concurrent' => 1,
+ 'log_file' => 'crontab_wechatFriends_deleted.log',
+ ],
+
+ // 每日 1:30 同步“已删除微信群聊”,用于统计与留痕
+ 'wechat_chatroom_deleted' => [
+ 'command' => 'wechatChatroom:list',
+ 'schedule' => '30 1 * * *', // 每天1:30
+ 'options' => ['--isDel=1'],
+ 'enabled' => true,
+ 'max_concurrent' => 1,
+ 'log_file' => 'crontab_wechatChatroom_deleted.log',
+ ],
+
+ // 每日 2:00 统一计算所有微信账号健康分(基础分 + 动态分)
+ 'wechat_calculate_score' => [
+ 'command' => 'wechat:calculate-score',
+ 'schedule' => '0 2 * * *', // 每天2点
+ 'options' => [],
+ 'enabled' => true,
+ 'max_concurrent' => 1,
+ 'log_file' => 'calculate_score.log',
+ ],
+
+ // 每 3 天执行的全量任务
+
+ // 每 3 天 3:00 全量同步所有在线好友,做一次大规模校准
+ 'sync_all_friends' => [
+ 'command' => 'sync:allFriends',
+ 'schedule' => '0 3 */3 * *', // 每3天的3点
+ 'options' => [],
+ 'enabled' => true,
+ 'max_concurrent' => 1,
+ 'log_file' => 'all_friends.log',
+ ],
+
+ // 已禁用的任务(注释掉的任务)
+ // 'workbench_group_push' => [
+ // 'command' => 'workbench:groupPush',
+ // 'schedule' => '*/2 * * * *',
+ // 'options' => [],
+ // 'enabled' => false,
+ // 'log_file' => 'workbench_groupPush.log',
+ // ],
+];
+