审查视图

controller/Home.php 31.6 KB
邓超 authored
1 2
<?php
1  
邓超 authored
3
namespace Controller;
邓超 authored
4
1  
邓超 authored
5
use Lib\Mail\Mail;
1  
邓超 authored
6
use Lib\Mail\MailFun;
1  
邓超 authored
7
use Lib\UploadFile;
1  
邓超 authored
8
use Lib\Verify;
1  
邓超 authored
9
use Model\bodySql;
1  
邓超 authored
10
use Model\emailSql;
1  
邓超 authored
11
use Model\folderSql;
1  
邓超 authored
12
use Model\listsSql;
1  
邓超 authored
13
use Model\sendJobsSql;
1  
邓超 authored
14 15
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
x  
邓超 authored
16
use function Swoole\Coroutine\Http\request;
1  
邓超 authored
17
1  
邓超 authored
18
邓超 authored
19 20
/**
 * @author:dc
1  
邓超 authored
21 22 23
 * @time 2023/2/13 11:28
 * Class Home
 * @package Controller
邓超 authored
24
 */
1  
邓超 authored
25
class Home extends Base {
1  
邓超 authored
26
邓超 authored
27
1  
邓超 authored
28 29 30 31 32 33 34 35 36 37 38
    /**
     * 邮件列表
     * @author:dc
     * @time 2023/2/17 14:12
     */
    public function lists(){

        // 分页 页数
        $page   =   app()->request('page',1,'intval');
        $page   =   $page ? $page : 1;
1  
邓超 authored
39 40 41 42 43 44 45 46 47 48 49
        $limit   =   app()->request('limit',20,'intval');
        $limit   =   $limit ? $limit : 1;

        // 指定id
        $ids = app()->request('mail_id');
        $ids = is_array($ids) ? $ids : [$ids];
        foreach ($ids as $i=>$d){
            if(!is_numeric($d)){
                unset($ids[$i]);
            }
        }
1  
邓超 authored
50
1  
邓超 authored
51
        // 附件
1  
邓超 authored
52
        $attachment =   app()->request('attachment',0,'bool_Val');
1  
邓超 authored
53 54
        // 已读/未读
        $seen =   app()->request('seen',-1,'intval');
1  
邓超 authored
55 56
        // 软删
        $deleted =   app()->request('deleted',0,'intval');
1  
邓超 authored
57
1  
邓超 authored
58 59

        $where = ['email_id'=>$this->getEmails('id')];
1  
邓超 authored
60
x  
邓超 authored
61
1  
邓超 authored
62
        $folder_id = [];
x  
邓超 authored
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
        if (app()->requestArr('folder_id')){
            $folder_id = app()->requestArr('folder_id');
        }else{
            // 目录
            $folder = app()->request('folder','收件箱');
            $folderList = db()->all(folderSql::all($where['email_id']));

            // 文件夹id
            if($folderList){
                foreach ($folderList as $item){
                    if(
                        // 数组文件夹
                        (is_array($folder) && in_array($item['folder'],$folder))
                        || $item['folder'] == $folder
                    ){
                        $folder_id[] = $item['id'];
                    }
1  
邓超 authored
80 81 82
                }
            }
        }
x  
邓超 authored
83
1  
邓超 authored
84 85 86
        if(!$folder_id){
            app()->e('folder_not_fount');
        }
1  
邓超 authored
87
1  
邓超 authored
88
        //目录
1  
邓超 authored
89
        $where['folder_id'] = $folder_id;
1  
邓超 authored
90
        if($ids) $where['id'] = $ids;
x  
邓超 authored
91 92 93 94 95 96

        if(paramHas('attachment')){
            $where['is_file'] = $attachment ? 1 : 0; //附件
        }

1  
邓超 authored
97 98
        // 软删
        $where['deleted'] = $deleted;
1  
邓超 authored
99
        // 已读/未读
x  
邓超 authored
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
        if(paramHas('seen')){
            if(in_array($seen,[0,1])){
                $where['seen'] = $seen;
            }
        }

        $where['_'] = [];
        // 搜索关键字
        $keyword = app()->request('keyword','',['htmlspecialchars','addslashes']);
        if($keyword){
            $where['_'][] = '`subject` like "%'.$keyword.'%"';
        }

        // 那个发的
        $address = app()->request('address');
        if($address){
            if(is_array($address)){
                // 发贱人
                if(Verify::sEmail($address['from']??'')){
                    $where['from'] = $address['from'];
                }
                // 收件人
                if(Verify::sEmail($address['to']??'')){
                    $where['_'][] = '`to_name` like "%'.$address.'%"';
                }

            }else if(Verify::sEmail($address)){
                // 收件人/发件人
                $where['_'][] = '(`from` = "'.$address.'" or `to_name` like "%'.$address.'%")';
            }
        }
x  
邓超 authored
131
        // from 搜索收件人
x  
邓超 authored
132
        if(app()->requestHas('from')){
x  
邓超 authored
133 134 135
            // 如果是发件箱
            if($folder == '发件箱'){
                $where['to'] = app()->request('from');
x  
邓超 authored
136 137 138 139
                if(!$where['to']){
                    // 不让查询数据
                    $where['id'] = 0;
                }
x  
邓超 authored
140 141
            }else{
                $where['from'] = app()->request('from');
x  
邓超 authored
142 143 144 145
                if(!$where['from']){
                    // 不让查询数据
                    $where['id'] = 0;
                }
x  
邓超 authored
146
            }
x  
邓超 authored
147 148

x  
邓超 authored
149 150 151
        }

x  
邓超 authored
152 153 154 155 156
        // 回复
        if (paramHas('answered')){
            $where['answered'] = app()->request('answered',0,'bool_Val')?1:0;
        }
邓超 authored
157
        // 这个主要是来筛选 是否是自己发送的
x  
邓超 authored
158 159 160 161 162
        $fromto = app()->request('formorto');
        if($fromto=='from'){
            $where['from'] = $this->getEmails('email');
        }elseif ($fromto=='to'){
            $where['from.notin'] = $this->getEmails('email');
1  
邓超 authored
163
        }
1  
邓超 authored
164
邓超 authored
165 166 167
        /**
         * 不查询哪些发件人的邮件
         */
x  
邓超 authored
168
        $form_not_in = app()->request('from_not_in');
邓超 authored
169 170 171 172 173 174 175 176 177
        if($form_not_in){
            $form_not_in = is_array($form_not_in) ? $form_not_in : [$form_not_in];
            $form_not_in = array_filter($form_not_in,function ($v){
               if(is_string($v) && Verify::sEmail($v)){
                   return true;
               }
               return false;
            });
            if($form_not_in){
x  
邓超 authored
178 179 180 181 182 183
                if(isset($where['from.notin'])){
                    $where['from.notin'] = array_merge($where['from.notin'],$form_not_in);
                }else{
                    $where['from.notin'] = $form_not_in;
                }
邓超 authored
184 185
            }
        }
x  
邓超 authored
186 187 188 189
        if(!empty($where['from.notin'])){
            $where['from.notin'] = array_unique($where['from.notin']);
        }
邓超 authored
190 191

1  
邓超 authored
192 193
        $lists = db()->all(
            listsSql::lists(
1  
邓超 authored
194
                dbWhere($where),
1  
邓超 authored
195
                $page,
1  
邓超 authored
196
                $limit
1  
邓超 authored
197 198
            )
        );
x  
邓超 authored
199
        $lists = $lists ? $lists : [];
1  
邓超 authored
200
邓超 authored
201 202
        // map
        $lists = array_map(function ($v){
邓超 authored
203
            $v['uuid'] = get_email_uuid($v['subject'],$v['udate'],$v['from'],$v['to'],$v['size']);
邓超 authored
204 205 206
            if(!empty($v['description'])){
                $v['description'] = @html_entity_decode($v['description'], ENT_COMPAT, 'UTF-8');
            }
x  
邓超 authored
207 208
            $v['to_name'] = @json_decode($v['to_name'],true);
            $v['to_name'] = $v['to_name']?:[];
x  
邓超 authored
209 210 211 212 213 214 215 216 217
            if($v['to_name']){
                if(!empty($v['to_name'][0]['email'])){
                    $v['to'] = $v['to_name'][0]['email'];
                }
                $v['to_name'] = $v['to_name'][0]['name']??'';
            }
            if(is_array($v['to_name'])){
                $v['to_name'] = '';
            }
邓超 authored
218 219 220
            return $v;
        },$lists);
1  
邓超 authored
221 222
        // 总数
        $total  = db()->count(
1  
邓超 authored
223
            listsSql::listCount(dbWhere($where))
1  
邓超 authored
224 225
        );
1  
邓超 authored
226
        app()->_json(listsPage($lists,$total,$page,$limit));
1  
邓超 authored
227 228 229

    }
1  
邓超 authored
230
1  
邓超 authored
231 232 233 234 235 236 237
    /**
     * 检测邮箱状态
     * @author:dc
     * @time 2023/3/28 16:19
     */
    public function check(){
x  
邓超 authored
238 239
        $lists = db()->all(emailSql::getValues(['email'=>web_request_emails()],'`id`,`pwd_error`,`email`,`password`,`imap`'));
        foreach ($lists as $k=>$list){
x  
邓超 authored
240 241
            if(!$list['pwd_error']){
                $mail = new \Lib\Mail\Mail($list['email'],base64_decode($list['password']),$list['imap']);
x  
邓超 authored
242
x  
邓超 authored
243
                // 2次登录请求
x  
邓超 authored
244
                if($mail->login()!==1){
x  
邓超 authored
245 246 247
                    if($mail->login()!==1){
                        $lists[$k]['pwd_error'] = 1;
                    }
x  
邓超 authored
248
                }
x  
邓超 authored
249
                $mail = null;
x  
邓超 authored
250
            }
x  
邓超 authored
251
x  
邓超 authored
252
        }
1  
邓超 authored
253 254 255 256 257

        return array_column($lists,'pwd_error','email');

    }
1  
邓超 authored
258
1  
邓超 authored
259
    /**
1  
邓超 authored
260
     * 发送邮件
1  
邓超 authored
261
     * @author:dc
1  
邓超 authored
262
     * @time 2023/2/18 17:32
1  
邓超 authored
263
     */
1  
邓超 authored
264
    public function send_mail(){
1  
邓超 authored
265
1  
邓超 authored
266 267
        $email = $this->getEmail();
1  
邓超 authored
268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284
        $yzemail = function(&$value,$field){
            if($value){
                if(!is_array($value)){
                    if(@json_decode($value,true)){
                        $value =    json_decode($value,true);
                    }else{
                        $value = [['email'=>$value,'name'=>'']];
                    }
                }
                foreach ($value as $item){
                    if(!Verify::sEmail($item['email'])){
                        app()->e([$field.'_verify_error',$item['email']]);
                    }
                }
            }
        };
1  
邓超 authored
285
        $formData = Verify::checks([
x  
邓超 authored
286
            'nickname|'.__('nickname')  =>  ['max'=>50],
邓超 authored
287
            'subject|'.__('subject')  =>  ['required','max'=>500],
1  
邓超 authored
288
            'body|'.__('body_email')  =>  ['required'],
1  
邓超 authored
289 290 291
            'tos|'.__('to_email')  =>  ['required',$yzemail],
            'cc|'.__('to_cc')  =>  [$yzemail],
            'bcc|'.__('to_bcc')  =>  [$yzemail],
1  
邓超 authored
292
            'priority|'.__('priority_email')  =>  ['in'=>[1,3,5]],
1  
邓超 authored
293
            'attachment|'.__('files_email')  =>  [
1  
邓超 authored
294 295
                'file'=>[
                    'ext'   =>  [],
1  
邓超 authored
296
                    'size'  =>  1024*1024*5,
1  
邓超 authored
297 298 299 300
                    'mine'  =>  []
                ]
            ],
            'receipt|'.__('receipt_email')  =>  []
1  
邓超 authored
301 302 303 304
        ],[

        ]);
1  
邓超 authored
305
1  
邓超 authored
306 307 308 309
        $sendData = [];
        $sendData['email']   =   $email['email'];
        $sendData['nickname']   =   $formData['nickname']??'';
        $sendData['tos']   =   $formData['tos'];
1  
邓超 authored
310 311 312
        if(count($sendData['tos'])>100){
            app()->e(['tos_number_error',100]);
        }
1  
邓超 authored
313
//        抄送
1  
邓超 authored
314
        $sendData['cc'] = [];
1  
邓超 authored
315 316
        if(($formData['isCc']??0) && !empty($formData['cc'])){
            $sendData['cc'] =   $formData['cc'];
1  
邓超 authored
317
        }
1  
邓超 authored
318 319 320
        if(count($sendData['cc'])>10){
            app()->e(['cc_number_error',10]);
        }
1  
邓超 authored
321
        // 密送
1  
邓超 authored
322
        $sendData['bcc'] = [];
1  
邓超 authored
323 324
        if(($formData['isBcc']??0) && !empty($formData['bcc'])){
            $sendData['bcc'] =   $formData['bcc'];
1  
邓超 authored
325
        }
x  
邓超 authored
326 327 328 329 330 331 332 333

        // 添加自定义头信息 预热邮件
        if(!empty($formData['aicc-hot'])){
            $sendData['mail-header'] = [
                'Aicc-Hot-Mail' =>  'hot' // 预热邮件
            ];
        }
1  
邓超 authored
334 335 336
        if(count($sendData['bcc'])>10){
            app()->e(['bcc_number_error',10]);
        }
1  
邓超 authored
337 338 339
        $sendData['reply_to'] = [];//回复到那个邮件
        //Attachments 附件 上传的
        $sendData['attachment'] = [];
1  
邓超 authored
340 341 342 343
        $attachment = app()->file('attachment');
        if($attachment){
            foreach ($attachment as $file){
                if($file->move()){
1  
邓超 authored
344 345 346 347 348 349
                    $sendData['attachment'][] = [
                        'name'  =>  $file->name,
                        'filename'  =>  $file->name,
                        'signName'  =>  $file->saveName,
                        'path'  =>  $file->savePath.$file->saveName
                    ];
1  
邓超 authored
350 351 352 353 354
                }else{
                    app()->e(['attachment_upload_error',$file->name]);
                }
            }
        }
1  
邓超 authored
355 356 357 358 359 360 361 362
        // 远程路径,云文件
        $attachmentUrl = app()->request('attachmentUrl');
        if(is_array($attachmentUrl)){
            foreach ($attachmentUrl as $file){
                $file = is_array($file) ? $file : json_decode($file,true);
                if(!empty($file['url']) && !empty($file['name'])){
                    $file = new UploadFile($file['name'],$file['url']);
                    if($file->move()){
1  
邓超 authored
363 364 365 366 367 368
                        $sendData['attachment'][] = [
                            'name'  =>  $file->name,
                            'filename'  =>  $file->name,
                            'signName'  =>  $file->saveName,
                            'path'  =>  $file->savePath.$file->saveName
                        ];
1  
邓超 authored
369 370 371 372 373 374 375
                    }else{
                        app()->e(['attachment_upload_error',$file->name]);
                    }
                }

            }
        }
1  
邓超 authored
376 377 378
        $sendData['receipt'] = empty($formData['receipt']) ? '' : 1;// 回执,阅读后收回执的邮箱
        $sendData['priority'] = $formData['priority']??3;// 是否紧急邮件
        $sendData['subject'] = $formData['subject'];// //Content 主题,标题
x  
邓超 authored
379 380
        // 删除script标记
        $sendData['body'] = strip_tags_content($formData['body'],'<script>',true);
1  
邓超 authored
381 382 383
        // 不重要的信息
        $sendData['jobName'] = $formData['jobName']??'';//任务标题
        $sendData['massSuit'] = $formData['massSuit']??0;// 是否是群发单显
1  
邓超 authored
384 385

        // 定时发送时间
1  
邓超 authored
386 387 388 389 390 391 392 393
        $timer = app()->request('timerValue',0);
        if(is_numeric($timer) && $timer){
            $timer = time()+$timer;
        }else if (is_string($timer)){
            $timer = strtotime($timer);
        }else{
            $timer = 0;
        }
1  
邓超 authored
394 395 396 397 398 399 400 401 402
        // 是否存草稿
        if(app()->request('saveType')=='draft'){
            // 保存
            $draftid =  listsSql::saveDraft($sendData,$email,app()->request('draft_id',0,'intval'));
            // 保存失败
           if($draftid){
                app()->_json(['draft_id'=>$draftid]);
           }
           app()->e('save_draft_error');
1  
邓超 authored
403 404

        }
1  
邓超 authored
405 406 407 408 409 410 411 412 413
        // 定时发送 或者是单条发送
        else if((app()->request('timer') &&  $timer > time()) || $sendData['massSuit']){

            if($sendData['massSuit']){
                // 每次发送间隔的时间
                $sendData['masssuit_interval_send']  = app()->request('masssuit_interval_send');
                $sendData['masssuit_interval_send']['start'] = intval($sendData['masssuit_interval_send']['start']??0);
                $sendData['masssuit_interval_send']['end'] = intval($sendData['masssuit_interval_send']['end']??1);
            }
1  
邓超 authored
414
x  
邓超 authored
415
1  
邓超 authored
416 417 418 419 420 421
            // 插入任务
            $job_id = db()->insert(sendJobsSql::$table,[
                'email_id'  =>  $email['id'],
                'maildata'  =>  $sendData,
                'title'  =>  $sendData['jobName'] ? : $sendData['subject'],
                'total'  =>  count($sendData['tos']),
x  
邓超 authored
422
                'send_time' =>  $timer?:time()
1  
邓超 authored
423 424 425 426 427 428 429 430 431 432 433 434 435 436
            ]);
            if($job_id){
                // 返回任务id
                app()->_json(['job_id'=>$job_id]);
            }

            app()->e('send_timer_job_error');
        }
        else{
            // 立即发送
            $result = MailFun::sendEmail($sendData,$email);
            if($result[0]){
                app()->_json(['messageId'   => $result[1]]);
            }
1  
邓超 authored
437 438
            // 错误
            app()->e($result[1]);
1  
邓超 authored
439 440
        }
1  
邓超 authored
441
    }
1  
邓超 authored
442 443

1  
邓超 authored
444 445 446 447 448 449
    /**
     * 收到前端的同步请求操作
     * @author:dc
     * @time 2023/3/10 10:38
     */
    public function sync(){
1  
邓超 authored
450
1  
邓超 authored
451
        $emails = web_request_emails();
1  
邓超 authored
452
1  
邓超 authored
453
        if(empty($emails)){
1  
邓超 authored
454 455 456
            app()->e('sync_request_param_error');
        }else{
            // 查询id
1  
邓超 authored
457 458 459
            if(count($emails)===1){
                $emails = $emails[0];
            }
1  
邓超 authored
460 461
            $datas = db()->all(emailSql::getValues(['email'=>$emails],'`id`,`email`,`pwd_error`'));
            foreach ($datas as $k=>$v){
1  
邓超 authored
462
                if(!$v['pwd_error']){
邓超 authored
463 464 465 466 467 468 469 470 471
                    $blacklist = app()->request('blacklist');
                    if(is_array($blacklist)){
                        $blacklist = [
                            'emails' =>   $blacklist['emails']??[],
                            'domain' =>   $blacklist['domain']??[],
                        ];
                        // 黑名单,7天过期时间
                        redis()->set('blacklist:'.$v['id'],$blacklist,86400*7);
                    }
x  
邓超 authored
472 473 474 475
                    // 删除
                    if(!$blacklist||(empty($blacklist['emails'])&&empty($blacklist['domain']))){
                        redis()->delete('blacklist:'.$v['id']);
                    }
邓超 authored
476
1  
邓超 authored
477 478
                    redis()->rPush('sync_email_lists', $v['id']);
                }
1  
邓超 authored
479
                $datas[$k]['have_new'] = redis()->getDel('have_new_mail_'.$v['id']);
邓超 authored
480 481

                // 计算
邓超 authored
482 483 484 485 486 487 488 489 490 491 492
//                $folders = db()->all(folderSql::all($v['id'],'`id`'));
//                foreach ($folders as $folder){
//                    $w = [
//                        'email_id'  =>  $v['id'],
//                        'folder_id'  =>  $folder['id'],
//                    ];
//                    db()->update(folderSql::$table,[
//                        'exsts' =>  db()->count(listsSql::listCount(dbWhere($w))),
//                        'unseen' =>  db()->count(listsSql::listCount(dbWhere(array_merge($w,['seen'=>0])))),
//                    ],'`id` = '.$folder['id'],false);
//                }
邓超 authored
493
1  
邓超 authored
494 495
            }
            // 返回成功的参数值
1  
邓超 authored
496
            app()->_json($datas);
1  
邓超 authored
497 498 499 500
        }

    }
1  
邓超 authored
501
1  
邓超 authored
502 503 504 505 506 507 508
    /**
     * 标记为已读
     * @throws \Lib\Err
     * @author:dc
     * @time 2023/3/17 16:15
     */
    public function seen_2_unseen(){
1  
邓超 authored
509 510 511
        $this->setFlags('seen');
    }
1  
邓超 authored
512 513 514 515 516 517
    /**
     * 是否已回复
     * @throws \Lib\Err
     * @author:dc
     * @time 2023/4/10 16:30
     */
1  
邓超 authored
518 519 520 521
    public function answered_2_unanswered(){
        $this->setFlags('answered');
    }
邓超 authored
522 523 524 525 526 527 528 529 530 531 532 533
    /**
     * 星标
     * @throws \Lib\Err
     * @author:dc
     * @time 2024/6/21 16:35
     */
    public function star_2_unstar(){
        $this->setFlags('flagged');
    }


1  
邓超 authored
534 535 536


    /**
1  
邓超 authored
537
     * 邮件移动
1  
邓超 authored
538 539 540
     * @author:dc
     * @time 2023/3/21 11:41
     */
1  
邓超 authored
541
    public function move(){
邓超 authored
542
        $this->moveCopy(function (Mail $mailInstance,$uid,$origin_folder,$to_origin_folder){
邓超 authored
543 544 545
//            try {
//                return $mailInstance->move($uid,$origin_folder,$to_origin_folder);
//            }catch (\Throwable $e){
邓超 authored
546
//                if(app()->request('move_err_copy',1)){
邓超 authored
547
                    // 复制成功
x  
邓超 authored
548 549 550 551 552 553 554 555 556
            try {
                if($mailInstance->copy($uid,$origin_folder,$to_origin_folder)){
                    return $mailInstance->deleted($uid,$origin_folder);
                }
            }catch (\Throwable $e){
                logs('移动失败:'.$e->getMessage());
                return false;
            }
邓超 authored
557
//                }
邓超 authored
558
//            }
邓超 authored
559 560
            return false;
邓超 authored
561 562 563 564 565
        });
    }


    private function moveCopy(\Closure $call){
1  
邓超 authored
566 567
        $emails = $this->getEmails();
x  
邓超 authored
568
        $mail_ids = app()->requestArr('mail_ids');
1  
邓超 authored
569 570 571
        if(!($mail_ids && is_array($mail_ids))){
            app()->e('param_request_error');
        }
1  
邓超 authored
572 573 574 575 576 577
        foreach ($mail_ids as $k=>$id){
            if(!is_numeric($id)){
                unset($mail_ids[$k]);
            }
        }
        // 移动到的文件夹
x  
邓超 authored
578
        $to_folder = folderAlias(app()->request('folder'));
1  
邓超 authored
579 580 581
        if(empty($to_folder)){
            app()->e('folder_move_error');
        }
1  
邓超 authored
582 583 584 585 586 587
        if($to_folder == '草稿箱'){
            app()->e('folder_move_to_draft_error');
        }
        if($to_folder == '发件箱'){
            app()->e('folder_move_to_send_error');
        }
1  
邓超 authored
588
x  
邓超 authored
589
        $data  = db()->all(listsSql::all(dbWhere(['id'=>$mail_ids,'email_id'=>array_column($emails,'id')]),'`id`,`uid`,`email_id`,`folder_id`'));
1  
邓超 authored
590 591 592 593 594
        if($data){
            // 查询邮箱
            $emails = array_column($emails,null,'id');
            $uids = [];
            foreach ($data as $datum){
1  
邓超 authored
595 596 597 598 599 600 601 602 603 604 605 606
                // 只有草稿箱才没有uid
                if(!$datum['uid']){
                    // 删除
                    if ($to_folder == '回收站'){
                        // 删除数据,真实删除
                        db()->delete(listsSql::$table,[
                            'id'    =>  $datum['id']
                        ]);
                        continue;
                    }
                }
x  
邓超 authored
607
                if(empty($uids[$datum['email_id']][$datum['folder_id']])){
1  
邓超 authored
608 609 610 611 612 613 614 615 616
                    $uids[$datum['email_id']][$datum['folder_id']] = [];
                }
                $uids[$datum['email_id']][$datum['folder_id']][] = [
                    'uid'   =>   $datum['uid'],
                    'id'   =>   $datum['id'],
                ];
            }

            foreach ($uids as $eid=>$arr){
1  
邓超 authored
617 618 619 620 621 622 623 624 625 626
                // 查询需要移动的文件夹
                $to_origin_folder = db()->first(folderSql::first(['email_id'=>$eid,'folder'=>$to_folder]));
                if($to_origin_folder){
                    foreach ($arr as $fid=>$uid){
                        // 查询目录
                        $folder = db()->first(folderSql::first($fid));
                        if($folder){
                            // 开始远程
                            $mailInstance = new Mail($emails[$eid]['email'],base64_decode($emails[$eid]['password']),$emails[$eid]['imap']);
x  
邓超 authored
627
                            if($mailInstance->login()==1){
邓超 authored
628
                                $ret = $call($mailInstance,array_column($uid,'uid'),$folder['origin_folder'],$to_origin_folder['origin_folder']);
1  
邓超 authored
629 630 631 632 633 634
                                // TODO:: 这个过程无法保证原子性。没办法
                                // 先复制
                                if($ret){
                                    $uret = db()->update(listsSql::$table,['deleted'=>1],dbWhere(['id'=>array_column($uid,'id')]));
                                }
邓超 authored
635
1  
邓超 authored
636
                            }
邓超 authored
637
                            $mailInstance = null;
1  
邓超 authored
638
1  
邓超 authored
639 640
                        }
                        $folder = null;
1  
邓超 authored
641 642
                    }
                }
1  
邓超 authored
643 644

1  
邓超 authored
645 646 647 648 649 650 651 652
            }

        }


        app()->_json([
            'mail_id'    =>  $mail_ids
        ]);
1  
邓超 authored
653 654 655
    }

邓超 authored
656 657 658 659 660 661 662 663 664 665 666 667 668 669 670
    /**
     * 复制邮件
     * @throws \Lib\Err
     * @author:dc
     * @time 2024/3/9 13:50
     */
    public function copy(){
        $this->moveCopy(function (Mail $mailInstance,$uid,$origin_folder,$to_origin_folder){

            return $mailInstance->copy($uid,$origin_folder,$to_origin_folder);

        });
    }

邓超 authored
671 672 673 674 675 676 677 678 679
    /**
     * 执行清空邮件操作
     * @throws \Lib\Err
     * @author:dc
     * @time 2024/3/14 14:18
     */
    public function expunge(){
        $email = $this->getEmail();
        $mailInstance = new Mail($email['email'],base64_decode($email['password']),$email['imap']);
x  
邓超 authored
680 681

        if($mailInstance->login()==1 && $mailInstance->expunge()){
邓超 authored
682 683 684 685 686 687 688
            app()->_json([]);
        }

        app()->e('执行失败');
    }

1  
邓超 authored
689 690

1  
邓超 authored
691 692 693 694 695 696 697
    /**
     * 远程标签
     * @param $d
     * @throws \Lib\Err
     * @author:dc
     * @time 2023/3/21 14:28
     */
1  
邓超 authored
698
    private function setFlags($d){
1  
邓超 authored
699 700 701
        $emails = $this->getEmails();

        $mail_ids = app()->request('mail_ids');
邓超 authored
702 703 704 705 706 707 708 709 710 711 712

        // 全部标记
        if(!$mail_ids){
            $folder = app()->request('folder','收件箱');
            // 查询 当前的 文件夹 如果有选中文件夹 就 查询出 选中文件夹的id
            $fids = db()->all(folderSql::all(array_column($emails,'id'),'`id`,`folder`'));
            foreach ($fids as $fk=>$fid){
                if($fid['folder'] != $folder){
                    unset($fids[$fk]);
                }
            }
邓超 authored
713 714 715 716 717 718
            if($fids){
                // 查询要标记的 邮件id
                $mail_ids = db()->all(listsSql::all(dbWhere(['folder_id'=>array_column($fids,'id'),'seen'=>0]),'`id`'));

                $mail_ids = array_column($mail_ids,'id');
            }
邓超 authored
719 720 721

        }
邓超 authored
722 723 724
        if($mail_ids){
            $mail_ids = is_array($mail_ids) ? $mail_ids : explode(',',$mail_ids);
        }
邓超 authored
725
1  
邓超 authored
726 727 728
        if(!($mail_ids && is_array($mail_ids))){
            app()->e('param_request_error');
        }
1  
邓超 authored
729 730 731 732 733 734
        foreach ($mail_ids as $k=>$id){
            if(!is_numeric($id)){
                unset($mail_ids[$k]);
            }
        }
        // 已读或未读
1  
邓超 authored
735 736
        $fv = (int) app()->request($d);
        $fv = $fv ? 1 : 0;
1  
邓超 authored
737
邓超 authored
738
        $data  = db()->all(listsSql::all(dbWhere(['id'=>$mail_ids,'email_id'=>array_column($emails,'id')]),'`id`,`uid`,`email_id`,`folder_id`'));
1  
邓超 authored
739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760
        if($data){
            // 查询邮箱
            $emails = array_column($emails,null,'id');
            $uids = [];
            foreach ($data as $datum){
                if(empty($uids[$datum['email_id']])){
                    $uids[$datum['email_id']][$datum['folder_id']] = [];
                }
                $uids[$datum['email_id']][$datum['folder_id']][] = [
                    'uid'   =>   $datum['uid'],
                    'id'   =>   $datum['id'],
                ];
            }

            foreach ($uids as $eid=>$arr){
                foreach ($arr as $fid=>$uid){
                    // 查询目录
                    $folder = db()->first(folderSql::first($fid));
                    if($folder){
                        // 开始远程
                        $mailInstance = new Mail($emails[$eid]['email'],base64_decode($emails[$eid]['password']),$emails[$eid]['imap']);
x  
邓超 authored
761
                        if($mailInstance->login()==1){
1  
邓超 authored
762 763 764 765 766 767
                            switch ($d){
                                // 已读 未读
                                case 'seen':{
                                    $mailInstance->seen(array_column($uid,'uid'),$folder['origin_folder'],$fv);
                                    break;
                                }
1  
邓超 authored
768 769 770 771 772
                                // 未回复/已回复
                                case 'answered':{
                                    $mailInstance->answered(array_column($uid,'uid'),$folder['origin_folder'],$fv);
                                    break;
                                }
邓超 authored
773 774 775 776 777
                                // 星标
                                case 'flagged':{
                                    $mailInstance->flagged(array_column($uid,'uid'),$folder['origin_folder'],$fv);
                                    break;
                                }
1  
邓超 authored
778
                                // 回收站,已删 未删,软删
1  
邓超 authored
779 780 781 782
//                                case 'deleted':{
//                                    $mailInstance->recycle(array_column($uid,'uid'),$folder['origin_folder'],$fv);
//                                    break;
//                                }
1  
邓超 authored
783
                            }
1  
邓超 authored
784 785 786 787

                            $mailInstance = null;
                            // 更新数据
                            db()->update(listsSql::$table,[
1  
邓超 authored
788
                                $d  =>  $fv
1  
邓超 authored
789 790 791 792
                            ],dbWhere([
                                'id'    =>  array_column($uid,'id')
                            ]));
                        }
1  
邓超 authored
793 794 795 796 797 798 799 800 801 802 803 804 805 806

                    }
                    $folder = null;
                }
            }

        }


        app()->_json([
            'mail_id'    =>  $mail_ids
        ]);

    }
1  
邓超 authored
807 808

1  
邓超 authored
809 810 811 812 813 814 815 816 817 818 819 820
    /**
     * @author:dc
     * @time 2023/4/1 9:24
     */
    public function info(){
        $id =   app()->request('id',0,'intval');
        // 没有,说明没有同步过来
        $email = $this->getEmail();
        $data    =   db()->first(listsSql::first(dbWhere(['id'=>$id,'email_id'=>$email['id']])));

        if($data){
            $sync_num = 0;
邓超 authored
821
邓超 authored
822
            $data['uuid'] = get_email_uuid($data['subject'],$data['udate'],$data['from'],$data['to'],$data['size']);
邓超 authored
823
邓超 authored
824 825
            $data['description'] = @html_entity_decode($data['description']??'', ENT_COMPAT, 'UTF-8');
1  
邓超 authored
826 827 828
            $data['to_name'] = $data['to_name'] ? json_decode($data['to_name'],true) : [];
            $data['cc'] = $data['cc'] ? json_decode($data['cc'],true) : [];
            $data['bcc'] = $data['bcc'] ? json_decode($data['bcc'],true) : [];
1  
邓超 authored
829
邓超 authored
830 831 832 833 834
            // 是否再次 重新获取
            $reload = app()->request('reload',0,'intval');
            if($reload){
                // 删除原有数据
                db()->delete(bodySql::$table,['lists_id'=>$id]);
x  
邓超 authored
835 836
                //同步基础信息
                $mail   =   new Mail($email['email'],base64_decode($email['password']),$email['imap']);
x  
邓超 authored
837
                if($mail->login()==1){
x  
邓超 authored
838 839 840 841 842 843
                    $folder = db()->value(folderSql::first(['id'=>$data['folder_id']],'origin_folder'));
                    if($folder){
                        $mail->client->selectFolder($folder);
                        $mail->syncUidEmail([$data['uid']],$email['id'],$folder,$data['folder_id'],[],[],db());
                    }
                }
邓超 authored
844 845
            }
1  
邓超 authored
846
            HOME_INFO_BODY:
1  
邓超 authored
847 848 849
            $body   =   db()->first(bodySql::first($id));
            if($body){
                $data['body'] = json_decode($body['text_html'],true);
邓超 authored
850
1  
邓超 authored
851 852
                $charset = 'utf-8';
                $htmlbody = '';
1  
邓超 authored
853
                foreach ($data['body'] as $bd){
1  
邓超 authored
854 855 856 857 858
//                    if(!empty($bd['charset'])){
//                        $charset = $bd['charset'];
//                    }
                    if(($bd['type']??'') == 'text/html'){
                        $htmlbody = base64_decode($bd['body']);
1  
邓超 authored
859 860 861 862
                    }
                }
                foreach ($data['body'] as $bdk=>$bd){
邓超 authored
863 864 865 866 867 868
                    if(count($bd)==1){
                        if(isset($bd['body'])){
                            $data['body'][$bdk]['type'] = 'text/html';
                        }
                    }
1  
邓超 authored
869 870
                    if(!empty($bd['path'])){
1  
邓超 authored
871 872 873 874 875 876 877
                        $data['body'][$bdk]['name'] = @base64_decode($bd['name']);
                        $data['body'][$bdk]['filename'] = @base64_decode($bd['filename']);
                        // 进行编码转换 会出现未知bug
//                        if($charset && strtolower($charset) != 'utf-8' && strtolower($charset) != 'utf8'){
//                            $data['body'][$bdk]['name'] = @iconv($charset,'utf-8',$data['body'][$bdk]['name']);
//                            $data['body'][$bdk]['filename'] = @iconv($charset,'utf-8',$data['body'][$bdk]['filename']);
//                        }
1  
邓超 authored
878 879 880 881 882 883 884 885 886 887

                        $data['body'][$bdk]['size'] = 0;
                        $data['body'][$bdk]['url'] = '';
                        if(is_file($bd['path'])){
                            // 文件大小
                            $data['body'][$bdk]['size'] = filesize($bd['path']);
                            // 文件访问地址
                            $data['body'][$bdk]['url'] = APP_HOST.str_replace(PUBLIC_PATH,'',$bd['path']);
                        }
1  
邓超 authored
888 889 890 891 892 893 894
                        // 验证编码是否有其他编码字符,这里编辑了未知编码
                        if(!@json_encode($data['body'][$bdk])){
                            // 抛弃原有的名字,显示已存储到服务器的名字
                            $data['body'][$bdk]['name'] = $data['body'][$bdk]['signName'];
                            $data['body'][$bdk]['filename'] = $data['body'][$bdk]['signName'];
                        }
1  
邓超 authored
895
                        unset($data['body'][$bdk]['path']);
1  
邓超 authored
896 897 898 899 900 901 902 903 904 905 906

                        // 内容区是有有cid
                        if ($htmlbody && !empty($bd['content-id'])){
                            if(!strpos($htmlbody,"\"cid:{$bd['content-id']}\"")){
                                unset($data['body'][$bdk]['content-id']);
                            }
                        }
                        // 没有html内容,content-id是不可能有的
                        else if(!$htmlbody){
                            unset($data['body'][$bdk]['content-id']);
                        }
1  
邓超 authored
907 908
                    }
                }
1  
邓超 authored
909 910 911
                return [
                    'data'  =>  $data
                ];
1  
邓超 authored
912 913 914 915 916 917
            }// 草稿
            else if(!$data['uid'] && $data['draft']){
                $data['body'] = [];
                return [
                    'data'  =>  $data
                ];
1  
邓超 authored
918
            }
1  
邓超 authored
919
            // 循环几次
1  
邓超 authored
920
            if($data['uid']&&$sync_num < 1){
1  
邓超 authored
921
                $mail   =   new Mail($email['email'],base64_decode($email['password']),$email['imap']);
1  
邓超 authored
922
x  
邓超 authored
923
                if($mail->login()==1){
1  
邓超 authored
924
1  
邓超 authored
925
                    $folder = db()->value(folderSql::first(['id'=>$data['folder_id']],'origin_folder'));
1  
邓超 authored
926 927 928
                    if($folder){
                        $ret = $mail->syncBody($folder,$data['uid'],$id);
                        $sync_num++;
1  
邓超 authored
929
                        if($ret){
1  
邓超 authored
930 931 932 933 934 935
                            goto HOME_INFO_BODY;
                        }
                    }

                }
            }
x  
邓超 authored
936
            logs('超过读取body次数 '.$data['id']);
x  
邓超 authored
937 938 939 940 941 942 943

            if(isset($mail)){
                if(!$mail->client->hasMail($data['uid'])){
                    app()->e('mail_not');
                }
            }
x  
邓超 authored
944 945
        }else{
            logs('读取body 没有查询到数据 '.$id.'-'.($email['email']??''));
1  
邓超 authored
946 947 948 949 950 951
        }

        app()->e('mail_body_error');

    }
1  
邓超 authored
952
邓超 authored
953 954 955 956 957 958 959 960 961 962
    /**
     * 解析订阅数据
     * @author:dc
     * @time 2024/8/7 14:12
     */
    public function desubscribe(){
        $key = app()->request('key','');
        app()->_json(MailFun::deSubscribeUrl($key));
    }
邓超 authored
963
}
1  
邓超 authored
964 965 966 967 968 969 970 971 972 973 974 975 976 977