作者 邓超

to es

  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 +