正在显示
1 个修改的文件
包含
245 行增加
和
0 行删除
cmd/sync_to_es_v2.php
0 → 100644
1 | +<?php | ||
2 | + | ||
3 | +//error_reporting(); | ||
4 | + | ||
5 | +require_once "../vendor/autoload.php"; | ||
6 | + | ||
7 | + | ||
8 | +/** | ||
9 | + * 把mysql的数据同步到es | ||
10 | + * @author:dc | ||
11 | + * @time 2025/3/4 10:19 | ||
12 | + * Class SyncToEsCmd | ||
13 | + */ | ||
14 | +class SyncToEsCmd { | ||
15 | + | ||
16 | + public $isStop = false; | ||
17 | + | ||
18 | + /** | ||
19 | + * 文件夹 | ||
20 | + * @var array | ||
21 | + */ | ||
22 | + public $folders = []; | ||
23 | + | ||
24 | + /** | ||
25 | + * @var \Lib\Db | ||
26 | + */ | ||
27 | + public $fob_db; | ||
28 | + | ||
29 | + | ||
30 | + /** | ||
31 | + * 是否是自动回复 | ||
32 | + * @author:dc | ||
33 | + * @time 2025/6/6 11:07 | ||
34 | + */ | ||
35 | + public function isAuto($db,$data){ | ||
36 | + $is_auto = $db ->count('select count(*) from `lists_auto` where `list_id` = '.$data['id']) ? 1 : 0; | ||
37 | + | ||
38 | + if($is_auto) return 1; | ||
39 | + | ||
40 | + $filter = redis()->get('ai_email_filter_lists',[]); | ||
41 | + $filter = is_array($filter) ? $filter : []; | ||
42 | + foreach ($filter as $f){ | ||
43 | + list($t,$str) = $f; | ||
44 | + $haystack = ''; | ||
45 | + if($t==2){ | ||
46 | + $haystack = $data['subject']; | ||
47 | + }elseif ($t==1){ | ||
48 | + $haystack = $data['from']; | ||
49 | + } | ||
50 | + if($haystack && $str && stripos($haystack,$str)!==false){ | ||
51 | + return 1; | ||
52 | + } | ||
53 | + } | ||
54 | + return 0; | ||
55 | + } | ||
56 | + | ||
57 | + public function handler(){ | ||
58 | + | ||
59 | + $handler = function ($signal){ | ||
60 | + _echo('收到进程信号 '. $signal); | ||
61 | + // 可以处理其他程序 | ||
62 | + $this->isStop = true; | ||
63 | + }; | ||
64 | + pcntl_signal(SIGTERM, $handler); // 这个是kill | ||
65 | + pcntl_signal(SIGINT, $handler); // 这个是 ctrl+c | ||
66 | +// pcntl_signal(SIGHUP, $handler); | ||
67 | + | ||
68 | + $es = es(); // 第一个库,即将丢弃 | ||
69 | + $es2 = es('email_lists'); // 第二个库 新 | ||
70 | + | ||
71 | + $db = db(); | ||
72 | + $this->fob_db = fob_mysql(); | ||
73 | + $startTime = time(); | ||
74 | + while (1){ | ||
75 | + | ||
76 | + if(time()-43200 > $startTime){ | ||
77 | + break; | ||
78 | + } | ||
79 | + | ||
80 | + // 检查是否接收到信号 | ||
81 | + pcntl_signal_dispatch(); | ||
82 | + | ||
83 | + if($this->isStop) { | ||
84 | + _echo('已退出进程'); | ||
85 | + break; | ||
86 | + } | ||
87 | + | ||
88 | + $id = redis()->lPop('sync_to_es'); | ||
89 | + $code = 500; | ||
90 | + if($id){ | ||
91 | + $doc_id = ''; | ||
92 | + try { | ||
93 | + $data = $db->throw()->first(\Model\listsSql::first('`id` = '.$id)); | ||
94 | + }catch (Throwable $e){ | ||
95 | + redis()->rPush('sync_to_es',$id); | ||
96 | + _echo('sync to es '.$e->getMessage()); | ||
97 | + break; | ||
98 | + } | ||
99 | + | ||
100 | + if($data){ | ||
101 | + try { | ||
102 | + // 文件夹 | ||
103 | + if(empty($this->folders[$data['folder_id']])){ | ||
104 | + $this->folders[$data['folder_id']] = $db->throw()->value(\Model\folderSql::first($data['folder_id'],'folder')); | ||
105 | + } | ||
106 | + | ||
107 | + // 为文件夹打标 方便查询 | ||
108 | + $data['folder_as_int'] = folder2int($this->folders[$data['folder_id']]); | ||
109 | + | ||
110 | + // 是否是自动回复 | ||
111 | + if($data['folder_as_int'] === 1){ | ||
112 | + $data['is_auto'] = $this->isAuto($db,$data); | ||
113 | + } | ||
114 | + | ||
115 | + // postid ai邮箱要用 这个是查询黑格 | ||
116 | + list($data['postid'],$data['source']) = $this->getPostid($data['email_id'],$data['udate']); | ||
117 | + | ||
118 | + }catch (Throwable $e){ | ||
119 | + redis()->rPush('sync_to_es',$id); | ||
120 | + _echo('sync to es '.$e->getMessage()); | ||
121 | + break; | ||
122 | + } | ||
123 | + | ||
124 | + $data = $this->getEsData($data); | ||
125 | + $doc_id = $data['email_id'].'_'.$data['folder_id'].'_'.$data['uid']; | ||
126 | + | ||
127 | + // 新 | ||
128 | + $code = $es2->save($doc_id,$data); | ||
129 | + | ||
130 | + // 这个验证数据没问题后会丢弃 | ||
131 | + $code = $es->save($doc_id,$data); | ||
132 | + | ||
133 | + } | ||
134 | + | ||
135 | + if($code!==200){ | ||
136 | + @file_put_contents(LOG_PATH.'/sync_es_fail.log',$id."\n",FILE_APPEND); | ||
137 | + _echo('同步es: '.$doc_id.'===>'.$code); | ||
138 | + } | ||
139 | + | ||
140 | + }else{ | ||
141 | + sleep(1); | ||
142 | + } | ||
143 | + } | ||
144 | + | ||
145 | + } | ||
146 | + | ||
147 | + protected $postids = []; | ||
148 | + | ||
149 | + /** | ||
150 | + * 项目id | ||
151 | + * @author:dc | ||
152 | + * @time 2025/5/20 15:44 | ||
153 | + */ | ||
154 | + public function getPostid($email_id,$udate){ | ||
155 | + | ||
156 | + // 查询历史记录 | ||
157 | + $times = redis()->getSet('fob_bind_mail_times:'.$email_id,300,function ($email_id){ | ||
158 | + | ||
159 | + $times = $this->fob_db->throw()->first("select `post_id`,`bind_time`,`source` from `e_mail_binds_log` where `email_id` = {$email_id} order by `bind_time` desc "); | ||
160 | + if(!$times){ | ||
161 | + return []; | ||
162 | + } | ||
163 | + | ||
164 | + return $times; | ||
165 | + | ||
166 | + },$email_id); | ||
167 | + | ||
168 | + foreach ($times as $time){ | ||
169 | + $t = strtotime($time['bind_time']); | ||
170 | + // 邮件收到的时间是否大于绑定时间 | ||
171 | + if($udate > $t){ | ||
172 | + $data = $time; | ||
173 | + break; | ||
174 | + } | ||
175 | + } | ||
176 | + | ||
177 | + // 没有找到历史,就找绑定表 | ||
178 | + if(empty($data)){ | ||
179 | + $data = redis()->getSet('fob_bind_mail:'.$email_id,300,function ($email_id){ | ||
180 | + return $this->fob_db->throw()->first("select `post_id`,`source` from `e_mail_binds` where `email_id` = '{$email_id}' and `deleted_at` is null order by `id` desc limit 1"); | ||
181 | + },$email_id); | ||
182 | + | ||
183 | + } | ||
184 | + | ||
185 | + return [ | ||
186 | + $data['post_id']??0, | ||
187 | + $data['source']??0, | ||
188 | + ]; | ||
189 | + } | ||
190 | + | ||
191 | + | ||
192 | + public function getEsData($data){ | ||
193 | + if(!empty($data['id'])){ | ||
194 | + $data['uuid'] = $data['id']; | ||
195 | + unset($data['id']); | ||
196 | + } | ||
197 | + | ||
198 | + $data['from'] = [ | ||
199 | + 'email' => $data['from'], | ||
200 | + 'name' => $data['from_name']??'' | ||
201 | + ]; | ||
202 | + unset($data['from_name']); | ||
203 | + unset($data['date']); | ||
204 | + | ||
205 | + if(!empty($data['to_name']) && strlen($data['to_name'])>10000){ | ||
206 | + $data['to_name'] = @json_decode($data['to_name'],true); | ||
207 | + if(is_array($data['to_name'])){ | ||
208 | + $data['to_name'] = array_map(function ($v){ | ||
209 | + $v['name'] = ''; | ||
210 | + return $v; | ||
211 | + },$data['to_name']); | ||
212 | + $data['to_name'] = array_slice($data['to_name'],0,100); | ||
213 | + $data['to_name'] = json_encode($data['to_name']); | ||
214 | + }else{ | ||
215 | + $data['to_name'] = ''; | ||
216 | + } | ||
217 | + } | ||
218 | + $data['description'] = str_replace(["\n"],"",$data['description']); | ||
219 | + // unset($data['to_name']); | ||
220 | + | ||
221 | + if(!empty($data['created_at'])){ | ||
222 | + $data['created_at'] = date('Y-m-d\TH:i:s',strtotime($data['created_at'])); | ||
223 | + } | ||
224 | + if(!empty($data['updated_at'])){ | ||
225 | + $data['updated_at'] = date('Y-m-d\TH:i:s',strtotime($data['updated_at'])); | ||
226 | + } | ||
227 | + $data['references'] = empty($data['references']) ? '' : $data['references']; | ||
228 | + return $data; | ||
229 | + } | ||
230 | + | ||
231 | + | ||
232 | +} | ||
233 | + | ||
234 | +(new SyncToEsCmd())->handler(); | ||
235 | + | ||
236 | +return 1; | ||
237 | + | ||
238 | + | ||
239 | + | ||
240 | + | ||
241 | + | ||
242 | + | ||
243 | + | ||
244 | + | ||
245 | + |
-
请 注册 或 登录 后发表评论