| 
 | 
 | 
 <?php
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 namespace App\Mail;
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 use App\Mail\Jobs\SendJob;
 | 
| 
 | 
 | 
 use App\Mail\lib\Lang;
 | 
| 
 | 
 | 
 use App\Mail\lib\MailFun;
 | 
| 
 | 
 | 
 use App\Mail\lib\MailParse\Body;
 | 
| 
 | 
 | 
 use App\Models\Email;
 | 
| 
 | 
 | 
 use App\Models\EmailBody;
 | 
| 
 | 
 | 
 use App\Models\EmailContact;
 | 
| 
 | 
 | 
 use App\Models\EmailContactGroup;
 | 
| 
 | 
 | 
 use App\Models\EmailFolder;
 | 
| 
 | 
 | 
 use App\Models\Host;
 | 
| 
 | 
 | 
 use App\Models\EmailList;
 | 
| 
 | 
 | 
 use App\Models\EmailLog;
 | 
| 
 | 
 | 
 use App\Models\EmailSendJob;
 | 
| 
 | 
 | 
 use Illuminate\Http\UploadedFile;
 | 
| 
 | 
 | 
 use Illuminate\Support\Facades\Config;
 | 
| 
 | 
 | 
 use Illuminate\Support\Facades\DB;
 | 
| 
 | 
 | 
 use Illuminate\Support\Facades\Log;
 | 
| 
 | 
 | 
 use Illuminate\Support\Facades\Validator;
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 /**
 | 
| 
 | 
 | 
  * 邮件服务
 | 
| 
 | 
 | 
  * @time 2022/7/29 15:05
 | 
| 
 | 
 | 
  * Class Mail
 | 
| 
 | 
 | 
  * @package app\Mail
 | 
| 
 | 
 | 
  */
 | 
| 
 | 
 | 
 class Mail {
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     /**
 | 
| 
 | 
 | 
      * @var Mail
 | 
| 
 | 
 | 
      */
 | 
| 
 | 
 | 
     private static $Instance;
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     /**
 | 
| 
 | 
 | 
      * 如 imap.qq.com
 | 
| 
 | 
 | 
      * @var array
 | 
| 
 | 
 | 
      */
 | 
| 
 | 
 | 
     private $host = [
 | 
| 
 | 
 | 
         'imap'=>'',
 | 
| 
 | 
 | 
         'smtp'=>''
 | 
| 
 | 
 | 
     ];
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     /**
 | 
| 
 | 
 | 
      * 用户email表的id
 | 
| 
 | 
 | 
      * @var int
 | 
| 
 | 
 | 
      */
 | 
| 
 | 
 | 
     private $id = 0;
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     /**
 | 
| 
 | 
 | 
      * 邮箱地址
 | 
| 
 | 
 | 
      * @var string
 | 
| 
 | 
 | 
      */
 | 
| 
 | 
 | 
     private $username = '';
 | 
| 
 | 
 | 
     private $nickname = '';
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     /**
 | 
| 
 | 
 | 
      * 密码
 | 
| 
 | 
 | 
      * @var string
 | 
| 
 | 
 | 
      */
 | 
| 
 | 
 | 
     private $password = '';
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     /**
 | 
| 
 | 
 | 
      * 端口
 | 
| 
 | 
 | 
      * @var int 143 993
 | 
| 
 | 
 | 
      */
 | 
| 
 | 
 | 
     private $port = 993;
 | 
| 
 | 
 | 
     /**
 | 
| 
 | 
 | 
      * 协议
 | 
| 
 | 
 | 
      * @var string
 | 
| 
 | 
 | 
      */
 | 
| 
 | 
 | 
     private $ssl = 'ssl://';
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     /**
 | 
| 
 | 
 | 
      * 用户id
 | 
| 
 | 
 | 
      * @var int
 | 
| 
 | 
 | 
      */
 | 
| 
 | 
 | 
     private $user_id = 0;
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     /**
 | 
| 
 | 
 | 
      * 附件保存目录
 | 
| 
 | 
 | 
      * @var string
 | 
| 
 | 
 | 
      */
 | 
| 
 | 
 | 
     private $filePath;
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     /**
 | 
| 
 | 
 | 
      * imap服务器连接
 | 
| 
 | 
 | 
      * @var \App\Http\Mail\lib\client\Imap[]
 | 
| 
 | 
 | 
      */
 | 
| 
 | 
 | 
     private $client;
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     /**
 | 
| 
 | 
 | 
      * 连接目录 INBOX
 | 
| 
 | 
 | 
      * @var string
 | 
| 
 | 
 | 
      */
 | 
| 
 | 
 | 
     private $folder = 'INBOX';
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     /**
 | 
| 
 | 
 | 
      * 目录编号
 | 
| 
 | 
 | 
      * @var int
 | 
| 
 | 
 | 
      */
 | 
| 
 | 
 | 
     private $folderId = 0;
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     /**
 | 
| 
 | 
 | 
      * @var array|\Illuminate\Contracts\Foundation\Application|\Illuminate\Http\Request|string|null
 | 
| 
 | 
 | 
      */
 | 
| 
 | 
 | 
     private $request;
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     /**
 | 
| 
 | 
 | 
      * 所有绑定邮箱的id
 | 
| 
 | 
 | 
      * @var array
 | 
| 
 | 
 | 
      */
 | 
| 
 | 
 | 
     private $email_ids = [];
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     private function __construct(){
 | 
| 
 | 
 | 
         $this->request  =   request();
 | 
| 
 | 
 | 
     }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     /**
 | 
| 
 | 
 | 
      * @return Mail
 | 
| 
 | 
 | 
      */
 | 
| 
 | 
 | 
     public static function getInstance(int $user_id, string $email=''): Mail
 | 
| 
 | 
 | 
     {
 | 
| 
 | 
 | 
         $key = md5($user_id.$email);
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         if(empty(self::$Instance[$key])){
 | 
| 
 | 
 | 
             $mail = self::$Instance[$key] =   new static();
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
             $mail->user_id = $user_id;
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
             // 绑定的所有邮箱id
 | 
| 
 | 
 | 
             $mail->email_ids = array_column(Email::_getById($mail->user_id),'id');
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
             if($email){
 | 
| 
 | 
 | 
                 $data   =   Email::_first($email);
 | 
| 
 | 
 | 
                 // 是否存在并绑定了
 | 
| 
 | 
 | 
                 if($data && in_array($data['id'],$mail->email_ids)){
 | 
| 
 | 
 | 
                     $mail->id = $data['id'];
 | 
| 
 | 
 | 
                     $mail->username =   $email;
 | 
| 
 | 
 | 
                     $mail->nickname =   $data['email_name']??'';
 | 
| 
 | 
 | 
                     $mail->password =   $data['password'];
 | 
| 
 | 
 | 
                     // 当前选择的邮箱
 | 
| 
 | 
 | 
                     $mail->host = [
 | 
| 
 | 
 | 
                         'imap'  =>  $data['imap'],
 | 
| 
 | 
 | 
                         'smtp'  =>  $data['smtp'],
 | 
| 
 | 
 | 
                     ];
 | 
| 
 | 
 | 
                     // 设置目录
 | 
| 
 | 
 | 
                     $mail->selectFolder($mail->folder);
 | 
| 
 | 
 | 
                 }else{
 | 
| 
 | 
 | 
                     throw new \Exception(Lang::__('email_not_bind',$email));
 | 
| 
 | 
 | 
                 }
 | 
| 
 | 
 | 
             }
 | 
| 
 | 
 | 
         }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         // 设置邮件附件地址
 | 
| 
 | 
 | 
         self::$Instance[$key]->setFilePath(storage_path('/imap'));
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         return self::$Instance[$key];
 | 
| 
 | 
 | 
     }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     /**
 | 
| 
 | 
 | 
      * 设置目录
 | 
| 
 | 
 | 
      * @param $path
 | 
| 
 | 
 | 
      * @time 2022/8/1 15:39
 | 
| 
 | 
 | 
      */
 | 
| 
 | 
 | 
     public function setFilePath($path){
 | 
| 
 | 
 | 
         $this->filePath =   $path;
 | 
| 
 | 
 | 
 //        if(!is_dir($this->filePath)){
 | 
| 
 | 
 | 
 //            @mkdir($this->filePath,0775,true);
 | 
| 
 | 
 | 
 //        }
 | 
| 
 | 
 | 
     }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     /**
 | 
| 
 | 
 | 
      * @return string
 | 
| 
 | 
 | 
      */
 | 
| 
 | 
 | 
     public function getFilePath(): string
 | 
| 
 | 
 | 
     {
 | 
| 
 | 
 | 
         $path = $this->filePath.'/'.$this->username.'/';
 | 
| 
 | 
 | 
 //        if(is_dir($path)){
 | 
| 
 | 
 | 
 //            mkdir($path,0775,true);
 | 
| 
 | 
 | 
 //        }
 | 
| 
 | 
 | 
         return $path;
 | 
| 
 | 
 | 
     }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     /**
 | 
| 
 | 
 | 
      * 选择使用的用户
 | 
| 
 | 
 | 
      * @param int $user_id
 | 
| 
 | 
 | 
      * @param string $email
 | 
| 
 | 
 | 
      * @return Mail
 | 
| 
 | 
 | 
      * @author:dc
 | 
| 
 | 
 | 
      * @time 2022/7/29 17:42
 | 
| 
 | 
 | 
      */
 | 
| 
 | 
 | 
     public static function use(int $user_id, string $email=''):Mail {
 | 
| 
 | 
 | 
         $mail = self::getInstance($user_id,$email);
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         return $mail;
 | 
| 
 | 
 | 
     }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     /**
 | 
| 
 | 
 | 
      * 选择文件夹
 | 
| 
 | 
 | 
      * @param string|int $folder
 | 
| 
 | 
 | 
      * @time 2022/8/4 14:54
 | 
| 
 | 
 | 
      */
 | 
| 
 | 
 | 
     public function selectFolder($folder){
 | 
| 
 | 
 | 
         if($folder) {
 | 
| 
 | 
 | 
             $lists = EmailFolder::_all($this->id, false);
 | 
| 
 | 
 | 
             // 找到目标文件的id,pid
 | 
| 
 | 
 | 
             foreach ($lists as $list) {
 | 
| 
 | 
 | 
                 if ($list[is_numeric($folder)?'id':'folder'] == $folder) {
 | 
| 
 | 
 | 
                     $id = $list['id'];// id
 | 
| 
 | 
 | 
                     $pid = $list['pid']; // 上级id
 | 
| 
 | 
 | 
                     $folder = $list['origin_folder'];
 | 
| 
 | 
 | 
                 }
 | 
| 
 | 
 | 
             }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
             // 不存在
 | 
| 
 | 
 | 
             if(!$lists){
 | 
| 
 | 
 | 
                 $folder = 'INBOX';
 | 
| 
 | 
 | 
                 $pid = 0;
 | 
| 
 | 
 | 
                 // 这个名字是每个邮箱默认的,不可更改
 | 
| 
 | 
 | 
                 $id = EmailFolder::_insert($this->user_id,$this->id,'INBOX','INBOX');
 | 
| 
 | 
 | 
                 if($folder != 'INBOX'){
 | 
| 
 | 
 | 
                     $id = 0;
 | 
| 
 | 
 | 
                 }
 | 
| 
 | 
 | 
             }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
             // 是否存
 | 
| 
 | 
 | 
             if ($id ?? 0) {
 | 
| 
 | 
 | 
                 // 拿到上级,成为 dir/dir/dir
 | 
| 
 | 
 | 
                 if ($pid ?? 0) {
 | 
| 
 | 
 | 
                     EmailFolder::_firstTree($lists, $pid, $folder,'origin_folder');
 | 
| 
 | 
 | 
                 }
 | 
| 
 | 
 | 
                 $this->folderId = $id;
 | 
| 
 | 
 | 
                 $this->folder = $folder;
 | 
| 
 | 
 | 
                 $this->folderInfo = EmailFolder::_first($id);
 | 
| 
 | 
 | 
             } else {
 | 
| 
 | 
 | 
                 throw new \Exception(Lang::__('email_folder_not', $folder));
 | 
| 
 | 
 | 
             }
 | 
| 
 | 
 | 
         }
 | 
| 
 | 
 | 
     }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     /**
 | 
| 
 | 
 | 
      * @return \App\Http\Mail\lib\client\Imap
 | 
| 
 | 
 | 
      * @throws \Exception
 | 
| 
 | 
 | 
      * @time 2022/8/5 17:22
 | 
| 
 | 
 | 
      */
 | 
| 
 | 
 | 
     public function client($email=''){
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         $email = $email ? : $this->username;
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         if(empty($this->client[$email])){
 | 
| 
 | 
 | 
             if($email == $this->username){
 | 
| 
 | 
 | 
                 $this->login();
 | 
| 
 | 
 | 
             }else{
 | 
| 
 | 
 | 
                 $data = Email::_first($email);
 | 
| 
 | 
 | 
                 if($data){
 | 
| 
 | 
 | 
                     $this->loginImap($data['imap'],$data['email'],$data['password']);
 | 
| 
 | 
 | 
                 }
 | 
| 
 | 
 | 
             }
 | 
| 
 | 
 | 
         }
 | 
| 
 | 
 | 
         return $this->client[$email];
 | 
| 
 | 
 | 
     }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     /**
 | 
| 
 | 
 | 
      * 登录邮箱
 | 
| 
 | 
 | 
      * @param string $password
 | 
| 
 | 
 | 
      * @param string $imap
 | 
| 
 | 
 | 
      * @param string $smtp
 | 
| 
 | 
 | 
      * @return bool
 | 
| 
 | 
 | 
      * @throws \Exception
 | 
| 
 | 
 | 
      * @time 2022/8/5 17:21
 | 
| 
 | 
 | 
      */
 | 
| 
 | 
 | 
     public function login(string $password='',string $imap='',string $smtp=''):bool{
 | 
| 
 | 
 | 
         // host
 | 
| 
 | 
 | 
         if($imap && $this->username){
 | 
| 
 | 
 | 
             $this->hostAdd(explode('@',$this->username)[1],$imap,$smtp);
 | 
| 
 | 
 | 
         }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         if(!$password && !$this->password){
 | 
| 
 | 
 | 
             throw new \Exception(Lang::__('password_required'));
 | 
| 
 | 
 | 
         }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         if($password){
 | 
| 
 | 
 | 
             // 如果密码不一致,更新
 | 
| 
 | 
 | 
             if($password != $this->password){
 | 
| 
 | 
 | 
                 Email::_changePwd($this->username, $password);
 | 
| 
 | 
 | 
             }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
             $this->password = $password;
 | 
| 
 | 
 | 
         }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         if(!$this->hostMy()){
 | 
| 
 | 
 | 
             throw new \Exception(Lang::__('login_host'));
 | 
| 
 | 
 | 
         }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         // imap imap.qq.com
 | 
| 
 | 
 | 
         $this->loginImap($this->hostMy('imap'),$this->username,$this->password);
 | 
| 
 | 
 | 
         // 密码没验证成功
 | 
| 
 | 
 | 
 //            if($this->id){
 | 
| 
 | 
 | 
 //                Email::_update(['id'=>$this->id],['pwd_error'=>1]);
 | 
| 
 | 
 | 
 //            }
 | 
| 
 | 
 | 
         return true;
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     /**
 | 
| 
 | 
 | 
      * 公用链接
 | 
| 
 | 
 | 
      * @param $host
 | 
| 
 | 
 | 
      * @param $email
 | 
| 
 | 
 | 
      * @param $password
 | 
| 
 | 
 | 
      * @throws \Exception
 | 
| 
 | 
 | 
      * @author:dc
 | 
| 
 | 
 | 
      * @time 2022/12/7 9:35
 | 
| 
 | 
 | 
      */
 | 
| 
 | 
 | 
     public function loginImap($host,$email,$password):void {
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         $this->client[$email] = new \App\Http\Mail\lib\client\Imap();
 | 
| 
 | 
 | 
         // 是否初始成功
 | 
| 
 | 
 | 
         $this->client[$email]->login($this->ssl.$host.':'.$this->port,$email,$password);
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     /**
 | 
| 
 | 
 | 
      * 自动路由
 | 
| 
 | 
 | 
      * @return \Illuminate\Http\JsonResponse|string|\Symfony\Component\HttpFoundation\BinaryFileResponse
 | 
| 
 | 
 | 
      * @throws \Illuminate\Contracts\Container\BindingResolutionException
 | 
| 
 | 
 | 
      * @throws \Psr\SimpleCache\InvalidArgumentException
 | 
| 
 | 
 | 
      * @throws \Throwable
 | 
| 
 | 
 | 
      * @author:dc
 | 
| 
 | 
 | 
      * @time 2022/8/1 11:07
 | 
| 
 | 
 | 
      */
 | 
| 
 | 
 | 
     public function autoRoute(){
 | 
| 
 | 
 | 
         $task = $this->request->get('_task');
 | 
| 
 | 
 | 
         $action = $this->request->get('_action');
 | 
| 
 | 
 | 
         $result = [];
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         switch ($task){
 | 
| 
 | 
 | 
             case 'sync': {
 | 
| 
 | 
 | 
                 // 同步操作
 | 
| 
 | 
 | 
                 switch ($action){
 | 
| 
 | 
 | 
                     case 'list': {
 | 
| 
 | 
 | 
                         // 同步邮件列表
 | 
| 
 | 
 | 
                         $msgno = $this->request->post('msgno',[]);
 | 
| 
 | 
 | 
                         if(is_string($msgno)){
 | 
| 
 | 
 | 
                             $msgno = explode(',',$msgno);
 | 
| 
 | 
 | 
                         }
 | 
| 
 | 
 | 
                         $result = $this->syncEmailList($msgno);
 | 
| 
 | 
 | 
                         break;
 | 
| 
 | 
 | 
                     }
 | 
| 
 | 
 | 
                     // 同步文件夹
 | 
| 
 | 
 | 
                     case 'folder': {
 | 
| 
 | 
 | 
                         $folder = $this->request->post('folder');
 | 
| 
 | 
 | 
                         $result = $this->syncFolder($folder);
 | 
| 
 | 
 | 
                         break;
 | 
| 
 | 
 | 
                     }
 | 
| 
 | 
 | 
                     // 更新最新的
 | 
| 
 | 
 | 
                     case 'new':{
 | 
| 
 | 
 | 
                         $result = $this->syncEmailList();
 | 
| 
 | 
 | 
                         break;
 | 
| 
 | 
 | 
                     }
 | 
| 
 | 
 | 
                 }
 | 
| 
 | 
 | 
                 break;
 | 
| 
 | 
 | 
             }
 | 
| 
 | 
 | 
             // 设置标签,已读,未读,删除等
 | 
| 
 | 
 | 
             case 'flags':{
 | 
| 
 | 
 | 
                 $ids = $this->request->post('ids');
 | 
| 
 | 
 | 
                 $ids = is_string($ids) ? explode(',',$ids) : $ids;
 | 
| 
 | 
 | 
                 $ids = is_array($ids) ? $ids : [$ids];
 | 
| 
 | 
 | 
                 // 获取到邮件的uid
 | 
| 
 | 
 | 
                 $uids = EmailList::_getUidsByIds($ids,$this->id);
 | 
| 
 | 
 | 
                 $filed = '';
 | 
| 
 | 
 | 
                 $value = 0;
 | 
| 
 | 
 | 
                 $mod = '';
 | 
| 
 | 
 | 
                 $flags = '';
 | 
| 
 | 
 | 
                 // 标记操作
 | 
| 
 | 
 | 
                 switch ($action){
 | 
| 
 | 
 | 
                     // 标记已读
 | 
| 
 | 
 | 
                     case 'setSeen':{
 | 
| 
 | 
 | 
                         $filed = 'seen';
 | 
| 
 | 
 | 
                         $value = 1;
 | 
| 
 | 
 | 
                         $flags = 'seen';
 | 
| 
 | 
 | 
                         $mod = '+';
 | 
| 
 | 
 | 
                         break;
 | 
| 
 | 
 | 
                     }
 | 
| 
 | 
 | 
                     // 标记未读
 | 
| 
 | 
 | 
                     case 'delSeen':{
 | 
| 
 | 
 | 
                         $filed = 'seen';
 | 
| 
 | 
 | 
                         $value = 0;
 | 
| 
 | 
 | 
                         $flags = 'seen';
 | 
| 
 | 
 | 
                         $mod = '-';
 | 
| 
 | 
 | 
                         break;
 | 
| 
 | 
 | 
                     }
 | 
| 
 | 
 | 
                     case 'setFlagged':{
 | 
| 
 | 
 | 
                         $filed = 'flagged';
 | 
| 
 | 
 | 
                         $value = 1;
 | 
| 
 | 
 | 
                         $flags = 'flagged';
 | 
| 
 | 
 | 
                         $mod = '+';
 | 
| 
 | 
 | 
                         break;
 | 
| 
 | 
 | 
                     }
 | 
| 
 | 
 | 
                     case 'delFlagged':{
 | 
| 
 | 
 | 
                         $filed = 'flagged';
 | 
| 
 | 
 | 
                         $value = 0;
 | 
| 
 | 
 | 
                         $flags = 'flagged';
 | 
| 
 | 
 | 
                         $mod = '-';
 | 
| 
 | 
 | 
                         break;
 | 
| 
 | 
 | 
                     }
 | 
| 
 | 
 | 
                 }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
                 if($this->setflagged($uids,$flags,$mod)){
 | 
| 
 | 
 | 
                     // 更新标签
 | 
| 
 | 
 | 
                     if(EmailList::_setFlags(array_keys($uids),$this->id,$filed,$value)){
 | 
| 
 | 
 | 
                         $result = array_keys($uids);
 | 
| 
 | 
 | 
                     }
 | 
| 
 | 
 | 
                 }
 | 
| 
 | 
 | 
                 break;
 | 
| 
 | 
 | 
             }
 | 
| 
 | 
 | 
             case 'info': {
 | 
| 
 | 
 | 
                 $id = (int) $this->request->get('id');
 | 
| 
 | 
 | 
                 // 读取邮件
 | 
| 
 | 
 | 
                 $result =  $this->emailInfo($id);
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
                 if(!$result){
 | 
| 
 | 
 | 
                     $result = new static();
 | 
| 
 | 
 | 
                 }else{
 | 
| 
 | 
 | 
                     // 是否是数组
 | 
| 
 | 
 | 
                     if(!is_array($result)) $result = $result->toArray();
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
                     // 缓存一下
 | 
| 
 | 
 | 
                     \Cache::set('app_email_info_'.$this->user_id.":".$result['id'],$result,3000);
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
                     // 渲染视图
 | 
| 
 | 
 | 
                     $result['body'] = view('admin/email/info',[
 | 
| 
 | 
 | 
                         'data'  =>  $result
 | 
| 
 | 
 | 
                     ])->render();
 | 
| 
 | 
 | 
                     // 有邮件编码bug,必须要转
 | 
| 
 | 
 | 
                     $result['body'] = base64_encode($result['body']);
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
                 }
 | 
| 
 | 
 | 
                 ///////////////////////// 这里是测试
 | 
| 
 | 
 | 
 //                print_r($result['body']['text_html']);exit();
 | 
| 
 | 
 | 
 //                foreach ($result['body']['text_html'] as $item){
 | 
| 
 | 
 | 
 //                    if(!empty($item['type']) && ($item['type'] == 'text/html' || $item['type'] == 'text/plain')){
 | 
| 
 | 
 | 
 //                        header("content-type:text/html;charset=".($item['charset']??'utf-8'));
 | 
| 
 | 
 | 
 //                        echo $item['body'];
 | 
| 
 | 
 | 
 //                    }
 | 
| 
 | 
 | 
 //                }
 | 
| 
 | 
 | 
 //                exit();
 | 
| 
 | 
 | 
                 ///////////////////////
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
                 break;
 | 
| 
 | 
 | 
             }
 | 
| 
 | 
 | 
             case 'list': {
 | 
| 
 | 
 | 
                 if($this->id){
 | 
| 
 | 
 | 
                     $eids = [$this->id];
 | 
| 
 | 
 | 
                 }else{
 | 
| 
 | 
 | 
                     $eids = array_column(Email::_get($this->user_id),'id');
 | 
| 
 | 
 | 
                 }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
                 $total = 0;
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
                 if($this->folder=='INBOX'){
 | 
| 
 | 
 | 
                     $fids = EmailFolder::_user_folders($this->email_ids);
 | 
| 
 | 
 | 
 //                    $total = array_sum(array_column($fids,'exsts'));
 | 
| 
 | 
 | 
                     $fids = array_column($fids,'id');
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
                     $unseen = array_sum(array_column($fids,'unseen')); // 未读数量
 | 
| 
 | 
 | 
 //                    $unseen = EmailList::_getUnseenNum($eids); // 未读数量
 | 
| 
 | 
 | 
                 }else{
 | 
| 
 | 
 | 
                     $fids = [$this->folderId];
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
                     $total = $this->folderInfo['exsts']??0;
 | 
| 
 | 
 | 
                 }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
                 // 搜索
 | 
| 
 | 
 | 
                 $search = [];
 | 
| 
 | 
 | 
                 $search['search'] = $this->request->get('search');
 | 
| 
 | 
 | 
                 $search['seen'] = $this->request->get('seen');
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
                 $result =  $this->emailLists($eids,$fids,$total,$search)->toArray();
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 //                if($this->folder == 'INBOX'){
 | 
| 
 | 
 | 
                 $this->allemail = [];
 | 
| 
 | 
 | 
                 foreach ($result['data'] as $k=>$datum){
 | 
| 
 | 
 | 
                     if(!$datum['uid']){
 | 
| 
 | 
 | 
                         // 邮件
 | 
| 
 | 
 | 
                         if (empty($this->allemail[$datum['email_id']])){
 | 
| 
 | 
 | 
                             $this->allemail[$datum['email_id']] = Email::_firstById($datum['email_id']);
 | 
| 
 | 
 | 
                         }
 | 
| 
 | 
 | 
                         if(empty($this->allemail[$datum['email_id']])){
 | 
| 
 | 
 | 
                             continue;
 | 
| 
 | 
 | 
                         }
 | 
| 
 | 
 | 
                         // 同步
 | 
| 
 | 
 | 
                         $id = $this->syncEmailList(
 | 
| 
 | 
 | 
                             [$datum['msgno']],
 | 
| 
 | 
 | 
                             $datum['email_id'],
 | 
| 
 | 
 | 
                             $this->allemail[$datum['email_id']]['email'],
 | 
| 
 | 
 | 
                             $datum['folder_id'],
 | 
| 
 | 
 | 
                             $this->folder
 | 
| 
 | 
 | 
                         );
 | 
| 
 | 
 | 
                         if($id['ids']){
 | 
| 
 | 
 | 
                             // 重新获取
 | 
| 
 | 
 | 
                             $result['data'][$k] = EmailList::_first($id['ids'][0]);
 | 
| 
 | 
 | 
                         }
 | 
| 
 | 
 | 
                     }
 | 
| 
 | 
 | 
                     // 干掉 -snv 和 (Failure)
 | 
| 
 | 
 | 
                     if(preg_match("/(\-\ssnv)|(\(Failure\))|(\(Delay\))$/",$datum['subject'])){
 | 
| 
 | 
 | 
                         unset($result['data'][$k]);
 | 
| 
 | 
 | 
                         continue;
 | 
| 
 | 
 | 
                     }
 | 
| 
 | 
 | 
                 }
 | 
| 
 | 
 | 
                 $result['data'] = array_values($result['data']);
 | 
| 
 | 
 | 
 //                }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
                 // 未读邮件数量
 | 
| 
 | 
 | 
                 $result['unseen'] = $unseen??0;
 | 
| 
 | 
 | 
                 break;
 | 
| 
 | 
 | 
             }
 | 
| 
 | 
 | 
             case 'mail': {
 | 
| 
 | 
 | 
                 $result =  $this->emails();
 | 
| 
 | 
 | 
                 break;
 | 
| 
 | 
 | 
             }
 | 
| 
 | 
 | 
             case 'add': {
 | 
| 
 | 
 | 
                 $result =  $this->emailAdd();
 | 
| 
 | 
 | 
                 break;
 | 
| 
 | 
 | 
             }
 | 
| 
 | 
 | 
             case 'folder': {
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
                 $email = $this->request->post('email');
 | 
| 
 | 
 | 
                 if($email){
 | 
| 
 | 
 | 
                     $ids = Email::_getIds($email);
 | 
| 
 | 
 | 
                 }else{
 | 
| 
 | 
 | 
                     $ids = $this->id;
 | 
| 
 | 
 | 
                 }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
                 $result = $this->folders($ids);
 | 
| 
 | 
 | 
                 break;
 | 
| 
 | 
 | 
             }
 | 
| 
 | 
 | 
             case 'contact': {
 | 
| 
 | 
 | 
                 switch ($action){
 | 
| 
 | 
 | 
                     case 'info': {
 | 
| 
 | 
 | 
                         $id =   $this->request->get('id');
 | 
| 
 | 
 | 
                         $result =  $this->contactInfo($id);
 | 
| 
 | 
 | 
                         break;
 | 
| 
 | 
 | 
                     }
 | 
| 
 | 
 | 
                     case 'add': {
 | 
| 
 | 
 | 
                         $result =  $this->contactAdd();
 | 
| 
 | 
 | 
                         break;
 | 
| 
 | 
 | 
                     }
 | 
| 
 | 
 | 
                     case 'del': {
 | 
| 
 | 
 | 
                         $result =  $this->contactDel();
 | 
| 
 | 
 | 
                         break;
 | 
| 
 | 
 | 
                     }
 | 
| 
 | 
 | 
                     case 'group':{
 | 
| 
 | 
 | 
                         $is_contact = $this->request->get('is_contact');
 | 
| 
 | 
 | 
                         $result =  $this->contactGroup($is_contact);
 | 
| 
 | 
 | 
                         break;
 | 
| 
 | 
 | 
                     }
 | 
| 
 | 
 | 
                     case 'group_save': {
 | 
| 
 | 
 | 
                         $name = $this->request->post('group_name');
 | 
| 
 | 
 | 
                         $id = $this->request->post('id',0);
 | 
| 
 | 
 | 
                         $result =   $this->contactGroupSave($name,$id);
 | 
| 
 | 
 | 
                         break;
 | 
| 
 | 
 | 
                     }
 | 
| 
 | 
 | 
                     case 'group_del': {
 | 
| 
 | 
 | 
                         $group_id = (int) $this->request->get('group_id');
 | 
| 
 | 
 | 
                         $result =   $this->contactGroupDel($group_id);
 | 
| 
 | 
 | 
                         break;
 | 
| 
 | 
 | 
                     }
 | 
| 
 | 
 | 
                     default: {
 | 
| 
 | 
 | 
                         $is_group = $this->request->get('is_group',false);
 | 
| 
 | 
 | 
                         $result =  $this->contact($is_group);
 | 
| 
 | 
 | 
                         break;
 | 
| 
 | 
 | 
                     }
 | 
| 
 | 
 | 
                 }
 | 
| 
 | 
 | 
                 break;
 | 
| 
 | 
 | 
             }
 | 
| 
 | 
 | 
             // 下载附件
 | 
| 
 | 
 | 
             case 'download':{
 | 
| 
 | 
 | 
                 $name = $this->request->get('name');
 | 
| 
 | 
 | 
                 $originname = $this->request->get('originname');
 | 
| 
 | 
 | 
                 return $this->download($name,$originname);
 | 
| 
 | 
 | 
             }
 | 
| 
 | 
 | 
             case 'contact_view':{
 | 
| 
 | 
 | 
                 return $this->contact_view();
 | 
| 
 | 
 | 
             }
 | 
| 
 | 
 | 
             // 发送邮件
 | 
| 
 | 
 | 
             case 'send_email':{
 | 
| 
 | 
 | 
                 $data = $this->request->post('to');
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
                 // 文件收件人
 | 
| 
 | 
 | 
                 $to = $this->request->file()['to']['to_email_file']??[];
 | 
| 
 | 
 | 
                 if($to && $to instanceof UploadedFile){
 | 
| 
 | 
 | 
                     $data['to'] = ($data['to']??'')."\n".$to->getContent();
 | 
| 
 | 
 | 
                 }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
                 // 附件
 | 
| 
 | 
 | 
                 $data['file'] = $this->request->file()['to']['file']??[];
 | 
| 
 | 
 | 
                 if($data['file']){
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
                     $upconfig = [
 | 
| 
 | 
 | 
                         // 上传文件的大小范围
 | 
| 
 | 
 | 
                         'size' => [
 | 
| 
 | 
 | 
                             'max' => 1024 * 1024 * 100,    // 100M大了服务器不知道会发生什么
 | 
| 
 | 
 | 
                             'min' => 1,                  // 0k
 | 
| 
 | 
 | 
                         ],
 | 
| 
 | 
 | 
                         // 扩展名
 | 
| 
 | 
 | 
                         'ext'  => [
 | 
| 
 | 
 | 
                             'xlsx', 'xltx', 'potx', 'ppsx', 'pptx', 'sldx', 'docx', 'dotx', 'xlam', 'xlsb',
 | 
| 
 | 
 | 
                             'apk', 'doc', 'pdf', 'xls', 'ppt', /*'jar', 'js', 'json', 'rpm',*/
 | 
| 
 | 
 | 
                             'swf', 'tar', 'zip', 'gif', 'png', 'flv', 'avi', 'ai', 'gz',
 | 
| 
 | 
 | 
                             'jpg', 'mov', 'mp3', 'mp4', 'txt', 'webm', 'webp',
 | 
| 
 | 
 | 
                         ],
 | 
| 
 | 
 | 
                         // mime类型
 | 
| 
 | 
 | 
                         'mime' => [
 | 
| 
 | 
 | 
                             /*'xlsx' => */'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
 | 
| 
 | 
 | 
                             /*'xltx' => */'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
 | 
| 
 | 
 | 
                             /*'potx' => */'application/vnd.openxmlformats-officedocument.presentationml.template',
 | 
| 
 | 
 | 
                             /*'ppsx' => */'application/vnd.openxmlformats-officedocument.presentationml.slideshow',
 | 
| 
 | 
 | 
                             /*'pptx' => */'application/vnd.openxmlformats-officedocument.presentationml.presentation',
 | 
| 
 | 
 | 
                             /*'sldx' => */'application/vnd.openxmlformats-officedocument.presentationml.slide',
 | 
| 
 | 
 | 
                             /*'docx' => */'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
 | 
| 
 | 
 | 
                             /*'dotx' => */'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
 | 
| 
 | 
 | 
                             /*'xlam' => */'application/vnd.ms-excel.addin.macroEnabled.12',
 | 
| 
 | 
 | 
                             /*'xlsb' => */'application/vnd.ms-excel.sheet.binary.macroEnabled.12',
 | 
| 
 | 
 | 
                             /*'apk' => */'application/vnd.android.package-archive',
 | 
| 
 | 
 | 
                             /*'doc' => */'application/msword',
 | 
| 
 | 
 | 
                             /*'pdf' => */'application/pdf',
 | 
| 
 | 
 | 
                             /*'xls' => */'application/vnd.ms-excel',
 | 
| 
 | 
 | 
                             /*'ppt' => */'application/vnd.ms-powerpoint',
 | 
| 
 | 
 | 
 //                            /*'jar' => */'application/java-archive',
 | 
| 
 | 
 | 
 //                            /*'js' => */'application/javascript',
 | 
| 
 | 
 | 
 //                            /*'json' => */'application/json',
 | 
| 
 | 
 | 
 //                            /*'rpm' => */'application/x-rpm',
 | 
| 
 | 
 | 
                             /*'swf' => */'application/x-shockwave-flash',
 | 
| 
 | 
 | 
                             /*'tar' => */'application/x-tar',
 | 
| 
 | 
 | 
                             /*'zip' => */'application/zip',
 | 
| 
 | 
 | 
                             /*'gif' => */'image/gif',
 | 
| 
 | 
 | 
                             /*'png' => */'image/png',
 | 
| 
 | 
 | 
                             /*'flv' => */'video/x-flv',
 | 
| 
 | 
 | 
                             /*'avi' => */'video/x-msvideo',
 | 
| 
 | 
 | 
                             /*'ai' => */'application/postscript',
 | 
| 
 | 
 | 
                             /*'gz' => */'application/x-gzip',
 | 
| 
 | 
 | 
                             /*'jpg' => */'image/jpeg',
 | 
| 
 | 
 | 
                             /*'mov' => */'video/quicktime',
 | 
| 
 | 
 | 
                             /*'mp3' => */'audio/mpeg',
 | 
| 
 | 
 | 
                             /*'mp4' => */'video/mp4',
 | 
| 
 | 
 | 
                             /*'txt' => */'text/plain',
 | 
| 
 | 
 | 
                             /*'webm' => */'video/webm',
 | 
| 
 | 
 | 
                             /*'webp' => */'image/webp',
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
                         ],
 | 
| 
 | 
 | 
                         // 磁盘
 | 
| 
 | 
 | 
                         'disk' => 'local2',
 | 
| 
 | 
 | 
                         // 目录
 | 
| 
 | 
 | 
                         'path' => '/email/'.$this->username.'/',
 | 
| 
 | 
 | 
                     ];
 | 
| 
 | 
 | 
                     // 设置配置
 | 
| 
 | 
 | 
                     Config::set('upload.email_upload',$upconfig);
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
                     foreach ($data['file'] as $k=>$file){
 | 
| 
 | 
 | 
                         if($file instanceof UploadedFile){
 | 
| 
 | 
 | 
                             $data['file'][$k]   =   [
 | 
| 
 | 
 | 
                                 'path'  =>  Upload::put($file,'email_upload'),
 | 
| 
 | 
 | 
                                 'origin_name'  =>  $file->getClientOriginalName(),
 | 
| 
 | 
 | 
                             ];
 | 
| 
 | 
 | 
                         }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
                     }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
                     // 保存的目录
 | 
| 
 | 
 | 
                     $path = config('filesystems.disks.local2.root');
 | 
| 
 | 
 | 
                     foreach ($data['file'] as &$f){
 | 
| 
 | 
 | 
                         $f['path'] = realpath($path.'/'.$f['path']);
 | 
| 
 | 
 | 
                     }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
                 }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
                 if($this->send($data)){
 | 
| 
 | 
 | 
                     return   $this->echoJson(1,'邮件发送成功');
 | 
| 
 | 
 | 
                 }
 | 
| 
 | 
 | 
             }
 | 
| 
 | 
 | 
         }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         return $this->echoJson($result);
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     /**
 | 
| 
 | 
 | 
      * 自动路由时
 | 
| 
 | 
 | 
      * @return array
 | 
| 
 | 
 | 
      * @time 2022/8/1 16:28
 | 
| 
 | 
 | 
      */
 | 
| 
 | 
 | 
     public function getRoute(){
 | 
| 
 | 
 | 
         return [
 | 
| 
 | 
 | 
             [
 | 
| 
 | 
 | 
                 'name'  =>  '同步文件夹',
 | 
| 
 | 
 | 
                 'route' =>  '?_task=sync&_action=folder'
 | 
| 
 | 
 | 
             ],
 | 
| 
 | 
 | 
             [
 | 
| 
 | 
 | 
                 'name'  =>  '同步邮件列表',
 | 
| 
 | 
 | 
                 'route' =>  '?_task=sync&_action=list'
 | 
| 
 | 
 | 
             ],
 | 
| 
 | 
 | 
             [
 | 
| 
 | 
 | 
                 'name'  =>  '邮件详情',
 | 
| 
 | 
 | 
                 'route' =>  '?_task=info&id=1972'
 | 
| 
 | 
 | 
             ],
 | 
| 
 | 
 | 
             [
 | 
| 
 | 
 | 
                 'name'  =>  '邮件列表',
 | 
| 
 | 
 | 
                 'route' =>  '?_task=list'
 | 
| 
 | 
 | 
             ],
 | 
| 
 | 
 | 
             [
 | 
| 
 | 
 | 
                 'name'  =>  '邮箱',
 | 
| 
 | 
 | 
                 'route' =>  '?_task=mail'
 | 
| 
 | 
 | 
             ],
 | 
| 
 | 
 | 
             [
 | 
| 
 | 
 | 
                 'name'  =>  '添加邮箱',
 | 
| 
 | 
 | 
                 'route' =>  '?_task=add'
 | 
| 
 | 
 | 
             ],
 | 
| 
 | 
 | 
             [
 | 
| 
 | 
 | 
                 'name'  =>  '邮箱联系人',
 | 
| 
 | 
 | 
                 'route' =>  '?_task=contact'
 | 
| 
 | 
 | 
             ],
 | 
| 
 | 
 | 
         ];
 | 
| 
 | 
 | 
     }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     /**
 | 
| 
 | 
 | 
      * 同步文件夹
 | 
| 
 | 
 | 
      * 缺点,远程修改文件名称后,同步回来,就会新建文件夹,会导致邮件混乱,
 | 
| 
 | 
 | 
      * 处理方法,删除本地的,重新同步该文件夹下面的所有邮件,虽然不友好,也只能这样做。
 | 
| 
 | 
 | 
      * @time 2022/8/1 16:09
 | 
| 
 | 
 | 
      */
 | 
| 
 | 
 | 
     public function syncFolder($folder=''){
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         // 同步单个文件夹
 | 
| 
 | 
 | 
         if($folder){
 | 
| 
 | 
 | 
             $status =   $this->client()->selectFolder($this->folder);
 | 
| 
 | 
 | 
             // 更新数量
 | 
| 
 | 
 | 
             EmailFolder::_updateNum($this->folderId,$status['EXISTS']??null, $status['UNSEEN']??null);
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
             return EmailFolder::_firstAndEmailId($this->folderId,$this->id);
 | 
| 
 | 
 | 
         }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         // 读取所有文件夹,未解密
 | 
| 
 | 
 | 
         $folders    =   $this->client()->getFolder();
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         DB::beginTransaction();
 | 
| 
 | 
 | 
         foreach ($folders as $folder){
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
             // 处理子父文件夹
 | 
| 
 | 
 | 
             $folder['id'] = explode('/',$folder['folder']);
 | 
| 
 | 
 | 
             $folder['name'] = explode('/',$folder['parseFolder']);
 | 
| 
 | 
 | 
             $pid = 0;
 | 
| 
 | 
 | 
             foreach ($folder['id'] as $k=>$item){
 | 
| 
 | 
 | 
                 // 插入到数据库
 | 
| 
 | 
 | 
                 $pid = EmailFolder::_insert(
 | 
| 
 | 
 | 
                     $this->user_id,
 | 
| 
 | 
 | 
                     $this->id,
 | 
| 
 | 
 | 
                     $folder['name'][$k],
 | 
| 
 | 
 | 
                     $item,
 | 
| 
 | 
 | 
                     $pid
 | 
| 
 | 
 | 
                 );
 | 
| 
 | 
 | 
             }
 | 
| 
 | 
 | 
         }
 | 
| 
 | 
 | 
         DB::commit();
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         return EmailFolder::_all($this->id);
 | 
| 
 | 
 | 
     }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     /**
 | 
| 
 | 
 | 
      * 同步当前用户的邮件数量
 | 
| 
 | 
 | 
      * @return array
 | 
| 
 | 
 | 
      * [surplus_num] 剩余待拉取数量
 | 
| 
 | 
 | 
      * [ids]    本次拉取后保存后的id
 | 
| 
 | 
 | 
      * @time 2022/8/2 14:06
 | 
| 
 | 
 | 
      */
 | 
| 
 | 
 | 
     public function syncEmailList($msgno=[],$use_email_id=0,$use_email='',$use_folder_id=0,$use_folder=''){
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         $use_email_id  =   $use_email_id ? : $this->id;
 | 
| 
 | 
 | 
         $use_email  =   $use_email ? : $this->username;
 | 
| 
 | 
 | 
         $use_folder_id  =   $use_folder_id ? : $this->folderId;
 | 
| 
 | 
 | 
         $use_folder  =   $use_folder ? : $this->folder;
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         // 零时增加时长
 | 
| 
 | 
 | 
 //        set_time_limit(180);
 | 
| 
 | 
 | 
         // 选择文件夹
 | 
| 
 | 
 | 
         $status =   $this->client($use_email)->selectFolder($use_folder);
 | 
| 
 | 
 | 
         if (!isset($status['EXISTS']) || !$status['EXISTS']){
 | 
| 
 | 
 | 
             return [
 | 
| 
 | 
 | 
                 'ids'   =>  [],
 | 
| 
 | 
 | 
                 'folder'   =>  $status,
 | 
| 
 | 
 | 
                 'end'   =>  true
 | 
| 
 | 
 | 
             ];
 | 
| 
 | 
 | 
         }
 | 
| 
 | 
 | 
         $end = false;
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         if($msgno){
 | 
| 
 | 
 | 
             goto SYNCEMAILLIST;
 | 
| 
 | 
 | 
         }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         // 最后拉取的时间,如果是第一次
 | 
| 
 | 
 | 
         $lastMsgno   =   EmailList::_lastMsgno($use_email_id, $use_folder_id);
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         $nu = 20;
 | 
| 
 | 
 | 
         if(!$msgno){
 | 
| 
 | 
 | 
             if(!$lastMsgno){
 | 
| 
 | 
 | 
                 $msgno = range(1,$nu);
 | 
| 
 | 
 | 
             }else{
 | 
| 
 | 
 | 
                 $msgno = range($lastMsgno,$lastMsgno+$nu);
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
                 if($lastMsgno > $status['EXISTS']){
 | 
| 
 | 
 | 
                     $msgno = range($status['EXISTS'] > $nu ? $status['EXISTS'] - $nu : 1,$status['EXISTS']);
 | 
| 
 | 
 | 
                 }
 | 
| 
 | 
 | 
                 // 一样就不拉新的
 | 
| 
 | 
 | 
                 if($lastMsgno == $status['EXISTS']){
 | 
| 
 | 
 | 
                     return [
 | 
| 
 | 
 | 
                         'ids'   =>  [],
 | 
| 
 | 
 | 
                         'folder'   =>  $status,
 | 
| 
 | 
 | 
                         'end'   =>  true,
 | 
| 
 | 
 | 
                     ];
 | 
| 
 | 
 | 
                 }
 | 
| 
 | 
 | 
             }
 | 
| 
 | 
 | 
         }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         // 更新数量
 | 
| 
 | 
 | 
         EmailFolder::_updateNum($use_folder_id,$status['EXISTS'], $status['UNSEEN']??null);
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         // 说明是第一次
 | 
| 
 | 
 | 
         if(!$lastMsgno){
 | 
| 
 | 
 | 
             $pgnu = 1000;
 | 
| 
 | 
 | 
             DB::beginTransaction();
 | 
| 
 | 
 | 
             for ($n=0;$n<$status['EXISTS']/$pgnu;$n++){
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
                 $i = ($pgnu*$n)+1;
 | 
| 
 | 
 | 
                 $max = $i+$pgnu;
 | 
| 
 | 
 | 
                 $max = $max > $status['EXISTS'] ? $status['EXISTS']+1 : $max;
 | 
| 
 | 
 | 
                 $sql = [];
 | 
| 
 | 
 | 
                 while ($i<$max){
 | 
| 
 | 
 | 
                     $sql[] = "(".$use_email_id.",{$i},".$use_folder_id.",1)";
 | 
| 
 | 
 | 
                     $i++;
 | 
| 
 | 
 | 
                 }
 | 
| 
 | 
 | 
 //                bug 使用事务,无法插入数据
 | 
| 
 | 
 | 
                 $ret = DB::insert("insert INTO email_lists (`email_id`,`msgno`,`folder_id`,`seen`) VALUES ".implode(',',$sql));
 | 
| 
 | 
 | 
                 if(!$ret){
 | 
| 
 | 
 | 
                     DB::rollBack();
 | 
| 
 | 
 | 
                     abort(500,'同步失败');
 | 
| 
 | 
 | 
                 }
 | 
| 
 | 
 | 
             }
 | 
| 
 | 
 | 
             DB::commit();
 | 
| 
 | 
 | 
             // 最新的数量
 | 
| 
 | 
 | 
             $msgno = range($status['EXISTS'] > $nu ? $status['EXISTS'] - $nu : 1,$status['EXISTS']);
 | 
| 
 | 
 | 
             // 不同步
 | 
| 
 | 
 | 
             return [
 | 
| 
 | 
 | 
                 'ids'   =>  [1],
 | 
| 
 | 
 | 
                 'folder'   =>  $status,
 | 
| 
 | 
 | 
                 'end'   =>  $end,
 | 
| 
 | 
 | 
             ];
 | 
| 
 | 
 | 
         }
 | 
| 
 | 
 | 
         SYNCEMAILLIST:
 | 
| 
 | 
 | 
         // 是否有id
 | 
| 
 | 
 | 
         $dataids = EmailList::_getIdsByMsgno($use_email_id,$use_folder_id,$msgno);
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         $this->client($use_email)->debug(false,storage_path('logs'));
 | 
| 
 | 
 | 
         // 循环
 | 
| 
 | 
 | 
         $results = $this->client($use_email)->fetchHeader($msgno);
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         if($results){
 | 
| 
 | 
 | 
             DB::beginTransaction();
 | 
| 
 | 
 | 
             // 批量插入
 | 
| 
 | 
 | 
             foreach ($results as $key=>$result){
 | 
| 
 | 
 | 
                 if($key == $status['EXISTS']){
 | 
| 
 | 
 | 
                     $end = true;
 | 
| 
 | 
 | 
                 }
 | 
| 
 | 
 | 
 //                $header = $this->client($use_email)->getHeader($result['RFC822.HEADER']??'');
 | 
| 
 | 
 | 
                 $header = &$result['HEADER.FIELDS'];
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
                 foreach ($result['FLAGS'] as $k=>$FLAG){
 | 
| 
 | 
 | 
                     $result['FLAGS'][$k] = strtolower(str_replace('\\','',$FLAG));
 | 
| 
 | 
 | 
                 }
 | 
| 
 | 
 | 
                 try {
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
                     $file_header = &$result['BODYSTRUCTURE'];
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
                     // 没有收件人
 | 
| 
 | 
 | 
                     if(!empty($header['To'])){
 | 
| 
 | 
 | 
                         $header['To'] = MailFun::toOrFrom($header['To']);
 | 
| 
 | 
 | 
                     }else{
 | 
| 
 | 
 | 
                         $header['To'] = [];
 | 
| 
 | 
 | 
                     }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
                     $header['From'] = MailFun::toOrFrom($header['From']);
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
                     $data   =   [
 | 
| 
 | 
 | 
                         'id'    =>  $dataids[$key]??0,
 | 
| 
 | 
 | 
                         'msgno'   =>  $key,
 | 
| 
 | 
 | 
                         'uid'   =>  $result['UID'],
 | 
| 
 | 
 | 
                         'subject'   =>  $header['Subject'],
 | 
| 
 | 
 | 
 //                        'cc'    =>  $header['Cc']??'',
 | 
| 
 | 
 | 
                         'from'   =>  $header['From'][0]['email']??'',
 | 
| 
 | 
 | 
                         'from_name'   =>  $header['From'][0]['name']??'',
 | 
| 
 | 
 | 
                         'to'   =>  $header['To']?implode(',',array_column($header['To'],'email')):'',
 | 
| 
 | 
 | 
                         'to_name'   =>  json_encode($header['To']),
 | 
| 
 | 
 | 
                         'date'   =>  isset($header['Date'])&&$header['Date'] ? strtotime(is_array($header['Date']) ? $header['Date'][0] : $header['Date']) : strtotime($result['INTERNALDATE']),
 | 
| 
 | 
 | 
                         'message_id'   =>  $header['Message-ID']??'',
 | 
| 
 | 
 | 
                         'udate'   =>  strtotime($result['INTERNALDATE']),
 | 
| 
 | 
 | 
 //                      'size'   =>  $result['RFC822.SIZE'],
 | 
| 
 | 
 | 
                         'recent'   =>  in_array('recent',$result['FLAGS']),
 | 
| 
 | 
 | 
                         'seen'   =>  in_array('seen',$result['FLAGS']),
 | 
| 
 | 
 | 
                         'draft'   =>  in_array('draft',$result['FLAGS']),
 | 
| 
 | 
 | 
                         'flagged'   =>  in_array('flagged',$result['FLAGS']),
 | 
| 
 | 
 | 
                         'answered'   =>  in_array('answered',$result['FLAGS']),
 | 
| 
 | 
 | 
                         'folder_id'   =>  $use_folder_id,
 | 
| 
 | 
 | 
                         'email_id'    =>  $use_email_id,
 | 
| 
 | 
 | 
                         'uuid'  =>  $use_email_id.$use_folder_id.$result['UID'],
 | 
| 
 | 
 | 
                         'is_file'  =>  MailFun::isFile($file_header[$key]['BODYSTRUCTURE']??[]) //是否附件
 | 
| 
 | 
 | 
                     ];
 | 
| 
 | 
 | 
                 }catch (\Throwable $e){
 | 
| 
 | 
 | 
                     Log::error('邮件解析失败:'.$e->getMessage().print_r($result,true));
 | 
| 
 | 
 | 
                     unset($results[$key]);
 | 
| 
 | 
 | 
                     continue;
 | 
| 
 | 
 | 
                 }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
                 $results[$key]  =   $data;
 | 
| 
 | 
 | 
             }
 | 
| 
 | 
 | 
             $ids = EmailList::_insertAll(array_values($results));
 | 
| 
 | 
 | 
             // 提交
 | 
| 
 | 
 | 
             DB::commit();
 | 
| 
 | 
 | 
         }else{
 | 
| 
 | 
 | 
             $end = true;
 | 
| 
 | 
 | 
         }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         return [
 | 
| 
 | 
 | 
             'ids'   =>  $ids??[],
 | 
| 
 | 
 | 
             'folder'   =>  $status,
 | 
| 
 | 
 | 
             'end'   =>  $end,
 | 
| 
 | 
 | 
         ];
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     /**
 | 
| 
 | 
 | 
      * 同步body
 | 
| 
 | 
 | 
      * @param int $uid
 | 
| 
 | 
 | 
      * @param int $id
 | 
| 
 | 
 | 
      * @return mixed
 | 
| 
 | 
 | 
      * @time 2022/8/2 15:11
 | 
| 
 | 
 | 
      */
 | 
| 
 | 
 | 
     public function syncEMailBody(int $uid, $id = 0 ){
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 //        $this->client()->debug(true,storage_path('logs'));
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         $this->client()->selectFolder($this->folder);
 | 
| 
 | 
 | 
         $body = $this->client()->fetch([$uid],'body',true);
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         /******* start ********/
 | 
| 
 | 
 | 
         // 记录原始数据,方便分析
 | 
| 
 | 
 | 
         $path = storage_path('logs/email/'.$this->username.'/');
 | 
| 
 | 
 | 
         if(!is_dir($path)){
 | 
| 
 | 
 | 
             mkdir($path,0775,true);
 | 
| 
 | 
 | 
         }
 | 
| 
 | 
 | 
         file_put_contents($path.$id.'.'.time().'.log',print_r($body,true));
 | 
| 
 | 
 | 
         /******** end *******/
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         if($body && $id){
 | 
| 
 | 
 | 
             $body = array_values($body);
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
             $body = (new Body($body[0]['RFC822.TEXT'],$this->getFilePath()))->getItem();
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
             EmailBody::_insert(
 | 
| 
 | 
 | 
                 $id,
 | 
| 
 | 
 | 
                 $body
 | 
| 
 | 
 | 
             );
 | 
| 
 | 
 | 
         }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         return EmailBody::_first($id);
 | 
| 
 | 
 | 
     }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     /**
 | 
| 
 | 
 | 
      * 设置标记
 | 
| 
 | 
 | 
      * @param array $uids
 | 
| 
 | 
 | 
      * @param string $flags
 | 
| 
 | 
 | 
      * @param string $mod +|-
 | 
| 
 | 
 | 
      * @return bool
 | 
| 
 | 
 | 
      * @throws \Exception
 | 
| 
 | 
 | 
      * @author:dc
 | 
| 
 | 
 | 
      * @time 2022/10/27 14:22
 | 
| 
 | 
 | 
      */
 | 
| 
 | 
 | 
     public function setflagged(array $uids,string $flags,string $mod){
 | 
| 
 | 
 | 
         // 选择目录
 | 
| 
 | 
 | 
         $status =   $this->client()->selectFolder($this->folder);
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         return $this->client()->flags($uids,[$flags],$mod,true);
 | 
| 
 | 
 | 
     }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     /**
 | 
| 
 | 
 | 
      * 设置为已读
 | 
| 
 | 
 | 
      * @param int|array $uids
 | 
| 
 | 
 | 
      * @return bool
 | 
| 
 | 
 | 
      * @throws \Exception
 | 
| 
 | 
 | 
      * @author:dc
 | 
| 
 | 
 | 
      * @time 2022/10/26 17:08
 | 
| 
 | 
 | 
      */
 | 
| 
 | 
 | 
     public function setSeen($uids):bool{
 | 
| 
 | 
 | 
         // 选择目录
 | 
| 
 | 
 | 
         $status =   $this->client()->selectFolder($this->folder);
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         return $this->client()->flags($uids,[\App\Http\Mail\lib\client\Imap::FLAGS_SEEN],'+',true);
 | 
| 
 | 
 | 
     }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     /**
 | 
| 
 | 
 | 
      * 设置为未读
 | 
| 
 | 
 | 
      * @param $uids
 | 
| 
 | 
 | 
      * @return bool
 | 
| 
 | 
 | 
      * @throws \Exception
 | 
| 
 | 
 | 
      * @author:dc
 | 
| 
 | 
 | 
      * @time 2022/10/26 17:11
 | 
| 
 | 
 | 
      */
 | 
| 
 | 
 | 
     public function delSeen($uids):bool{
 | 
| 
 | 
 | 
         // 选择目录
 | 
| 
 | 
 | 
         $status =   $this->client()->selectFolder($this->folder);
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         return $this->client()->flags($uids,[\App\Http\Mail\lib\client\Imap::FLAGS_SEEN],'-',true);
 | 
| 
 | 
 | 
     }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     /**
 | 
| 
 | 
 | 
      * 邮件列表
 | 
| 
 | 
 | 
      * @param array $mail_id
 | 
| 
 | 
 | 
      * @param array $folder
 | 
| 
 | 
 | 
      * @param int $total
 | 
| 
 | 
 | 
      * @return mixed|object
 | 
| 
 | 
 | 
      * @throws \Illuminate\Contracts\Container\BindingResolutionException
 | 
| 
 | 
 | 
      * @time 2022/8/16 17:34
 | 
| 
 | 
 | 
      */
 | 
| 
 | 
 | 
     public function emailLists($mail_id = [], $folder = [], $total = 0, $search = []){
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         return EmailList::_paginate(function ($query) use ($mail_id, $folder,$search){
 | 
| 
 | 
 | 
             $query->whereIn('email_id',$mail_id)->whereIn('folder_id',$folder);
 | 
| 
 | 
 | 
             // 搜索
 | 
| 
 | 
 | 
             if(!empty($search['search'])){
 | 
| 
 | 
 | 
                 $search = htmlspecialchars($search);
 | 
| 
 | 
 | 
                 $query->where('subject','like',"%{$search}%");
 | 
| 
 | 
 | 
             }
 | 
| 
 | 
 | 
             // 已读
 | 
| 
 | 
 | 
             if(!empty($search['seen']) && $search['seen']){
 | 
| 
 | 
 | 
                 $query->where('seen',0);
 | 
| 
 | 
 | 
             }
 | 
| 
 | 
 | 
             // 过滤
 | 
| 
 | 
 | 
             $query->where([
 | 
| 
 | 
 | 
                 ['subject','not like','%- snv'],
 | 
| 
 | 
 | 
                 ['subject','not like','%(Failure)'],
 | 
| 
 | 
 | 
                 ['subject','not like','%(Delay)']
 | 
| 
 | 
 | 
             ]);
 | 
| 
 | 
 | 
         },20,$total);
 | 
| 
 | 
 | 
     }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     /**
 | 
| 
 | 
 | 
      * 读取邮件详情
 | 
| 
 | 
 | 
      * @param $id
 | 
| 
 | 
 | 
      * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|object|null
 | 
| 
 | 
 | 
      * @time 2022/8/2 15:13
 | 
| 
 | 
 | 
      */
 | 
| 
 | 
 | 
     public function emailInfo($id){
 | 
| 
 | 
 | 
         $email = EmailList::_firstWithBody($id);
 | 
| 
 | 
 | 
         // 是否存在,并且是否属于自己
 | 
| 
 | 
 | 
         if($email && in_array($email->email_id,$this->email_ids)){
 | 
| 
 | 
 | 
             if(!$email->body && $email['uid']){
 | 
| 
 | 
 | 
                 $email = $email->toArray();
 | 
| 
 | 
 | 
                 try {
 | 
| 
 | 
 | 
                     $email['body']   =   $this->syncEMailBody($email['uid'],$email['id']);
 | 
| 
 | 
 | 
                 }catch (\Throwable $e){
 | 
| 
 | 
 | 
                     $email['body']   =   $this->syncEMailBody($email['uid'],$email['id']);
 | 
| 
 | 
 | 
                 }
 | 
| 
 | 
 | 
             }
 | 
| 
 | 
 | 
             return $email;
 | 
| 
 | 
 | 
         }
 | 
| 
 | 
 | 
         return null;
 | 
| 
 | 
 | 
     }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     /**
 | 
| 
 | 
 | 
      * 获取邮件服务器
 | 
| 
 | 
 | 
      * @param string $suffix
 | 
| 
 | 
 | 
      * @return array
 | 
| 
 | 
 | 
      * @time 2022/7/29 16:24
 | 
| 
 | 
 | 
      */
 | 
| 
 | 
 | 
     public function host(string $suffix=''):array {
 | 
| 
 | 
 | 
         if($suffix){
 | 
| 
 | 
 | 
             return EmailHost::_get($suffix);
 | 
| 
 | 
 | 
         }
 | 
| 
 | 
 | 
         return EmailHost::_all();
 | 
| 
 | 
 | 
     }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     /**
 | 
| 
 | 
 | 
      * 获取自己的服务器地址
 | 
| 
 | 
 | 
      * @param null $name
 | 
| 
 | 
 | 
      * @return array|mixed|string
 | 
| 
 | 
 | 
      * @time 2022/8/1 15:46
 | 
| 
 | 
 | 
      */
 | 
| 
 | 
 | 
     public function hostMy($name=null) {
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 //        if(!$this->host){
 | 
| 
 | 
 | 
 //            $data = Email::_first($this->id);
 | 
| 
 | 
 | 
 //            $this->host = [
 | 
| 
 | 
 | 
 //                'imap'  =>  $data['imap'],
 | 
| 
 | 
 | 
 //                'smtp'  =>  $data['smtp'],
 | 
| 
 | 
 | 
 //            ];
 | 
| 
 | 
 | 
 //        }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         if($name){
 | 
| 
 | 
 | 
             return $this->host[$name]??'';
 | 
| 
 | 
 | 
         }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         return $this->host;
 | 
| 
 | 
 | 
     }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     /**
 | 
| 
 | 
 | 
      * 添加邮件服务器
 | 
| 
 | 
 | 
      * @param string $suffix
 | 
| 
 | 
 | 
      * @param string $imap
 | 
| 
 | 
 | 
      * @param string $smtp
 | 
| 
 | 
 | 
      * @return int email host 表的id
 | 
| 
 | 
 | 
      * @time 2022/7/29 16:28
 | 
| 
 | 
 | 
      */
 | 
| 
 | 
 | 
     public function hostAdd(string $suffix, string $imap, string $smtp):int{
 | 
| 
 | 
 | 
         return EmailHost::_insert($suffix, $imap, $smtp);
 | 
| 
 | 
 | 
     }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     /**
 | 
| 
 | 
 | 
      * 添加一个邮箱地址
 | 
| 
 | 
 | 
      * @time 2022/7/29 16:51
 | 
| 
 | 
 | 
      */
 | 
| 
 | 
 | 
     public function emailAdd($data=[]){
 | 
| 
 | 
 | 
         $data = $data ? $data : $this->request->post();
 | 
| 
 | 
 | 
         if(!$data){
 | 
| 
 | 
 | 
             throw new \Exception(Lang::__('empty_form'));
 | 
| 
 | 
 | 
         }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         $validator = Validator::make($data,[
 | 
| 
 | 
 | 
             'email' =>  ['required','email'],
 | 
| 
 | 
 | 
             'password'  =>  ['required'],
 | 
| 
 | 
 | 
         ],[
 | 
| 
 | 
 | 
             'email.required' =>  'email_required',
 | 
| 
 | 
 | 
             'email.email' =>  'email_validator',
 | 
| 
 | 
 | 
             'password.required' =>  'password_required',
 | 
| 
 | 
 | 
         ]);
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         if($validator->fails()){
 | 
| 
 | 
 | 
             throw new \Exception(Lang::__($validator->errors()->first()));
 | 
| 
 | 
 | 
         }
 | 
| 
 | 
 | 
         $data['email'] = trim($data['email']);
 | 
| 
 | 
 | 
         $data['password'] = trim($data['password']);
 | 
| 
 | 
 | 
         $data['email_name'] = trim($data['email_name']??$data['email']);
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         // 检查imap服务器
 | 
| 
 | 
 | 
         if($data['host']??''){
 | 
| 
 | 
 | 
             $host = [
 | 
| 
 | 
 | 
                 'imap'  =>  trim($data['host']),
 | 
| 
 | 
 | 
                 'smtp'  =>  trim($data['smtp']??'')
 | 
| 
 | 
 | 
             ];
 | 
| 
 | 
 | 
         }else{
 | 
| 
 | 
 | 
             // 获取数据库中有的
 | 
| 
 | 
 | 
             $host = $this->host(explode('@',$data['email'])[1]);
 | 
| 
 | 
 | 
         }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         if(!$host){
 | 
| 
 | 
 | 
             // 是否存在imap服务器
 | 
| 
 | 
 | 
             throw new \Exception(Lang::__('host_required'));
 | 
| 
 | 
 | 
         }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         // 登录名
 | 
| 
 | 
 | 
         $this->username = $data['email'];
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         // 进行远程登录
 | 
| 
 | 
 | 
         // imap imap.qq.com
 | 
| 
 | 
 | 
         $imap = new \App\Http\Mail\lib\client\Imap();
 | 
| 
 | 
 | 
         $imap->login($this->ssl.$host['imap'].':'.$this->port,$data['email'],$data['password']);
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         // 添加邮箱,并绑定user_id
 | 
| 
 | 
 | 
         $model = Email::_add($this->user_id, $data['email'], $data['password'], $data['email_name'],$host);
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         try {
 | 
| 
 | 
 | 
             // 添加一个联系人的默认分组
 | 
| 
 | 
 | 
             $this->contactGroupSave('默认分组');
 | 
| 
 | 
 | 
         }catch (\Throwable $e){
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         // 退出imap登录
 | 
| 
 | 
 | 
         $imap->loginOut();
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         return $model;
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 //        throw new \Exception(Lang::__('email_insert_error'));
 | 
| 
 | 
 | 
     }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     /**
 | 
| 
 | 
 | 
      * 读取所有邮箱
 | 
| 
 | 
 | 
      * @return array
 | 
| 
 | 
 | 
      * @time 2022/8/1 9:34
 | 
| 
 | 
 | 
      */
 | 
| 
 | 
 | 
     public function emails():array {
 | 
| 
 | 
 | 
         return Email::_get($this->user_id);
 | 
| 
 | 
 | 
     }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     /**
 | 
| 
 | 
 | 
      * 文件夹
 | 
| 
 | 
 | 
      * @return array
 | 
| 
 | 
 | 
      * @time 2022/8/4 17:34
 | 
| 
 | 
 | 
      */
 | 
| 
 | 
 | 
     public function folders($id){
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         $result = EmailFolder::_all($id);
 | 
| 
 | 
 | 
         if(!$result){
 | 
| 
 | 
 | 
             $result = $this->syncFolder();
 | 
| 
 | 
 | 
         }
 | 
| 
 | 
 | 
         return $result;
 | 
| 
 | 
 | 
     }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     /**
 | 
| 
 | 
 | 
      * 联系人列表
 | 
| 
 | 
 | 
      * @return mixed
 | 
| 
 | 
 | 
      * @time 2022/8/4 9:05
 | 
| 
 | 
 | 
      */
 | 
| 
 | 
 | 
     public function contact($is_group=false){
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         return EmailContact::_all($this->id,$is_group);
 | 
| 
 | 
 | 
     }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     /**
 | 
| 
 | 
 | 
      * 联系人管理视图
 | 
| 
 | 
 | 
      * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\View\View
 | 
| 
 | 
 | 
      * @author:dc
 | 
| 
 | 
 | 
      * @time 2022/11/2 16:37
 | 
| 
 | 
 | 
      */
 | 
| 
 | 
 | 
     public function contact_view(){
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         return view('admin/email/contacts',[
 | 
| 
 | 
 | 
 //            'emails'    =>  $this->emails(),
 | 
| 
 | 
 | 
             'email'  =>  $this->username,
 | 
| 
 | 
 | 
 //            'groups'  =>  $this->contactGroup(),
 | 
| 
 | 
 | 
 //            'contacts'  =>  $this->contact()
 | 
| 
 | 
 | 
         ]);
 | 
| 
 | 
 | 
     }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     /**
 | 
| 
 | 
 | 
      * 添加联系人
 | 
| 
 | 
 | 
      * @return EmailContact
 | 
| 
 | 
 | 
      * @throws \Exception
 | 
| 
 | 
 | 
      * @time 2022/8/4 9:46
 | 
| 
 | 
 | 
      */
 | 
| 
 | 
 | 
     public function contactAdd(){
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         $data = $this->request->post();
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         $validator = Validator::make($data,[
 | 
| 
 | 
 | 
             'group_id' =>  ['required'],
 | 
| 
 | 
 | 
             'email' =>  ['required','email'],
 | 
| 
 | 
 | 
             'email_name' =>  ['required','max:100'],
 | 
| 
 | 
 | 
             'remark' =>  ['max:200'],
 | 
| 
 | 
 | 
         ],[
 | 
| 
 | 
 | 
             'group_id.required'        =>  'contact_group_exists',
 | 
| 
 | 
 | 
             'email.required'        =>  'contact_email_required',
 | 
| 
 | 
 | 
             'email.email'           =>  'contact_email_error',
 | 
| 
 | 
 | 
             'email_name.required'   =>  'contact_email_name_required',
 | 
| 
 | 
 | 
             'email_name.max'        =>  'contact_email_name_max',
 | 
| 
 | 
 | 
             'remark.max'        =>  'contact_remark_max',
 | 
| 
 | 
 | 
         ]);
 | 
| 
 | 
 | 
         // 验证数据
 | 
| 
 | 
 | 
         if($validator->fails()){
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
             $p = '';
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
             switch ($validator->errors()->first()){
 | 
| 
 | 
 | 
                 case 'contact_email_name_max': $p = '100';break;
 | 
| 
 | 
 | 
                 case 'contact_remark_max': $p = '200';break;
 | 
| 
 | 
 | 
             }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
             throw new \Exception(
 | 
| 
 | 
 | 
                 Lang::__(
 | 
| 
 | 
 | 
                     $validator->errors()->first(),
 | 
| 
 | 
 | 
                     $p
 | 
| 
 | 
 | 
                 )
 | 
| 
 | 
 | 
             );
 | 
| 
 | 
 | 
         }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         $group = EmailContactGroup::_first($data['group_id']);
 | 
| 
 | 
 | 
         if(!$group || $group['email_id']!=$this->id){
 | 
| 
 | 
 | 
             abort(600,Lang::__('contact_group_exists'));
 | 
| 
 | 
 | 
         }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         return EmailContact::_save($this->id,$data);
 | 
| 
 | 
 | 
     }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     /**
 | 
| 
 | 
 | 
      * 联系人详情
 | 
| 
 | 
 | 
      * @param $id
 | 
| 
 | 
 | 
      * @return array
 | 
| 
 | 
 | 
      * @author:dc
 | 
| 
 | 
 | 
      * @time 2022/11/4 17:02
 | 
| 
 | 
 | 
      */
 | 
| 
 | 
 | 
     public function contactInfo($id){
 | 
| 
 | 
 | 
         return EmailContact::_first($this->id,$id);
 | 
| 
 | 
 | 
     }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     /**
 | 
| 
 | 
 | 
      * 删除联系人
 | 
| 
 | 
 | 
      * @time 2022/8/4 9:52
 | 
| 
 | 
 | 
      */
 | 
| 
 | 
 | 
     public function contactDel(){
 | 
| 
 | 
 | 
         $contact_id = (int) $this->request->get('contact_id');
 | 
| 
 | 
 | 
         if(!$contact_id || EmailContact::_del($this->id,$contact_id)){
 | 
| 
 | 
 | 
             abort(600,Lang::__('del_error'));
 | 
| 
 | 
 | 
         }
 | 
| 
 | 
 | 
         return true;
 | 
| 
 | 
 | 
     }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     /**
 | 
| 
 | 
 | 
      * 联系人分组
 | 
| 
 | 
 | 
      * @return mixed
 | 
| 
 | 
 | 
      * @time 2022/8/4 10:13
 | 
| 
 | 
 | 
      */
 | 
| 
 | 
 | 
     public function contactGroup($is_contact=false){
 | 
| 
 | 
 | 
         return EmailContactGroup::_all($this->id,$is_contact);
 | 
| 
 | 
 | 
     }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     /**
 | 
| 
 | 
 | 
      * 添加联系人分组
 | 
| 
 | 
 | 
      * @return EmailContactGroup
 | 
| 
 | 
 | 
      * @throws \Exception
 | 
| 
 | 
 | 
      * @time 2022/8/4 10:47
 | 
| 
 | 
 | 
      */
 | 
| 
 | 
 | 
     public function contactGroupSave($name,$id=0){
 | 
| 
 | 
 | 
         if(!$name || mb_strlen($name)>100){
 | 
| 
 | 
 | 
             throw new \Exception(Lang::__('contact_group_name_error',1,100));
 | 
| 
 | 
 | 
         }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         $name = htmlspecialchars($name);
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         $data = EmailContactGroup::_firstByName($this->id,$name);
 | 
| 
 | 
 | 
         if(($data && !$id) || ($data && $id && $data['id'] != $id)){
 | 
| 
 | 
 | 
             throw new \Exception(Lang::__('contact_group_name_unique'));
 | 
| 
 | 
 | 
         }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         return EmailContactGroup::_save($this->id,$name,$id);
 | 
| 
 | 
 | 
     }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     /**
 | 
| 
 | 
 | 
      * 删除
 | 
| 
 | 
 | 
      * @return false|mixed
 | 
| 
 | 
 | 
      * @time 2022/8/4 10:49
 | 
| 
 | 
 | 
      */
 | 
| 
 | 
 | 
     public function contactGroupDel($group_id){
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         if(!$group_id){
 | 
| 
 | 
 | 
             GROUP_DEL_ABORT:
 | 
| 
 | 
 | 
             abort(600,Lang::__('contact_group_del_id'));
 | 
| 
 | 
 | 
         }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         // 是否有联系人在其中
 | 
| 
 | 
 | 
         if(EmailContact::_count($group_id, $this->id)){
 | 
| 
 | 
 | 
             abort(600,Lang::__('contact_group_del_contact'));
 | 
| 
 | 
 | 
         }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         // 删除
 | 
| 
 | 
 | 
         if(!EmailContactGroup::_del($group_id, $this->id)){
 | 
| 
 | 
 | 
             goto GROUP_DEL_ABORT;
 | 
| 
 | 
 | 
         }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         return true;
 | 
| 
 | 
 | 
     }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     /**
 | 
| 
 | 
 | 
      * 发送邮件
 | 
| 
 | 
 | 
      * @time 2022/8/3 16:08
 | 
| 
 | 
 | 
      */
 | 
| 
 | 
 | 
     public function send($data=[]){
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         $data = $data ? $data : $this->request->post();
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         $data['is_text']    =   intval($data['is_text']??0);//纯文本
 | 
| 
 | 
 | 
 //        $data['save_send']    =   intval($data['save_send']??0);//保存到已发送
 | 
| 
 | 
 | 
         $data['priority']    =   intval($data['priority']??0);//紧急
 | 
| 
 | 
 | 
         $data['receipt']    =   intval($data['receipt']??0);//需要回执
 | 
| 
 | 
 | 
         $data['encrypt']    =   intval($data['encrypt']??0);//加密邮件
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         // 是纯文本还是html
 | 
| 
 | 
 | 
         $data['body']   =   $data['is_text'] ? ($data['text']??'') : ($data['html']??'');
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 //        是否是回复邮件
 | 
| 
 | 
 | 
         if(!empty($data['reply']['id']) && !empty($data['reply']['email_id'])){
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
             // 标题,主题
 | 
| 
 | 
 | 
             if(empty($data['subject'])){
 | 
| 
 | 
 | 
                 throw new \Exception(Lang::__('send_email_subject_error',500));
 | 
| 
 | 
 | 
             }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
             // 查询
 | 
| 
 | 
 | 
             $originData =   EmailList::_first($data['reply']['id']);
 | 
| 
 | 
 | 
             // 是否存在邮件
 | 
| 
 | 
 | 
             if($originData && $originData['email_id'] == $data['reply']['email_id'] && in_array($originData['email_id'],$this->email_ids)){
 | 
| 
 | 
 | 
                 $emaildata = Email::_firstById($originData['email_id']);
 | 
| 
 | 
 | 
                 if(!$emaildata){
 | 
| 
 | 
 | 
                     throw new \Exception('发件人异常',600);
 | 
| 
 | 
 | 
                 }
 | 
| 
 | 
 | 
                 try {
 | 
| 
 | 
 | 
                     // 立刻发送邮件
 | 
| 
 | 
 | 
                     MailFun::sendEmail(
 | 
| 
 | 
 | 
                         $emaildata['smtp'],$emaildata['email'],$emaildata['password'],
 | 
| 
 | 
 | 
                         $emaildata['email_name'],['email'=>$originData['from'],'name'=>$originData['from_name']]
 | 
| 
 | 
 | 
                         ,$data['subject'],$data['body'],$data['file']??[],$data['receipt'],$data['priority']?1:3
 | 
| 
 | 
 | 
                     );
 | 
| 
 | 
 | 
                     // 记录下
 | 
| 
 | 
 | 
                     EmailLog::error(print_r([
 | 
| 
 | 
 | 
                         'manage_id'=>the_manage('id'),
 | 
| 
 | 
 | 
                         'data'  =>  $data,
 | 
| 
 | 
 | 
                         '回复邮件'
 | 
| 
 | 
 | 
                     ],true));
 | 
| 
 | 
 | 
                     return true;
 | 
| 
 | 
 | 
                 }catch (\Throwable $e){
 | 
| 
 | 
 | 
                     throw new \Exception($e->getMessage());
 | 
| 
 | 
 | 
                 }
 | 
| 
 | 
 | 
             }
 | 
| 
 | 
 | 
         }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         // 收件人
 | 
| 
 | 
 | 
         if(empty($data['to'])){
 | 
| 
 | 
 | 
             SEND_EMAIL_TO_ERROR:
 | 
| 
 | 
 | 
             throw new \Exception(Lang::__('send_email_to_error'));
 | 
| 
 | 
 | 
         }
 | 
| 
 | 
 | 
         // 是否是数组
 | 
| 
 | 
 | 
         $data['to'] = explode("\n",trim($data['to']));
 | 
| 
 | 
 | 
         if(!$data['to']){
 | 
| 
 | 
 | 
             goto SEND_EMAIL_TO_ERROR;
 | 
| 
 | 
 | 
         }
 | 
| 
 | 
 | 
 //        $to = [
 | 
| 
 | 
 | 
 //            'email' =>  'xxx@qq.com',
 | 
| 
 | 
 | 
 //            'name'  =>  'xxx'
 | 
| 
 | 
 | 
 //        ];
 | 
| 
 | 
 | 
         foreach ($data['to'] as $k=>$to){
 | 
| 
 | 
 | 
             $to = trim($to);
 | 
| 
 | 
 | 
             $data['to'][$to] = [];
 | 
| 
 | 
 | 
             $data['to'][$to]['email'] =   $to;
 | 
| 
 | 
 | 
             $data['to'][$to]['name'] =   explode('@',$to)[0];
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
             // 是否是邮箱
 | 
| 
 | 
 | 
             if(!preg_match('/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/',$data['to'][$to]['email'])){
 | 
| 
 | 
 | 
 //                throw new \Exception(Lang::__('send_email_to_error',$data['to'][$to]['email']));
 | 
| 
 | 
 | 
                 unset($data['to'][$to]);
 | 
| 
 | 
 | 
             }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
             unset($data['to'][$k]);
 | 
| 
 | 
 | 
         }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         $data['to'] = array_values($data['to']);
 | 
| 
 | 
 | 
         if(!$data['to']){
 | 
| 
 | 
 | 
             goto SEND_EMAIL_TO_ERROR;
 | 
| 
 | 
 | 
         }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         // 时间
 | 
| 
 | 
 | 
         if($data['send_time'] != 'now'){
 | 
| 
 | 
 | 
             $data['send_time'] = explode(',',$data['send_time']);
 | 
| 
 | 
 | 
             if($data['send_time'][0] < 24 && $data['send_time'][1] < 24){
 | 
| 
 | 
 | 
                 $data['send_time'] = implode(',',$data['send_time']);
 | 
| 
 | 
 | 
             }else{
 | 
| 
 | 
 | 
                 $data['send_time'] = '21,11';
 | 
| 
 | 
 | 
             }
 | 
| 
 | 
 | 
         }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         $tags = get('tags');
 | 
| 
 | 
 | 
         if (!$tags || !is_array($tags)){
 | 
| 
 | 
 | 
             throw new \Exception('请选择tag标签');
 | 
| 
 | 
 | 
         }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         // 加入任务
 | 
| 
 | 
 | 
         $job_id = EmailSendJob::_insert([
 | 
| 
 | 
 | 
             'title' =>  $data['subject']??'',
 | 
| 
 | 
 | 
             'to'    =>  $data['to'],
 | 
| 
 | 
 | 
             'the_manage_id' =>  the_manage('id'),
 | 
| 
 | 
 | 
             'email_id'  => $this->id,
 | 
| 
 | 
 | 
             'user_id'   =>  $this->user_id,
 | 
| 
 | 
 | 
             'data'  =>  $data,
 | 
| 
 | 
 | 
             'send_time' =>  $data['send_time'],
 | 
| 
 | 
 | 
             'tags'  =>  $tags
 | 
| 
 | 
 | 
         ]);
 | 
| 
 | 
 | 
         if($job_id){
 | 
| 
 | 
 | 
             // 发送一个任务
 | 
| 
 | 
 | 
             SendJob::dispatch($job_id);
 | 
| 
 | 
 | 
             return $job_id;
 | 
| 
 | 
 | 
         }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         throw new \Exception(Lang::__('email_send_error'));
 | 
| 
 | 
 | 
     }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     /**
 | 
| 
 | 
 | 
      * 下载附件
 | 
| 
 | 
 | 
      * @param $name
 | 
| 
 | 
 | 
      * @param string $originname
 | 
| 
 | 
 | 
      * @return string|\Symfony\Component\HttpFoundation\BinaryFileResponse
 | 
| 
 | 
 | 
      * @author:dc
 | 
| 
 | 
 | 
      * @time 2022/11/2 10:59
 | 
| 
 | 
 | 
      */
 | 
| 
 | 
 | 
     public function download($name,$originname=''){
 | 
| 
 | 
 | 
         $file = $this->getFilePath().$name;
 | 
| 
 | 
 | 
         if(is_file($file)){
 | 
| 
 | 
 | 
             return response()->download($file,$originname ? : $name);
 | 
| 
 | 
 | 
         }
 | 
| 
 | 
 | 
         return '';
 | 
| 
 | 
 | 
     }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     /**
 | 
| 
 | 
 | 
      * @param mixed $data
 | 
| 
 | 
 | 
      * @param string $message
 | 
| 
 | 
 | 
      * @param int $status
 | 
| 
 | 
 | 
      * @return \Illuminate\Http\JsonResponse
 | 
| 
 | 
 | 
      * @author:dc
 | 
| 
 | 
 | 
      * @time 2022/8/1 11:05
 | 
| 
 | 
 | 
      */
 | 
| 
 | 
 | 
     private function echoJson($data='', $message='', $status=200):\Illuminate\Http\JsonResponse{
 | 
| 
 | 
 | 
         $data = [
 | 
| 
 | 
 | 
             'data'  =>  $data,
 | 
| 
 | 
 | 
             'message'   =>  $message,
 | 
| 
 | 
 | 
             'status'    =>  $status
 | 
| 
 | 
 | 
         ];
 | 
| 
 | 
 | 
         return response()->json($data,200,[]);
 | 
| 
 | 
 | 
     }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 } |