作者 邓超

1

@@ -93,7 +93,11 @@ class Folder extends Base { @@ -93,7 +93,11 @@ class Folder extends Base {
93 $origin_folder = $parent['origin_folder'].'/'.$origin_folder; 93 $origin_folder = $parent['origin_folder'].'/'.$origin_folder;
94 } 94 }
95 95
96 - $formData['folder'] = str_replace(["'",'"','/','\\','&','*','(',')'],'',$formData['folder']); 96 + $formData['folder'] = str_replace(
  97 + ["'",'"','/','\\','&','*','(',')','{','}','|','$','@','!','#','%','^','<','>','?','`','~','[',']'],
  98 + '',
  99 + $formData['folder']
  100 + );
97 101
98 // 判断文件夹是否存在 102 // 判断文件夹是否存在
99 $has = db()->count(folderSql::has( 103 $has = db()->count(folderSql::has(
@@ -132,14 +136,22 @@ class Folder extends Base { @@ -132,14 +136,22 @@ class Folder extends Base {
132 'folder' => $formData['folder'], 136 'folder' => $formData['folder'],
133 'origin_folder' => $origin_folder, 137 'origin_folder' => $origin_folder,
134 'uuid' => md5($email['id'].$origin_folder), 138 'uuid' => md5($email['id'].$origin_folder),
135 - ]); 139 + ],false);
136 140
137 if(!$id){ 141 if(!$id){
138 app()->e('folder_create_save_error'); 142 app()->e('folder_create_save_error');
139 } 143 }
140 144
141 - // 返回数据  
142 - app()->_json(db()->first(folderSql::first($id))); 145 + // 查询
  146 + $folders = db()->all(
  147 + \Model\folderSql::all(
  148 + $email['id'],
  149 + '`id`,`folder`,`pid`,`exsts`,`unseen`,`email_id`'
  150 + )
  151 + );
  152 +
  153 +
  154 + return list_to_tree($folders);
143 155
144 } 156 }
145 157
@@ -186,17 +186,81 @@ class Home extends Base { @@ -186,17 +186,81 @@ class Home extends Base {
186 186
187 187
188 /** 188 /**
189 - * 邮件回收站,进行回收,恢复邮件 189 + * 邮件移动
190 * @author:dc 190 * @author:dc
191 * @time 2023/3/21 11:41 191 * @time 2023/3/21 11:41
192 */ 192 */
193 - public function recycle(){  
194 - $this->setFlags('deleted'); 193 + public function move(){
  194 + $emails = $this->getEmails();
  195 +
  196 + $mail_ids = app()->request('mail_ids');
  197 + foreach ($mail_ids as $k=>$id){
  198 + if(!is_numeric($id)){
  199 + unset($mail_ids[$k]);
  200 + }
  201 + }
  202 + // 移动到的文件夹
  203 + $folder = app()->request('folder');
  204 +
  205 + $data = db()->all(listsSql::first(dbWhere(['id'=>$mail_ids,'email_id'=>array_column($emails,'id')]),'`id`,`uid`,`email_id`,`folder_id`'));
  206 + if($data){
  207 + // 查询邮箱
  208 + $emails = array_column($emails,null,'id');
  209 + $uids = [];
  210 + foreach ($data as $datum){
  211 + if(empty($uids[$datum['email_id']])){
  212 + $uids[$datum['email_id']][$datum['folder_id']] = [];
  213 + }
  214 + $uids[$datum['email_id']][$datum['folder_id']][] = [
  215 + 'uid' => $datum['uid'],
  216 + 'id' => $datum['id'],
  217 + ];
  218 + }
  219 +
  220 + foreach ($uids as $eid=>$arr){
  221 + foreach ($arr as $fid=>$uid){
  222 + // 查询目录
  223 + $folder = db()->first(folderSql::first($fid));
  224 + if($folder){
  225 + // 开始远程
  226 + $mailInstance = new Mail($emails[$eid]['email'],base64_decode($emails[$eid]['password']),$emails[$eid]['imap']);
  227 +
  228 + if($mailInstance->login()){
  229 +
  230 + $mailInstance->move();
  231 +
  232 + $mailInstance = null;
  233 + // 更新数据
  234 +// db()->update(listsSql::$table,[
  235 +// $d => $fv
  236 +// ],dbWhere([
  237 +// 'id' => array_column($uid,'id')
  238 +// ]));
  239 + }
  240 +
  241 + }
  242 + $folder = null;
  243 + }
  244 + }
  245 +
  246 + }
  247 +
  248 +
  249 + app()->_json([
  250 + 'mail_id' => $mail_ids
  251 + ]);
195 } 252 }
196 253
197 254
198 255
199 256
  257 + /**
  258 + * 远程标签
  259 + * @param $d
  260 + * @throws \Lib\Err
  261 + * @author:dc
  262 + * @time 2023/3/21 14:28
  263 + */
200 private function setFlags($d){ 264 private function setFlags($d){
201 $emails = $this->getEmails(); 265 $emails = $this->getEmails();
202 266
@@ -210,7 +274,7 @@ class Home extends Base { @@ -210,7 +274,7 @@ class Home extends Base {
210 $fv = (int) app()->request($d); 274 $fv = (int) app()->request($d);
211 $fv = $fv ? 1 : 0; 275 $fv = $fv ? 1 : 0;
212 276
213 - $data = db()->all(listsSql::first(dbWhere(['id'=>$mail_ids,'email_id'=>array_column($emails,'id')]))); 277 + $data = db()->all(listsSql::first(dbWhere(['id'=>$mail_ids,'email_id'=>array_column($emails,'id')]),'`id`,`uid`,`email_id`,`folder_id`'));
214 if($data){ 278 if($data){
215 // 查询邮箱 279 // 查询邮箱
216 $emails = array_column($emails,null,'id'); 280 $emails = array_column($emails,null,'id');
@@ -241,10 +305,10 @@ class Home extends Base { @@ -241,10 +305,10 @@ class Home extends Base {
241 break; 305 break;
242 } 306 }
243 // 回收站,已删 未删,软删 307 // 回收站,已删 未删,软删
244 - case 'deleted':{  
245 - $mailInstance->recycle(array_column($uid,'uid'),$folder['origin_folder'],$fv);  
246 - break;  
247 - } 308 +// case 'deleted':{
  309 +// $mailInstance->recycle(array_column($uid,'uid'),$folder['origin_folder'],$fv);
  310 +// break;
  311 +// }
248 } 312 }
249 313
250 $mailInstance = null; 314 $mailInstance = null;
@@ -301,9 +301,26 @@ function start_now_mail(){ @@ -301,9 +301,26 @@ function start_now_mail(){
301 } 301 }
302 302
303 303
  304 +/**
  305 + * 固定文件夹的名称,统一
  306 + * @param $folder
  307 + * @return string
  308 + * @author:dc
  309 + * @time 2023/3/21 16:00
  310 + */
  311 +function folderAlias($folder){
  312 + $folder_map = [
  313 + 'INBOX' => '收件箱',
  314 + // qq的
  315 + 'Sent Messages' => '发件箱',
  316 + 'Drafts' => '草稿箱',
  317 + 'Junk' => '垃圾箱',
  318 + 'Deleted Messages' => '回收站',
  319 + ];
304 320
  321 + return $folder_map[$folder]??$folder;
305 322
306 - 323 +}
307 324
308 325
309 326
@@ -493,6 +493,15 @@ class Imap { @@ -493,6 +493,15 @@ class Imap {
493 493
494 } 494 }
495 495
  496 + /**
  497 + * 移动邮件
  498 + * @author:dc
  499 + * @time 2023/3/21 14:55
  500 + */
  501 + public function move(){
  502 +
  503 + }
  504 +
496 505
497 /** 506 /**
498 * 获取邮件头,并解析 507 * 获取邮件头,并解析
@@ -65,8 +65,12 @@ class Mail { @@ -65,8 +65,12 @@ class Mail {
65 $this->client->login("ssl://{$this->server}:993",$this->username,$this->password); 65 $this->client->login("ssl://{$this->server}:993",$this->username,$this->password);
66 }catch (\Throwable $e){ 66 }catch (\Throwable $e){
67 if($pass_err && $e->getCode() == 403){ 67 if($pass_err && $e->getCode() == 403){
68 - // 登录失败了 ,  
69 - db()->update(\Model\emailSql::$table,['pwd_error'=>1],dbWhere(['email'=>$this->username])); 68 + // 一天中超过 3次失败说明密码错误了
  69 + if(redis()->incr('email_login_error:'.md5($this->username),86400) > 3){
  70 + // 登录失败了 ,
  71 + db()->update(\Model\emailSql::$table,['pwd_error'=>1],dbWhere(['email'=>$this->username]));
  72 + }
  73 + return -1;
70 }else{ 74 }else{
71 logs($e->getMessage()); 75 logs($e->getMessage());
72 } 76 }
@@ -74,6 +78,8 @@ class Mail { @@ -74,6 +78,8 @@ class Mail {
74 return $e->getCode() == 403 ? 0 : -1; 78 return $e->getCode() == 403 ? 0 : -1;
75 79
76 } 80 }
  81 + redis()->delete('email_login_error:'.md5($this->username));
  82 +
77 return 1; 83 return 1;
78 } 84 }
79 85
@@ -106,18 +112,21 @@ class Mail { @@ -106,18 +112,21 @@ class Mail {
106 $folder['parseFolder'] = explode('/',$folder['parseFolder'])[1]; 112 $folder['parseFolder'] = explode('/',$folder['parseFolder'])[1];
107 } 113 }
108 114
109 - try {  
110 - $db->insert(folderSql::$table,[  
111 - 'email_id' => $email_id,  
112 - 'folder' => $folder['parseFolder'],  
113 - 'origin_folder' => $folder['folder'],  
114 - 'uuid' => $uuid,  
115 - 'pid' => $pid  
116 - ],false);  
117 - }catch (\Throwable $e){  
118 - // 这里就不处理失败了 115 + if(!$db->count(folderSql::has(['uuid'=>$uuid]))){
  116 + try {
  117 + $db->insert(folderSql::$table,[
  118 + 'email_id' => $email_id,
  119 + 'folder' => folderAlias($folder['parseFolder']),
  120 + 'origin_folder' => $folder['folder'],
  121 + 'uuid' => $uuid,
  122 + 'pid' => $pid
  123 + ],false);
  124 + }catch (\Throwable $e){
  125 + // 这里就不处理失败了
  126 + }
119 } 127 }
120 128
  129 +
121 } 130 }
122 // $db->commit(); 131 // $db->commit();
123 132
@@ -319,20 +328,24 @@ class Mail { @@ -319,20 +328,24 @@ class Mail {
319 } 328 }
320 329
321 /** 330 /**
322 - * 回收站 331 + * 移动邮件,
323 * @param $uids 332 * @param $uids
324 * @param $folder 333 * @param $folder
325 - * @param $recycle 334 + * @return bool
  335 + * @throws \Exception
326 * @author:dc 336 * @author:dc
327 - * @time 2023/3/21 13:41 337 + * @time 2023/3/21 14:54
328 */ 338 */
329 - public function recycle($uids,$folder,$recycle){ 339 + public function move($uids,$folder,$to_folder){
330 // 选择目录 340 // 选择目录
331 $status = $this->client->selectFolder($folder); 341 $status = $this->client->selectFolder($folder);
332 342
333 - return $this->client->flags($uids,[Imap::FLAGS_DELETED],$recycle ? '+' : '-',true); 343 + return $this->client->folderRename($uids,[Imap::FLAGS_DELETED],$recycle ? '+' : '-',true);
334 344
335 } 345 }
336 346
337 347
  348 +
  349 +
  350 +
338 } 351 }
@@ -94,9 +94,9 @@ class listsSql { @@ -94,9 +94,9 @@ class listsSql {
94 * @author:dc 94 * @author:dc
95 * @time 2023/3/17 16:24 95 * @time 2023/3/17 16:24
96 */ 96 */
97 - public static function first(string $where):string { 97 + public static function first(string $where,$filed='*'):string {
98 98
99 - return "select * from `".self::$table."` where ".$where; 99 + return "select {$filed} from `".self::$table."` where ".$where;
100 } 100 }
101 101
102 102
@@ -31,8 +31,8 @@ return [ @@ -31,8 +31,8 @@ return [
31 'sync' => [\Controller\Home::class, 'sync'], 31 'sync' => [\Controller\Home::class, 'sync'],
32 // 标记为已读 32 // 标记为已读
33 'seen_2_unseen' => [\Controller\Home::class, 'seen_2_unseen'], 33 'seen_2_unseen' => [\Controller\Home::class, 'seen_2_unseen'],
34 - // 回收站,邮件删除,非真实删除  
35 - 'recycle' => [\Controller\Home::class, 'recycle'], 34 + // 邮件移动文件夹
  35 + 'move' => [\Controller\Home::class, 'move'],
36 36
37 37
38 38