SyncMailList.php 3.3 KB
<?php

namespace App\Console\Commands;

use App\Models\Email;
use App\Models\Folder;
use Helper\Mail\Mail;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;
use function Co\run;

class SyncMailList extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'SyncMailList';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = '同步邮箱的邮件到本地';

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {

        // 这个是防止前一个任务没有完成,反而无法取得资源。
        $rand = date('dHi');
        // 携程数量越大,需要的内存越大
        $max_coroutine  =   10000;
        // 最大携程数量
        \co::set(['max_coroutine'=>$max_coroutine]);

        run(function () use ($rand,$max_coroutine){
            // 获取邮箱总数量
            $size = Email::where([])->count();
            // 最后一条数据的id
            $lastId = Email::where([])->orderBy('id','desc')->value('id');
            // 创建的携程数量
            $max_coroutine = $size > $max_coroutine ? $max_coroutine : $size;
            if ($max_coroutine){
                for ($i = $max_coroutine; $i > 0; $i--) {
                    // 创建携程
                    go(function () use ($size,$rand,$lastId){

                        $n = 1;
                        while ($n <= $lastId){
                            // 是否已存在
                            if(Cache::add('syncMail'.$rand.':'.$n,$n,7200)) {
                                $this->sync($n);
                            }
                            $n++;
                        }

                    });
                }
            }

        });

        return Command::SUCCESS;
    }

    /**
     * 开始同步执行
     * @param int $n 第几条数据
     * @author:dc
     * @time 2023/2/5 17:21
     */
    private function sync(int $n = 0){

        $email = Email::where(['id'=>$n])->first();
        // 密码没有错误,且状态正常的
        if ($email && $email->pwd_error == 0 && $email->status == Email::STATUS_ACTIVE){
            // 登录imap服务器
            Mail::login($email->email,$email->password,$email->imap);
            // 设置id
            Mail::$client[$email]->setId($email->id);
            // 同步文件夹
            Mail::syncFolder($email->email);

            // 获取当前邮箱的所有文件夹
            $folders =   Folder::_all($email->id);
            // 目前只发现最高2级
            foreach ($folders as $folder){
                if(empty($folder['_child'])){
                    // 同步邮件
                    Mail::syncMail([],$email->email,$email->id,$folder['id'],$folder['origin_folder']);
                }else{
                    // 循环子级目录,有子级的情况,父级不可操作,且不会有邮件
                    foreach ($folder['_child'] as $f){
                        // 同步邮件
                        Mail::syncMail([],$email->email,$email->id,$f['id'],$folder['origin_folder'].'/'.$f['origin_folder']);
                    }
                }

            }
        }

    }



}