| 
@@ -3,6 +3,8 @@ | 
 | 
@@ -3,6 +3,8 @@ | 
| 
3
 | 
 namespace Lib\Mail;
 | 
3
 | 
 namespace Lib\Mail;
 | 
| 
4
 | 
 
 | 
4
 | 
 
 | 
| 
5
 | 
 use Lib\DbPool;
 | 
5
 | 
 use Lib\DbPool;
 | 
| 
 | 
   | 
6
 | 
+use Model\folderSql;
 | 
| 
 | 
   | 
7
 | 
+use Model\listsSql;
 | 
| 
6
 | 
 
 | 
8
 | 
 
 | 
| 
7
 | 
 /**
 | 
9
 | 
 /**
 | 
| 
8
 | 
  * 操作邮件
 | 
10
 | 
  * 操作邮件
 | 
 | 
@@ -59,11 +61,14 @@ class Mail { | 
 | 
@@ -59,11 +61,14 @@ class Mail { | 
| 
59
 | 
             $pid = 0;
 | 
61
 | 
             $pid = 0;
 | 
| 
60
 | 
             foreach ($folder['id'] as $k=>$item){
 | 
62
 | 
             foreach ($folder['id'] as $k=>$item){
 | 
| 
61
 | 
                 // 插入到数据库
 | 
63
 | 
                 // 插入到数据库
 | 
| 
62
 | 
-                $pid = Folder::_insert(
 | 
 | 
   | 
| 
63
 | 
-                    $this->client->getId(),
 | 
 | 
   | 
| 
64
 | 
-                    $folder['name'][$k],
 | 
 | 
   | 
| 
65
 | 
-                    $item,
 | 
 | 
   | 
| 
66
 | 
-                    $pid
 | 
64
 | 
+                $pid = $db->insert(
 | 
| 
 | 
   | 
65
 | 
+                    folderSql::$table,
 | 
| 
 | 
   | 
66
 | 
+                    [
 | 
| 
 | 
   | 
67
 | 
+                        'email_id' => $this->client->getId(),
 | 
| 
 | 
   | 
68
 | 
+                        'folder' => $folder['name'][$k],
 | 
| 
 | 
   | 
69
 | 
+                        'origin_folder' => $item,
 | 
| 
 | 
   | 
70
 | 
+                        'pid' => $pid
 | 
| 
 | 
   | 
71
 | 
+                    ]
 | 
| 
67
 | 
                 );
 | 
72
 | 
                 );
 | 
| 
68
 | 
             }
 | 
73
 | 
             }
 | 
| 
69
 | 
         }
 | 
74
 | 
         }
 | 
 | 
@@ -74,32 +79,35 @@ class Mail { | 
 | 
@@ -74,32 +79,35 @@ class Mail { | 
| 
74
 | 
 
 | 
79
 | 
 
 | 
| 
75
 | 
     /**
 | 
80
 | 
     /**
 | 
| 
76
 | 
      * 同步邮件
 | 
81
 | 
      * 同步邮件
 | 
| 
77
 | 
-     * @param $email
 | 
 | 
   | 
| 
78
 | 
      * @param $email_id
 | 
82
 | 
      * @param $email_id
 | 
| 
79
 | 
      * @param $folder_id
 | 
83
 | 
      * @param $folder_id
 | 
| 
80
 | 
      * @param string $folder
 | 
84
 | 
      * @param string $folder
 | 
| 
 | 
   | 
85
 | 
+     * @param null|DbPool $db
 | 
| 
81
 | 
      * @return bool
 | 
86
 | 
      * @return bool
 | 
| 
 | 
   | 
87
 | 
+     * @throws \Exception
 | 
| 
82
 | 
      * @author:dc
 | 
88
 | 
      * @author:dc
 | 
| 
83
 | 
-     * @time 2023/2/6 15:04
 | 
89
 | 
+     * @time 2023/2/18 9:54
 | 
| 
84
 | 
      */
 | 
90
 | 
      */
 | 
| 
85
 | 
-    public static function syncMail($email,$email_id,$folder_id,$folder='INBOX'):bool {
 | 
91
 | 
+    public function syncMail($email_id,$folder_id,$folder='INBOX',$db = null):bool {
 | 
| 
 | 
   | 
92
 | 
+        $db = $db ? $db : db();
 | 
| 
86
 | 
         // 选择文件夹
 | 
93
 | 
         // 选择文件夹
 | 
| 
87
 | 
-        try {
 | 
 | 
   | 
| 
88
 | 
-            $status =   static::$client[$email]->selectFolder($folder);
 | 
 | 
   | 
| 
89
 | 
-        }catch (\Throwable $e){
 | 
 | 
   | 
| 
90
 | 
-            Log::error($email.' 选择文件夹错误:'.$e->getMessage());
 | 
 | 
   | 
| 
91
 | 
-            return false;
 | 
 | 
   | 
| 
92
 | 
-        }
 | 
94
 | 
+        $status =   $this->client->selectFolder($folder);
 | 
| 
 | 
   | 
95
 | 
+
 | 
| 
93
 | 
         // 是否有邮件
 | 
96
 | 
         // 是否有邮件
 | 
| 
94
 | 
         if (!isset($status['EXISTS']) || !$status['EXISTS']){
 | 
97
 | 
         if (!isset($status['EXISTS']) || !$status['EXISTS']){
 | 
| 
95
 | 
             return true;
 | 
98
 | 
             return true;
 | 
| 
96
 | 
         }
 | 
99
 | 
         }
 | 
| 
97
 | 
 
 | 
100
 | 
 
 | 
| 
98
 | 
         // 更新数量
 | 
101
 | 
         // 更新数量
 | 
| 
99
 | 
-        Folder::_updateNum($folder_id,$status['EXISTS'], $status['UNSEEN']??null);
 | 
102
 | 
+        $db->update(
 | 
| 
 | 
   | 
103
 | 
+            folderSql::$table,
 | 
| 
 | 
   | 
104
 | 
+            ['exsts'=>$status['EXISTS'],'unseen'=>$status['UNSEEN']??0],
 | 
| 
 | 
   | 
105
 | 
+            dbWhere(['id'=>$folder_id])
 | 
| 
 | 
   | 
106
 | 
+        );
 | 
| 
 | 
   | 
107
 | 
+
 | 
| 
100
 | 
 
 | 
108
 | 
 
 | 
| 
101
 | 
-        // 最后拉取的时间,如果是第一次
 | 
 | 
   | 
| 
102
 | 
-        $lastMsgno   =   EList::_lastMsgno($email_id, $folder_id);
 | 
109
 | 
+        // 最后拉取的msgno
 | 
| 
 | 
   | 
110
 | 
+        $lastMsgno   =   $db->value(listsSql::lastMsgno($email_id,$folder_id));
 | 
| 
103
 | 
 
 | 
111
 | 
 
 | 
| 
104
 | 
         $nu = 20;
 | 
112
 | 
         $nu = 20;
 | 
| 
105
 | 
 
 | 
113
 | 
 
 | 
 | 
@@ -118,29 +126,19 @@ class Mail { | 
 | 
@@ -118,29 +126,19 @@ class Mail { | 
| 
118
 | 
         }
 | 
126
 | 
         }
 | 
| 
119
 | 
 
 | 
127
 | 
 
 | 
| 
120
 | 
 
 | 
128
 | 
 
 | 
| 
121
 | 
-
 | 
 | 
   | 
| 
122
 | 
-        SYNCEMAILLIST:
 | 
 | 
   | 
| 
123
 | 
-        // 是否有id
 | 
 | 
   | 
| 
124
 | 
-        $dataids = EList::_getIdsByMsgno($email_id,$folder_id,$msgno);
 | 
 | 
   | 
| 
125
 | 
-
 | 
 | 
   | 
| 
126
 | 
         // 循环
 | 
129
 | 
         // 循环
 | 
| 
127
 | 
-        $results = static::$client[$email]->fetchHeader($msgno);
 | 
 | 
   | 
| 
128
 | 
-
 | 
130
 | 
+        $results = $this->client->fetchHeader($msgno);
 | 
| 
129
 | 
         if($results){
 | 
131
 | 
         if($results){
 | 
| 
130
 | 
-            DB::beginTransaction();
 | 
 | 
   | 
| 
131
 | 
             // 批量插入
 | 
132
 | 
             // 批量插入
 | 
| 
132
 | 
             foreach ($results as $key=>$result){
 | 
133
 | 
             foreach ($results as $key=>$result){
 | 
| 
133
 | 
-                if($key == $status['EXISTS']){
 | 
 | 
   | 
| 
134
 | 
-                    $end = true;
 | 
 | 
   | 
| 
135
 | 
-                }
 | 
 | 
   | 
| 
136
 | 
-                $header = &$result['HEADER.FIELDS'];
 | 
134
 | 
+                $header = $result['HEADER.FIELDS'];
 | 
| 
137
 | 
 
 | 
135
 | 
 
 | 
| 
138
 | 
                 foreach ($result['FLAGS'] as $k=>$FLAG){
 | 
136
 | 
                 foreach ($result['FLAGS'] as $k=>$FLAG){
 | 
| 
139
 | 
                     $result['FLAGS'][$k] = strtolower(str_replace('\\','',$FLAG));
 | 
137
 | 
                     $result['FLAGS'][$k] = strtolower(str_replace('\\','',$FLAG));
 | 
| 
140
 | 
                 }
 | 
138
 | 
                 }
 | 
| 
141
 | 
                 try {
 | 
139
 | 
                 try {
 | 
| 
142
 | 
 
 | 
140
 | 
 
 | 
| 
143
 | 
-                    $file_header = &$result['BODYSTRUCTURE'];
 | 
141
 | 
+                    $file_header = $result['BODYSTRUCTURE'];
 | 
| 
144
 | 
 
 | 
142
 | 
 
 | 
| 
145
 | 
                     // 没有收件人
 | 
143
 | 
                     // 没有收件人
 | 
| 
146
 | 
                     if(!empty($header['To'])){
 | 
144
 | 
                     if(!empty($header['To'])){
 | 
 | 
@@ -149,11 +147,9 @@ class Mail { | 
 | 
@@ -149,11 +147,9 @@ class Mail { | 
| 
149
 | 
                         $header['To'] = [];
 | 
147
 | 
                         $header['To'] = [];
 | 
| 
150
 | 
                     }
 | 
148
 | 
                     }
 | 
| 
151
 | 
 
 | 
149
 | 
 
 | 
| 
152
 | 
-
 | 
 | 
   | 
| 
153
 | 
                     $header['From'] = MailFun::toOrFrom($header['From']);
 | 
150
 | 
                     $header['From'] = MailFun::toOrFrom($header['From']);
 | 
| 
154
 | 
 
 | 
151
 | 
 
 | 
| 
155
 | 
                     $data   =   [
 | 
152
 | 
                     $data   =   [
 | 
| 
156
 | 
-                        'id'    =>  $dataids[$key]??0,
 | 
 | 
   | 
| 
157
 | 
                         'msgno'   =>  $key,
 | 
153
 | 
                         'msgno'   =>  $key,
 | 
| 
158
 | 
                         'uid'   =>  $result['UID'],
 | 
154
 | 
                         'uid'   =>  $result['UID'],
 | 
| 
159
 | 
                         'subject'   =>  $header['Subject'],
 | 
155
 | 
                         'subject'   =>  $header['Subject'],
 | 
 | 
@@ -166,7 +162,7 @@ class Mail { | 
 | 
@@ -166,7 +162,7 @@ class Mail { | 
| 
166
 | 
                         'date'   =>  isset($header['Date'])&&$header['Date'] ? strtotime(is_array($header['Date']) ? $header['Date'][0] : $header['Date']) : strtotime($result['INTERNALDATE']),
 | 
162
 | 
                         'date'   =>  isset($header['Date'])&&$header['Date'] ? strtotime(is_array($header['Date']) ? $header['Date'][0] : $header['Date']) : strtotime($result['INTERNALDATE']),
 | 
| 
167
 | 
                         'message_id'   =>  $header['Message-ID']??'',
 | 
163
 | 
                         'message_id'   =>  $header['Message-ID']??'',
 | 
| 
168
 | 
                         'udate'   =>  strtotime($result['INTERNALDATE']),
 | 
164
 | 
                         'udate'   =>  strtotime($result['INTERNALDATE']),
 | 
| 
169
 | 
-//                      'size'   =>  $result['RFC822.SIZE'],
 | 
165
 | 
+                        'size'   =>  $result['RFC822.SIZE']??0,
 | 
| 
170
 | 
                         'recent'   =>  in_array('recent',$result['FLAGS']),
 | 
166
 | 
                         'recent'   =>  in_array('recent',$result['FLAGS']),
 | 
| 
171
 | 
                         'seen'   =>  in_array('seen',$result['FLAGS']),
 | 
167
 | 
                         'seen'   =>  in_array('seen',$result['FLAGS']),
 | 
| 
172
 | 
                         'draft'   =>  in_array('draft',$result['FLAGS']),
 | 
168
 | 
                         'draft'   =>  in_array('draft',$result['FLAGS']),
 | 
 | 
@@ -174,29 +170,50 @@ class Mail { | 
 | 
@@ -174,29 +170,50 @@ class Mail { | 
| 
174
 | 
                         'answered'   =>  in_array('answered',$result['FLAGS']),
 | 
170
 | 
                         'answered'   =>  in_array('answered',$result['FLAGS']),
 | 
| 
175
 | 
                         'folder_id'   =>  $folder_id,
 | 
171
 | 
                         'folder_id'   =>  $folder_id,
 | 
| 
176
 | 
                         'email_id'    =>  $email_id,
 | 
172
 | 
                         'email_id'    =>  $email_id,
 | 
| 
177
 | 
-                        'uuid'  =>  $email_id.$folder_id.$result['UID'],
 | 
173
 | 
+                        'uuid'  =>  md5($email_id.$folder_id.$result['UID']),
 | 
| 
178
 | 
                         'is_file'  =>  MailFun::isFile($file_header[$key]['BODYSTRUCTURE']??[]) //是否附件
 | 
174
 | 
                         'is_file'  =>  MailFun::isFile($file_header[$key]['BODYSTRUCTURE']??[]) //是否附件
 | 
| 
179
 | 
                     ];
 | 
175
 | 
                     ];
 | 
| 
180
 | 
                 }catch (\Throwable $e){
 | 
176
 | 
                 }catch (\Throwable $e){
 | 
| 
181
 | 
-                    Log::error('邮件解析失败:'.$e->getMessage().print_r($result,true));
 | 
177
 | 
+                    logs(
 | 
| 
 | 
   | 
178
 | 
+                        '邮件解析失败:'.PHP_EOL.$e->getMessage().PHP_EOL.print_r($result,true),
 | 
| 
 | 
   | 
179
 | 
+                        LOG_PATH.'/imap/mail/'.$email_id.'/'.$result['UID'].'.log'
 | 
| 
 | 
   | 
180
 | 
+                    );
 | 
| 
182
 | 
                     unset($results[$key]);
 | 
181
 | 
                     unset($results[$key]);
 | 
| 
183
 | 
                     continue;
 | 
182
 | 
                     continue;
 | 
| 
184
 | 
                 }
 | 
183
 | 
                 }
 | 
| 
185
 | 
 
 | 
184
 | 
 
 | 
| 
186
 | 
                 $results[$key]  =   $data;
 | 
185
 | 
                 $results[$key]  =   $data;
 | 
| 
187
 | 
             }
 | 
186
 | 
             }
 | 
| 
188
 | 
-            EList::_insertAll(array_values($results));
 | 
 | 
   | 
| 
189
 | 
-            // 提交
 | 
 | 
   | 
| 
190
 | 
-            DB::commit();
 | 
187
 | 
+
 | 
| 
 | 
   | 
188
 | 
+            // 保存数据,这里其实不用再次写循环的。我想写一个
 | 
| 
 | 
   | 
189
 | 
+            $uuids = $db->all(listsSql::hasUuid(array_column($results,'uuid')));
 | 
| 
 | 
   | 
190
 | 
+            $uuids = $uuids ? array_column($uuids,null,'uuid') : [];
 | 
| 
 | 
   | 
191
 | 
+
 | 
| 
 | 
   | 
192
 | 
+            $db->transaction();
 | 
| 
 | 
   | 
193
 | 
+            foreach ($results as $insert){
 | 
| 
 | 
   | 
194
 | 
+                if(empty($uuids[$insert['uuid']])){
 | 
| 
 | 
   | 
195
 | 
+                    // 新增
 | 
| 
 | 
   | 
196
 | 
+                    $db->insert(listsSql::$table,$insert);
 | 
| 
 | 
   | 
197
 | 
+                }else{
 | 
| 
 | 
   | 
198
 | 
+                    // 修改
 | 
| 
 | 
   | 
199
 | 
+                    $db->update(
 | 
| 
 | 
   | 
200
 | 
+                        listsSql::$table,
 | 
| 
 | 
   | 
201
 | 
+                        $insert,
 | 
| 
 | 
   | 
202
 | 
+                        dbWhere(['id'=>$uuids[$insert['uuid']]['id']])
 | 
| 
 | 
   | 
203
 | 
+                    );
 | 
| 
 | 
   | 
204
 | 
+                }
 | 
| 
 | 
   | 
205
 | 
+            }
 | 
| 
 | 
   | 
206
 | 
+            $db->commit();
 | 
| 
 | 
   | 
207
 | 
+
 | 
| 
 | 
   | 
208
 | 
+            // 结束操作了
 | 
| 
191
 | 
         }
 | 
209
 | 
         }
 | 
| 
192
 | 
 
 | 
210
 | 
 
 | 
| 
193
 | 
 
 | 
211
 | 
 
 | 
| 
194
 | 
         // 再次调用
 | 
212
 | 
         // 再次调用
 | 
| 
195
 | 
-        Mail::syncMail($email,$email_id,$folder_id,$folder);
 | 
213
 | 
+        $this->syncMail($email_id,$folder_id,$folder,$db);
 | 
| 
196
 | 
 
 | 
214
 | 
 
 | 
| 
197
 | 
         return true;
 | 
215
 | 
         return true;
 | 
| 
198
 | 
 
 | 
216
 | 
 
 | 
| 
199
 | 
-
 | 
 | 
   | 
| 
200
 | 
     }
 | 
217
 | 
     }
 | 
| 
201
 | 
 
 | 
218
 | 
 
 | 
| 
202
 | 
 
 | 
219
 | 
 
 |