CrmRemove.php 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617
  1. <?php
  2. namespace app\jobs;
  3. use app\model\CrmRemoveCustomer;
  4. use app\model\CrmRemoveImportLog;
  5. use app\model\CrmRemoveRecord;
  6. use app\model\Customer;
  7. use app\model\CustomerInvalidLog;
  8. use app\model\CustomerPortraitField;
  9. use app\model\CustomerSource;
  10. use app\model\CustomerVisitLog;
  11. use app\model\Employee;
  12. use cutExcel\MyreadFilter;
  13. use OSS\Core\OssException;
  14. use PHPExcel_Shared_Date;
  15. use PhpOffice\PhpSpreadsheet\IOFactory;
  16. use think\facade\Db;
  17. use think\facade\Log;
  18. use think\queue\Job;
  19. use think\facade\Queue;
  20. use toolkits\Aec;
  21. class CrmRemove
  22. {
  23. public function fire(Job $job, $queuedata)
  24. {
  25. try {
  26. if ($job->attempts() > 2) {
  27. $job->delete();
  28. }
  29. $is_done = $this->jobDone($queuedata);
  30. if($is_done){
  31. $job->delete();
  32. } else {
  33. // 导入过程失败
  34. $log = CrmRemoveImportLog::where('id', $queuedata['id'])->find();
  35. $tmp_file = $log['tmp_path'];
  36. if (file_exists($tmp_file)) {
  37. unlink($tmp_file);
  38. }
  39. $log->tmp_path = '';
  40. $log->status = 3;
  41. $log->save();
  42. $job->delete();
  43. }
  44. } catch (OssException $e) {
  45. //报错直接结束
  46. $job->delete();
  47. }
  48. }
  49. public function failed($queuedata)
  50. {
  51. // ...任务达到最大重试次数后,失败了
  52. }
  53. // 导入
  54. private function jobDone($data){
  55. $log_id = $data['id'];
  56. $new_queue = false;
  57. $log = CrmRemoveImportLog::where('id', $log_id)->findOrEmpty();
  58. if ($log->isEmpty()) {
  59. return false;
  60. }
  61. if ($log['status'] == 2) {
  62. return true;
  63. }
  64. if (empty($log['tmp_path'])) {
  65. // 开始导入
  66. $ali_oss_bindurl = config('app.ali_oss_bindurl');
  67. $path = 'https://' . $ali_oss_bindurl . '/' . $log['path'];
  68. // 抓取远程Excel文件的内容
  69. try {
  70. $content = file_get_contents($path);
  71. if (!$content) {
  72. return false;
  73. }
  74. } catch (\Exception $e) {
  75. return false;
  76. }
  77. // 保存Excel文件到本地临时文件
  78. $run_path = runtime_path();
  79. $tmp_file = tempnam($run_path, 'PHPExcel');
  80. file_put_contents($tmp_file, $content);
  81. $log->tmp_path = $tmp_file;
  82. $log->save();
  83. } else {
  84. $tmp_file = $log['tmp_path'];
  85. }
  86. //实例化PHPExcel类
  87. $reader = IOFactory::createReader('Xlsx');
  88. if (!$reader->canRead($tmp_file)) {
  89. Log::record('-------------')->save();
  90. Log::record('file canRead false')->save();
  91. Log::record('-------------')->save();
  92. return false;
  93. }
  94. $rows = 20;
  95. if ($log['execute_rows'] == 0) {
  96. $start_rows = 1;
  97. } else {
  98. $start_rows = $log['execute_rows'];
  99. }
  100. $end_rows = $start_rows + $rows;
  101. $MyReadFilter = new MyreadFilter($start_rows, $end_rows);
  102. $reader->setReadFilter($MyReadFilter);
  103. $reader->setReadDataOnly(true);
  104. $objPHPExcel = $reader->load($tmp_file);
  105. $sheet = $objPHPExcel->getSheet(0); //excel中的第一张sheet
  106. $highestRow = $sheet->getHighestRow(); // 取得总行数
  107. $highestColumn = $sheet->getHighestColumn(); // 取得总列数
  108. \PhpOffice\PhpSpreadsheet\Cell\Coordinate::columnIndexFromString($highestColumn);
  109. $lines = $highestRow - 1;
  110. $end = true;
  111. $root_id = $log['root_id'];
  112. if ($lines > 0) {
  113. //客户来源扩展字段
  114. $source = CustomerSource::where(['root_id'=> $root_id])->column('id','source');
  115. //员工
  116. $employee_list = Employee::where([['root_id', '=', $root_id], ['uid', '>', 0], ['state', '=', '在职']])->field('id,name,uid,org_id,root_id,phone')->select()->toArray();
  117. $employee = [];
  118. foreach ($employee_list as $k => $v) {
  119. if ($v['phone']) {
  120. $employee[$v['phone']] = $v;
  121. }
  122. }
  123. $datas = [];
  124. $j = $start_rows + 1;
  125. for ($j; $j <= $highestRow; $j++) {
  126. $date_check = ['K', 'O', 'P', 'Q', 'R', 'S', 'T', 'V', 'X', 'Y'];
  127. $date_value = [];
  128. foreach ($date_check as $v) {
  129. try {
  130. $get_value = $objPHPExcel->getActiveSheet()->getCell($v . $j)->getValue();
  131. if (empty($get_value)) {
  132. $date_value[$v] = '';
  133. continue;
  134. }
  135. if ($v !== "O") {
  136. $date_value[$v] = gmdate('Y-m-d H:i:s', PHPExcel_Shared_Date::ExcelToPHP($get_value));
  137. } else {
  138. $date_value[$v] = gmdate('Y-m-d', PHPExcel_Shared_Date::ExcelToPHP($get_value));
  139. }
  140. } catch (\Exception $e) {
  141. $date_value[$v] = '';
  142. }
  143. }
  144. $datas[] = [
  145. 'employee_name' => trim($objPHPExcel->getActiveSheet()->getCell("A" . $j)->getValue()),
  146. 'employee_phone' => trim($objPHPExcel->getActiveSheet()->getCell("B" . $j)->getValue()),
  147. 'name' => trim($objPHPExcel->getActiveSheet()->getCell("C" . $j)->getValue()),
  148. 'sex' => trim($objPHPExcel->getActiveSheet()->getCell("D" . $j)->getValue()),
  149. 'phone' => trim($objPHPExcel->getActiveSheet()->getCell("E" . $j)->getValue()),
  150. 'level' => trim($objPHPExcel->getActiveSheet()->getCell("F" . $j)->getValue()),
  151. 'community_name' => trim($objPHPExcel->getActiveSheet()->getCell("G" . $j)->getValue()),
  152. 'square' => trim($objPHPExcel->getActiveSheet()->getCell("H" . $j)->getValue()),
  153. 'housetype_arrow' => trim($objPHPExcel->getActiveSheet()->getCell("I" . $j)->getValue()),
  154. 'follow' => trim($objPHPExcel->getActiveSheet()->getCell("J" . $j)->getValue()),
  155. 'addtime' => !empty($date_value["K"]) ? $date_value["K"] : date('Y-m-d H:i:s'),
  156. 'age_range' => trim($objPHPExcel->getActiveSheet()->getCell("L" . $j)->getValue()),
  157. 'source' => trim($objPHPExcel->getActiveSheet()->getCell("M" . $j)->getValue()),
  158. 'state' => trim($objPHPExcel->getActiveSheet()->getCell("N" . $j)->getValue()),
  159. 'add_wechat_time' => !empty($date_value["O"]) ? $date_value["O"] : null,
  160. 'valid_time' => !empty($date_value["P"]) ? $date_value["P"] : null,
  161. 'daodian_time' => !empty($date_value["Q"]) ? $date_value["Q"] : null,
  162. 'liangfang_time' => !empty($date_value["R"]) ? $date_value["R"] : null,
  163. 'daochang_time' => !empty($date_value["S"]) ? $date_value["S"] : null,
  164. 'qiandan_time' => !empty($date_value["T"]) ? $date_value["T"] : null,
  165. 'qiandan_money' => trim($objPHPExcel->getActiveSheet()->getCell("U" . $j)->getValue()),
  166. 'zhuandan_time' => !empty($date_value["V"]) ? $date_value["V"] : null,
  167. 'zhuandan_money' => trim($objPHPExcel->getActiveSheet()->getCell("W" . $j)->getValue()),
  168. 'maika_time' => !empty($date_value["X"]) ? $date_value["X"] : null,
  169. 'wuxiao_time' => !empty($date_value["Y"]) ? $date_value["Y"] : null,
  170. 'row'=> $j
  171. ];
  172. }
  173. //error 手机号错误数量 repeat 手机号重复数量
  174. $rs = ['ok' => 0, 'error' => 0, 'repeat' => 0];
  175. $error = [];
  176. $portrait_field = CustomerPortraitField::with('select')->where([['root_id', '=', $root_id], ['keyname', 'in', ['housetype_arrow', 'wechat', 'follow', 'add_wechat_time']]])->select()->toArray();
  177. $save_data = [];
  178. $wx_state = CustomerVisitLog::changeState('无效', 'n');
  179. $aec = new Aec(config('app.aec_key'), config('app.aec_iv'));
  180. foreach ($datas as $k => $v) {
  181. if(isset($employee[$v['employee_phone']])) {
  182. $employee_id = $employee[$v['employee_phone']]['id'];
  183. $one_cus = [];
  184. $one_log = [];
  185. $one_cus['phone1'] = $one_cus['phone2'] = '';
  186. ////2023-02-15 修改手机号可以输入多个
  187. $s = true;
  188. $ls_phone = explode('、', $v['phone']);
  189. if(!empty($ls_phone) && is_array($ls_phone)){
  190. $p = 0;
  191. foreach ($ls_phone as $k2 => $v2) {
  192. if ($this->checkphone($v2)) {
  193. $field = $p ? 'phone'.$p : 'phone';
  194. $one_cus[$field] = $aec->encrypt($v2);
  195. $p+=1;
  196. }
  197. if($p>2) break;//只取三个有效手机号
  198. }
  199. if($p>0) $s = false;
  200. }
  201. if($s){
  202. $rs['error']++;
  203. $one_error['rows'] = $v['row'];
  204. $one_error['type'] = 2; // 1、员工不存在 2、手机号格式错误
  205. $one_error['phone'] = $v['phone'];
  206. $error[] = $one_error;
  207. continue;
  208. }
  209. // 手机号验重
  210. $encrypt_phone = $one_cus['phone'];
  211. $is_have = Customer::where([['employee_id', '=', $employee_id], ['phone', '=', $encrypt_phone]])->findOrEmpty();
  212. if (!$is_have->isEmpty()) {
  213. $rs['error']++;
  214. $one_error['rows'] = $v['row'];
  215. $one_error['type'] = 3; // 1、员工不存在 2、手机号格式错误 3、手机号重复
  216. $one_error['phone'] = $v['phone'];
  217. $error[] = $one_error;
  218. continue;
  219. }
  220. // 来源判断处理
  221. $source_id = 0;
  222. if (!empty($v['source'])) {
  223. if (!isset($source[$v['source']])) {
  224. $source_id = CustomerSource::insertGetId(['source'=> $v['source'], 'root_id'=> $root_id]);
  225. $source[$v['source']] = $source_id;
  226. } else {
  227. $source_id = $source[$v['source']];
  228. }
  229. }
  230. // 数据处理
  231. $one_cus['employee_id'] = $employee_id;
  232. $one_cus['name'] = $v['name'];
  233. $one_cus['sex'] = $v['sex'];
  234. $one_cus['level'] = in_array($v['level'], ['A', 'B', 'C', 'D']) ? $v['level'] : '';
  235. $one_cus['community_name'] = $v['community_name'];
  236. $one_cus['square'] = $v['square'];
  237. $one_cus['community_name'] = $v['community_name'];
  238. $state = Customer::changeState($v['state'], 'n');
  239. $one_cus['state'] = $state ? $state : 0;
  240. $one_cus['org_id'] = $employee[$v['employee_phone']]['org_id'];
  241. $one_cus['bad_phone'] = 0;
  242. $one_cus['source_id'] = $source_id;
  243. $one_cus['addtime'] = date('Y-m-d H:i:s', strtotime($v['addtime']));
  244. $one_cus['age_range'] = $v['age_range'];
  245. $one_cus['deposit_money'] = $v['qiandan_money'] ? $v['qiandan_money'] : 0;
  246. $one_cus['signed_money'] = $v['zhuandan_money'] ? $v['zhuandan_money'] : 0;
  247. // 标记有效时间
  248. if ($v['valid_time']) {
  249. $one_cus['valid_time'] = $v['valid_time'];
  250. } else {
  251. // 如果没填写有效时间
  252. $min_valid_time = '';
  253. $time_field = ['daodian_time', 'liangfang_time', 'daochang_time', 'qiandan_time', 'zhuandan_time'];
  254. foreach ($time_field as $t) {
  255. if (empty($v[$t])) {
  256. continue;
  257. }
  258. if (empty($min_valid_time)) {
  259. $min_valid_time = $v[$t];
  260. } elseif (strtotime($v[$t]) < strtotime($min_valid_time)) {
  261. $min_valid_time = $v[$t];
  262. }
  263. }
  264. if ($min_valid_time) {
  265. $one_cus['valid_time'] = $min_valid_time;
  266. }
  267. }
  268. $youxiao = false;
  269. // 当前状态是待确认
  270. $now_state = $one_cus['state'];
  271. if ($now_state == 0) {
  272. $one_log[] = [
  273. 'type'=> '',
  274. 'employee_id'=> $employee_id,
  275. 'user_id'=> $employee[$v['employee_phone']]['uid'],
  276. 'state'=> CustomerVisitLog::changeState('待确认', 'n'),
  277. 'addtime'=> date('Y-m-d H:i:s'),
  278. 'org_id'=> $employee[$v['employee_phone']]['org_id'],
  279. 'customer_employee_id'=> $employee_id,
  280. 'customer_org_id'=> $employee[$v['employee_phone']]['org_id']
  281. ];
  282. } elseif ($now_state == 7) {
  283. // 无效状态清空员工
  284. $one_cus['employee_id'] = null;
  285. }
  286. // 到店记录
  287. $dd_state = CustomerVisitLog::changeState('已到店', 'n');
  288. if (!empty($v['daodian_time']) || $now_state == $dd_state) {
  289. $youxiao = true;
  290. $one_log[] = [
  291. 'type'=> '',
  292. 'employee_id'=> $employee_id,
  293. 'user_id'=> $employee[$v['employee_phone']]['uid'],
  294. 'state'=> $dd_state,
  295. 'addtime'=> !empty($v['daodian_time']) ? $v['daodian_time'] : date('Y-m-d H:i:s'),
  296. 'confirm_date'=> !empty($v['daodian_time']) ? $v['daodian_time'] : date('Y-m-d H:i:s'),
  297. 'org_id'=> $employee[$v['employee_phone']]['org_id'],
  298. 'customer_employee_id'=> $employee_id,
  299. 'customer_org_id'=> $employee[$v['employee_phone']]['org_id']
  300. ];
  301. }
  302. // 量房记录
  303. $lf_state = CustomerVisitLog::changeState('已量房', 'n');
  304. if (!empty($v['liangfang_time']) || $now_state == $lf_state) {
  305. $youxiao = true;
  306. $one_log[] = [
  307. 'type'=> '',
  308. 'employee_id'=> $employee_id,
  309. 'user_id'=> $employee[$v['employee_phone']]['uid'],
  310. 'state'=> $lf_state,
  311. 'addtime'=> !empty($v['liangfang_time']) ? $v['liangfang_time'] : date('Y-m-d H:i:s'),
  312. 'confirm_date'=> !empty($v['liangfang_time']) ? $v['liangfang_time'] : date('Y-m-d H:i:s'),
  313. 'org_id'=> $employee[$v['employee_phone']]['org_id'],
  314. 'customer_employee_id'=> $employee_id,
  315. 'customer_org_id'=> $employee[$v['employee_phone']]['org_id']
  316. ];
  317. }
  318. // 到场记录
  319. $dc_state = CustomerVisitLog::changeState('已到场', 'n');
  320. if (!empty($v['daochang_time']) || $now_state == $dc_state) {
  321. $youxiao = true;
  322. $one_log[] = [
  323. 'type'=> '',
  324. 'employee_id'=> $employee_id,
  325. 'user_id'=> $employee[$v['employee_phone']]['uid'],
  326. 'state'=> $dc_state,
  327. 'addtime'=> !empty($v['daochang_time']) ? $v['daochang_time'] : date('Y-m-d H:i:s'),
  328. 'confirm_date'=> !empty($v['daochang_time']) ? $v['daochang_time'] : date('Y-m-d H:i:s'),
  329. 'org_id'=> $employee[$v['employee_phone']]['org_id'],
  330. 'customer_employee_id'=> $employee_id,
  331. 'customer_org_id'=> $employee[$v['employee_phone']]['org_id']
  332. ];
  333. }
  334. // 签单记录
  335. $qd_state = CustomerVisitLog::changeState('已交定', 'n');
  336. if (!empty($v['qiandan_time']) || $now_state == $qd_state) {
  337. $youxiao = true;
  338. $qiandan_money = 0;
  339. if (!empty($v['qiandan_money'])) {
  340. $qiandan_money = $v['qiandan_money'];
  341. }
  342. $one_log[] = [
  343. 'type'=> '',
  344. 'employee_id'=> $employee_id,
  345. 'user_id'=> $employee[$v['employee_phone']]['uid'],
  346. 'state'=> $qd_state,
  347. 'addtime'=> !empty($v['qiandan_time']) ? $v['qiandan_time'] : date('Y-m-d H:i:s'),
  348. 'confirm_date'=> !empty($v['qiandan_time']) ? $v['qiandan_time'] : date('Y-m-d H:i:s'),
  349. 'org_id'=> $employee[$v['employee_phone']]['org_id'],
  350. 'customer_employee_id'=> $employee_id,
  351. 'customer_org_id'=> $employee[$v['employee_phone']]['org_id'],
  352. 'money'=> $qiandan_money
  353. ];
  354. }
  355. // 转单记录
  356. $zd_state = CustomerVisitLog::changeState('已签单', 'n');
  357. if (!empty($v['zhuandan_time']) || $now_state == $zd_state) {
  358. $youxiao = true;
  359. $zhuandan_money = 0;
  360. if (!empty($v['zhuandan_money'])) {
  361. $zhuandan_money = $v['zhuandan_money'];
  362. }
  363. $one_log[] = [
  364. 'type'=> '',
  365. 'employee_id'=> $employee_id,
  366. 'user_id'=> $employee[$v['employee_phone']]['uid'],
  367. 'state'=> $zd_state,
  368. 'addtime'=> !empty($v['zhuandan_time']) ? $v['zhuandan_time'] : date('Y-m-d H:i:s'),
  369. 'confirm_date'=> !empty($v['zhuandan_time']) ? $v['zhuandan_time'] : date('Y-m-d H:i:s'),
  370. 'org_id'=> $employee[$v['employee_phone']]['org_id'],
  371. 'customer_employee_id'=> $employee_id,
  372. 'customer_org_id'=> $employee[$v['employee_phone']]['org_id'],
  373. 'money'=> $zhuandan_money
  374. ];
  375. }
  376. // 卖卡记录
  377. $mk_state = CustomerVisitLog::changeState('已卖卡', 'n');
  378. if (!empty($v['maika_time']) || $now_state == $mk_state) {
  379. $youxiao = true;
  380. $one_log[] = [
  381. 'type'=> '',
  382. 'employee_id'=> $employee_id,
  383. 'user_id'=> $employee[$v['employee_phone']]['uid'],
  384. 'state'=> $mk_state,
  385. 'addtime'=> !empty($v['maika_time']) ? $v['maika_time'] : date('Y-m-d H:i:s'),
  386. 'confirm_date'=> !empty($v['maika_time']) ? $v['maika_time'] : date('Y-m-d H:i:s'),
  387. 'org_id'=> $employee[$v['employee_phone']]['org_id'],
  388. 'customer_employee_id'=> $employee_id,
  389. 'customer_org_id'=> $employee[$v['employee_phone']]['org_id']
  390. ];
  391. }
  392. // 无效记录
  393. if (!empty($v['wuxiao_time']) || $now_state == $wx_state) {
  394. $one_log[] = [
  395. 'type'=> '',
  396. 'employee_id'=> $employee_id,
  397. 'user_id'=> $employee[$v['employee_phone']]['uid'],
  398. 'state'=> $wx_state,
  399. 'addtime'=> !empty($v['wuxiao_time']) ? $v['wuxiao_time'] : date('Y-m-d H:i:s'),
  400. 'confirm_date'=> !empty($v['wuxiao_time']) ? $v['wuxiao_time'] : date('Y-m-d H:i:s'),
  401. 'org_id'=> $employee[$v['employee_phone']]['org_id'],
  402. 'customer_employee_id'=> $employee_id,
  403. 'customer_org_id'=> $employee[$v['employee_phone']]['org_id']
  404. ];
  405. $inv_log = [
  406. 'employee_id'=> $employee_id,
  407. 'designer_id'=> 0,
  408. 'org_id'=> $employee[$v['employee_phone']]['org_id'],
  409. 'root_id'=> $employee[$v['employee_phone']]['root_id'],
  410. 'cus_addtime'=> $one_cus['addtime'],
  411. 'source_id'=> $one_cus['source_id'],
  412. 'status'=> $youxiao ? 1 : 2
  413. ];
  414. if ($one_cus['valid_time']) {
  415. $inv_log['valid_time'] = $one_cus['valid_time'];
  416. }
  417. }
  418. $ext = [];
  419. // 扩展字段 户型、装修关注点、是否加微
  420. foreach ($portrait_field as $kk => $vv) {
  421. switch ($vv['keyname']) {
  422. case 'housetype_arrow':
  423. $house_type_val = 0;
  424. if (!empty($vv['select'])) {
  425. foreach ($vv['select'] as $vvv) {
  426. if ($vvv['name'] == $v['housetype_arrow']) {
  427. $house_type_val = $vvv['id'];
  428. }
  429. }
  430. }
  431. if ($house_type_val) {
  432. $ext[] = ['id'=> $vv['id'], 'keyname'=> 'housetype_arrow', 'value'=> (string)$house_type_val];
  433. }
  434. break;
  435. case 'wechat':
  436. if (!empty($v['add_wechat_time'])) {
  437. $have_wechat_val = ['是', '有'];
  438. $have_wechat = 0;
  439. if (!empty($vv['select'])) {
  440. foreach ($vv['select'] as $vvv) {
  441. if (in_array($vvv['name'], $have_wechat_val)) {
  442. $have_wechat = $vvv['id'];
  443. }
  444. }
  445. }
  446. if ($have_wechat) {
  447. $ext[] = ['id'=> $vv['id'], 'keyname'=> 'wechat', 'value'=> (string)$have_wechat];
  448. }
  449. }
  450. break;
  451. case 'add_wechat_time':
  452. if (!empty($v['add_wechat_time'])) {
  453. $ext[] = ['id'=> $vv['id'], 'keyname'=> 'add_wechat_time', 'value'=> (string)$v['add_wechat_time']];
  454. }
  455. break;
  456. case 'follow':
  457. $follow_list = explode('、', $v['follow']);
  458. $follow_ids = [];
  459. if (!empty($vv['select'])) {
  460. foreach ($vv['select'] as $vvv) {
  461. if (in_array($vvv['name'], $follow_list)) {
  462. $follow_ids[] = $vvv['id'];
  463. }
  464. }
  465. }
  466. if (!empty($follow_ids)) {
  467. $ext[] = ['id'=> $vv['id'], 'keyname'=> 'follow', 'value'=> implode(',', $follow_ids)];
  468. }
  469. break;
  470. default:
  471. break;
  472. }
  473. }
  474. $one_cus['ext'] = $ext ? json_encode($ext) : NULL;
  475. $one['customer'] = $one_cus;
  476. $one['log'] = $one_log;
  477. $save_data[] = $one;
  478. $rs['ok']++;
  479. } else {
  480. $rs['error']++;
  481. $one_error['rows'] = $v['row'];
  482. $one_error['type'] = 1; // 1、员工不存在 2、手机号格式错误
  483. $one_error['phone'] = $v['phone'];
  484. $error[] = $one_error;
  485. }
  486. }
  487. Db::startTrans();
  488. try {
  489. foreach ($save_data as $k => $v) {
  490. $customer_id = Customer::insertGetId($v['customer']);
  491. if (!empty($v['log'])) {
  492. foreach($v['log'] as $v_log){
  493. $v_log['customer_id'] = $customer_id;
  494. $res_id = CustomerVisitLog::insertGetId($v_log);
  495. if (!empty($inv_log) && $v_log['state'] == $wx_state) {
  496. $inv_log['customer_id'] = $customer_id;
  497. $inv_log['visitlog_id'] = $res_id;
  498. CustomerInvalidLog::create($inv_log);
  499. }
  500. }
  501. }
  502. $log_customer['log_id'] = $log_id;
  503. $log_customer['customer_id'] = $customer_id;
  504. $log_customer['root_id'] = $root_id;
  505. CrmRemoveCustomer::create($log_customer);
  506. }
  507. Db::commit();
  508. } catch (\Exception $e) {
  509. trace($e->getMessage(), 'error');
  510. // 回滚事务
  511. Db::rollback();
  512. return false;
  513. }
  514. // 执行记录
  515. $excute_log['log_id'] = $log_id;
  516. $excute_log['employee_id'] = $log['employee_id'];
  517. $excute_log['start_rows'] = $start_rows;
  518. $excute_log['end_rows'] = $end_rows;
  519. $excute_log['error_count'] = count($error);
  520. $excute_log['content'] = $error ? json_encode($error) : null;
  521. CrmRemoveRecord::create($excute_log);
  522. if ($log['status'] == 0) {
  523. $log->status = 1;
  524. }
  525. $log->count = $log['count'] + count($datas);
  526. $log->avaliable_count = $log['avaliable_count'] + $rs['ok'];
  527. $log->bad_phone_num = $log['bad_phone_num'] + $rs['error'];
  528. $log->execute_rows = $highestRow;
  529. $log->save();
  530. if (count($datas) > 0) {
  531. $end = false;
  532. } else {
  533. $log->tmp_path = '';
  534. $log->status = 2;
  535. $log->save();
  536. if (file_exists($tmp_file)) {
  537. unlink($tmp_file);
  538. }
  539. }
  540. } else {
  541. $log->tmp_path = '';
  542. $log->status = 2;
  543. $log->save();
  544. if (file_exists($tmp_file)) {
  545. unlink($tmp_file);
  546. }
  547. }
  548. if($lines == $rows) {
  549. $end = false;
  550. }
  551. if (!$end) {
  552. $new_queue = true;
  553. }
  554. if ($new_queue == true) {
  555. $jobHandlerClassName = 'app\jobs\CrmRemove';
  556. $jobQueueName = 'crm_remove';
  557. $orderData = ['id'=> $log_id]; //这个是需要传到消费者的数据
  558. Queue::later(0, $jobHandlerClassName, $orderData, $jobQueueName);
  559. }
  560. return true;
  561. }
  562. private function checkphone($value)
  563. {
  564. if (preg_match("/^1[356789]\d{9}$/", $value)) {
  565. return true;
  566. } else {
  567. return false;
  568. }
  569. }
  570. }