作者 邓超

x

@@ -13,6 +13,7 @@ use Model\listsSql; @@ -13,6 +13,7 @@ use Model\listsSql;
13 use Model\sendJobsSql; 13 use Model\sendJobsSql;
14 use PHPMailer\PHPMailer\PHPMailer; 14 use PHPMailer\PHPMailer\PHPMailer;
15 use PHPMailer\PHPMailer\SMTP; 15 use PHPMailer\PHPMailer\SMTP;
  16 +use Service\SyncMail;
16 use function Swoole\Coroutine\Http\request; 17 use function Swoole\Coroutine\Http\request;
17 18
18 19
@@ -858,23 +859,10 @@ class Home extends Base { @@ -858,23 +859,10 @@ class Home extends Base {
858 859
859 // 是否再次 重新获取 860 // 是否再次 重新获取
860 $reload = app()->request('reload',0,'intval'); 861 $reload = app()->request('reload',0,'intval');
861 - if($reload){  
862 - // 删除原有数据  
863 - db()->delete(bodySql::$table,['lists_id'=>$id]);  
864 - //同步基础信息  
865 - $mail = new Mail($email['email'],base64_decode($email['password']),$email['imap']);  
866 - if($mail->login()==1){  
867 - $folder = db()->value(folderSql::first(['id'=>$data['folder_id']],'origin_folder'));  
868 - if($folder){  
869 - $mail->client->selectFolder($folder);  
870 - $mail->syncUidEmail([$data['uid']],$email['id'],$folder,$data['folder_id'],[],[],db());  
871 - }  
872 - }  
873 - }  
874 862
875 HOME_INFO_BODY: 863 HOME_INFO_BODY:
876 $body = db()->first(bodySql::first($id)); 864 $body = db()->first(bodySql::first($id));
877 - if($body){ 865 + if($body && !$reload){
878 $data['body'] = json_decode($body['text_html'],true); 866 $data['body'] = json_decode($body['text_html'],true);
879 867
880 $charset = 'utf-8'; 868 $charset = 'utf-8';
@@ -897,8 +885,8 @@ class Home extends Base { @@ -897,8 +885,8 @@ class Home extends Base {
897 885
898 if(!empty($bd['path'])){ 886 if(!empty($bd['path'])){
899 887
900 - $data['body'][$bdk]['name'] = @base64_decode($bd['name']);  
901 - $data['body'][$bdk]['filename'] = @base64_decode($bd['filename']); 888 + $data['body'][$bdk]['name'] = MailFun::isBase64($bd['name']) ? @base64_decode($bd['name']) : $bd['name'];
  889 + $data['body'][$bdk]['filename'] = MailFun::isBase64($bd['filename']) ? @base64_decode($bd['filename']) : $bd['filename'];
902 // 进行编码转换 会出现未知bug 890 // 进行编码转换 会出现未知bug
903 // if($charset && strtolower($charset) != 'utf-8' && strtolower($charset) != 'utf8'){ 891 // if($charset && strtolower($charset) != 'utf-8' && strtolower($charset) != 'utf8'){
904 // $data['body'][$bdk]['name'] = @iconv($charset,'utf-8',$data['body'][$bdk]['name']); 892 // $data['body'][$bdk]['name'] = @iconv($charset,'utf-8',$data['body'][$bdk]['name']);
@@ -945,31 +933,17 @@ class Home extends Base { @@ -945,31 +933,17 @@ class Home extends Base {
945 'data' => $data 933 'data' => $data
946 ]; 934 ];
947 } 935 }
  936 +
948 // 循环几次 937 // 循环几次
949 if($data['uid']&&$sync_num < 1){ 938 if($data['uid']&&$sync_num < 1){
950 - $mail = new Mail($email['email'],base64_decode($email['password']),$email['imap']);  
951 -  
952 - if($mail->login()==1){  
953 -  
954 - $folder = db()->value(folderSql::first(['id'=>$data['folder_id']],'origin_folder'));  
955 - if($folder){  
956 - $ret = $mail->syncBody($folder,$data['uid'],$id);  
957 - $sync_num++;  
958 - if($ret){  
959 - goto HOME_INFO_BODY;  
960 - }  
961 - }  
962 -  
963 - } 939 + $folder = db()->value(folderSql::first(['id'=>$data['folder_id']],'origin_folder'));
  940 + (new SyncMail($data['email_id']))->mail($folder,[$data['uid']],true);
  941 + $sync_num++;
  942 + $reload = 0;
  943 + goto HOME_INFO_BODY;
964 } 944 }
965 logs('超过读取body次数 '.$data['id']); 945 logs('超过读取body次数 '.$data['id']);
966 946
967 - if(isset($mail)){  
968 - if(!$mail->client->hasMail($data['uid'])){  
969 - app()->e('mail_not');  
970 - }  
971 - }  
972 -  
973 }else{ 947 }else{
974 logs('读取body 没有查询到数据 '.$id.'-'.($email['email']??'')); 948 logs('读取body 没有查询到数据 '.$id.'-'.($email['email']??''));
975 } 949 }
@@ -98,19 +98,25 @@ class Attachment { @@ -98,19 +98,25 @@ class Attachment {
98 98
99 /** 99 /**
100 * 保存 文件到目录 100 * 保存 文件到目录
101 - * @param string $filename 绝对路径的目录 文件名  
102 - * @return bool 101 + * @param string $path 绝对路径的目录
  102 + * @param string $filename 文件名
  103 + * @return bool|string
103 * @author:dc 104 * @author:dc
104 * @time 2024/9/21 17:10 105 * @time 2024/9/21 17:10
105 */ 106 */
106 - public function save(string $filename):bool {  
107 - $path = dirname($filename); 107 + public function save(string $path, string $filename = ''):bool|string {
  108 +
  109 + $filename = $filename ? : (md5($this->getContent()).'.'.$this->getExtension());
  110 +
108 if(!is_dir($path)){ 111 if(!is_dir($path)){
109 @mkdir($path,0775,true); 112 @mkdir($path,0775,true);
110 } 113 }
  114 +
  115 + $path = rtrim($path,'/').'/';
  116 +
111 // 保存文件 117 // 保存文件
112 - if(@file_put_contents($filename,$this->getContent())){  
113 - return true; 118 + if(@file_put_contents($path.$filename,$this->getContent())){
  119 + return $path.$filename;
114 } 120 }
115 121
116 return false; 122 return false;
@@ -244,6 +244,8 @@ class Body { @@ -244,6 +244,8 @@ class Body {
244 244
245 // 默认编码 245 // 默认编码
246 if(!$data->Charset) $data->Charset = 'utf-8'; 246 if(!$data->Charset) $data->Charset = 'utf-8';
  247 + // 处理content id中意外的字符串
  248 + $data->set('Content-ID',trim(str_replace(['"','<','>'],'',$data->get('Content-ID'))));
247 249
248 return $data; 250 return $data;
249 } 251 }
@@ -319,17 +321,24 @@ class Body { @@ -319,17 +321,24 @@ class Body {
319 * 读取附件 目前有2中 321 * 读取附件 目前有2中
320 * 1是 attachment 附件 就是文件 322 * 1是 attachment 附件 就是文件
321 * 2是 inline 是嵌套在html代码中的,一半情况只有图片才会这样做 323 * 2是 inline 是嵌套在html代码中的,一半情况只有图片才会这样做
322 - * @param bool $inline 是否是读取嵌入html中的图片或者其他,一半情况 图片路径以 cid:xxx 324 + * @param bool|null $inline 是否是读取嵌入html中的图片或者其他,一半情况 图片路径以 cid:xxx
323 * @return Attachment[] 325 * @return Attachment[]
324 * @author:dc 326 * @author:dc
325 * @time 2024/9/23 10:23 327 * @time 2024/9/23 10:23
326 */ 328 */
327 - public function getAttachment(bool $inline = false):array { 329 + public function getAttachment(bool|null $inline = null):array {
328 $attachment = []; 330 $attachment = [];
329 foreach ($this->items as $item){ 331 foreach ($this->items as $item){
330 // 有的邮箱服务器 不带inline,就只有通过content-id来识别了 332 // 有的邮箱服务器 不带inline,就只有通过content-id来识别了
331 - if((!$inline && $item->eq('Content-Disposition','attachment')) || ($inline && $item->get('Content-ID'))){  
332 - $attachment[] = new Attachment($item); 333 + $isAttachment = $item->eq('Content-Disposition','attachment');
  334 + if($inline === null){
  335 + if($isAttachment || $item->get('Content-ID')){
  336 + $attachment[] = new Attachment($item);
  337 + }
  338 + }else{
  339 + if((!$inline && $isAttachment) || ($inline && $item->get('Content-ID'))){
  340 + $attachment[] = new Attachment($item);
  341 + }
333 } 342 }
334 } 343 }
335 344
@@ -134,10 +134,13 @@ class Header{ @@ -134,10 +134,13 @@ class Header{
134 */ 134 */
135 private function parseAddress(string $address, $isArray = false){ 135 private function parseAddress(string $address, $isArray = false){
136 $arr = []; 136 $arr = [];
137 - foreach (explode(',',$address) as $k=>$str){  
138 - $arr[$k] = Address::make($str);  
139 - if($isArray) $arr[$k] = $arr[$k]->toArray(); 137 + if($address){
  138 + foreach (explode(',',$address) as $k=>$str){
  139 + $arr[$k] = Address::make($str);
  140 + if($isArray) $arr[$k] = $arr[$k]->toArray();
  141 + }
140 } 142 }
  143 +
141 return $arr; 144 return $arr;
142 } 145 }
143 146
@@ -201,7 +201,7 @@ class SyncMail { @@ -201,7 +201,7 @@ class SyncMail {
201 */ 201 */
202 public function mail(string|\Lib\Imap\Request\Folder $folder, array $uids = [],$isBody = false){ 202 public function mail(string|\Lib\Imap\Request\Folder $folder, array $uids = [],$isBody = false){
203 if(is_string($folder)){ 203 if(is_string($folder)){
204 - $folder = $this->imap->folder($folder); 204 + $folder = $this->imap->folder($folder)->exec();
205 } 205 }
206 206
207 $folder_id = $this->db->value(folderSql::first([ 207 $folder_id = $this->db->value(folderSql::first([
@@ -298,25 +298,54 @@ class SyncMail { @@ -298,25 +298,54 @@ class SyncMail {
298 // 是否同步body内容 298 // 是否同步body内容
299 if($isBody){ 299 if($isBody){
300 300
301 -// $body = [  
302 -// 'lists_id' => $id,  
303 -// 'text_html' => []  
304 -// ];  
305 -//  
306 -// foreach ($item->getBody()->getItems() as $item){  
307 -// $body['text_html'][] = [  
308 -// 'body' => $item->body,  
309 -// 'content-type' => $item->get('content-type'),  
310 -// 'content-id' => $item->get('content-id'),  
311 -// 'charset' => $item->get('charset')  
312 -// ];  
313 -// }  
314 -//  
315 -// if($this->db->count(bodySql::has($id))){  
316 -// $this->db->update(bodySql::$table,$body,'`lists_id` = '.$id,false);  
317 -// }else{  
318 -// $this->db->insert(bodySql::$table,$body,false);  
319 -// } 301 + $body = [
  302 + 'lists_id' => $id,
  303 + 'text_html' => []
  304 + ];
  305 +
  306 +
  307 + $body['text_html'][] = [
  308 + 'body' => base64_encode($item->getBody()->getHtml() ? : $item->getBody()->getText()),
  309 + 'type' => 'text/html',
  310 + 'charset' => 'utf-8',
  311 + 'encode' => 'base64',
  312 + ];
  313 +
  314 + // 处理附件
  315 + foreach ($item->getBody()->getAttachment() as $itemBody){
  316 + $tmp = [
  317 + 'body' => '',
  318 + 'type' => $itemBody->getFileType(),
  319 + 'charset' => 'binary',
  320 + 'encode' => $itemBody->data->get('content-transfer-encoding'),
  321 + 'name' => $itemBody->getFilename(),
  322 + 'filename' => $itemBody->getFilename(),
  323 + 'path' => $itemBody->save(MAIL_ATTACHMENT_PATH)
  324 + ];
  325 + if(!$tmp){
  326 + throw new \Exception('请检查附件是否有写入权限');
  327 + }
  328 + if($itemBody->getContentId()){
  329 + $tmp['content-id'] = $itemBody->getContentId();
  330 + }
  331 + if($itemBody->data->get('Content-Disposition')){
  332 + $tmp['content-disposition'] = $itemBody->data->get('Content-Disposition');
  333 + }
  334 + $tmp['signName'] = explode('/',$tmp['path']);
  335 + $tmp['signName'] = end($tmp['signName']);
  336 +
  337 + $body['text_html'][] = $tmp;
  338 +
  339 + }
  340 +
  341 + if($this->db->count(bodySql::has($id))){
  342 + $this->db->update(bodySql::$table,$body,'`lists_id` = '.$id,false);
  343 + }else{
  344 + $this->db->insert(bodySql::$table,$body,false);
  345 + }
  346 +
  347 + // 更新描述
  348 + $this->db->update(listsSql::$table,['description'=>mb_substr($item->getBody()->getText(),0,150)],dbWhere(['id'=> $id]));
320 349
321 } 350 }
322 351