企微短剧业务系统

CustomerAssignmentDataRepair.php 19KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: shensong
  5. * Date: 2023/1/3
  6. * Time: 16:55
  7. */
  8. namespace App\Console\Repair;
  9. use App\Log;
  10. use App\Models\BatchTransferCustomer;
  11. use App\Models\CustomerAssignmentTotal;
  12. use App\Models\CustomerDetails;
  13. use App\Models\DjUser;
  14. use App\RedisModel;
  15. use App\Support\EmailQueue;
  16. use Illuminate\Console\Command;
  17. class CustomerAssignmentDataRepair extends Command
  18. {
  19. /**
  20. * The name and signature of the console command.
  21. *
  22. * @var string
  23. */
  24. protected $signature = 'CustomerAssignmentDataRepair';
  25. /**
  26. * The console command description.
  27. *
  28. * @var string
  29. */
  30. protected $description = '客户迁移历史数据处理';
  31. /**
  32. * Create a new command instance.
  33. *
  34. * @return void
  35. */
  36. public function __construct()
  37. {
  38. parent::__construct();
  39. }
  40. public function handle()
  41. {
  42. # 需要处理的迁移列表
  43. $assignmentData = BatchTransferCustomer::query()
  44. ->where('create_time', '>=', '2022-12-01')
  45. ->where('enable', 1)
  46. ->orderBy('id', 'asc')
  47. ->get();
  48. $this->info(date('H:i') . ' 开始执行, 待处理的数据有'.$assignmentData->count());
  49. foreach($assignmentData as $data) {
  50. // 判断迁移类型并分别处理
  51. if(1 == $data['type']) {
  52. $this->customerAssignmentOnJob($data);
  53. } else {
  54. $this->customerAssignmentQuit($data);
  55. }
  56. }
  57. }
  58. public function customerAssignmentOnJob($data)
  59. {
  60. $params = json_decode($data['params'], 1);
  61. $customerName = isset($params['customer_name']) ? $params['customer_name'] : null;
  62. $userIdList = isset($params['user_id_list']) ? $params['user_id_list'] : null;
  63. $addDateStart = isset($params['add_date_start']) ? $params['add_date_start'] : null;
  64. $addDateEnd = isset($params['add_date_end']) ? $params['add_date_end'] : null;
  65. $addWay = isset($params['add_way']) ? $params['add_way'] : null;
  66. $gender = isset($params['gender']) ? $params['gender'] : null;
  67. $payStatus = isset($params['pay_status']) ? $params['pay_status'] : null;
  68. $payNumMin = isset($params['pay_num_min']) ? $params['pay_num_min'] : null;
  69. $payNumMax = isset($params['pay_num_max']) ? $params['pay_num_max'] : null;
  70. $tagType = isset($params['tag_type']) ? $params['tag_type'] : null;
  71. $tagIdList = isset($params['tag_id_list']) ? $params['tag_id_list'] : null;
  72. $lossStatus = 0;
  73. $corpid = $data['corpid'];
  74. $page = 1;
  75. $pageSize = 500;
  76. $filterCustomerList = json_decode($data['filter_customer_list'], 1);
  77. $filterData = [];
  78. foreach($filterCustomerList as $value) {
  79. $filterData[] = $value['external_userid'].'-'.$value['handover_userid'];
  80. }
  81. // 判断是否筛选了客服
  82. if(empty($userIdList)) {
  83. // 没有筛选客服时,从系统中获取所有客服
  84. $userIdList = DjUser::query()
  85. ->where('corpid', $data['corpid'])
  86. ->where('enable', 1)
  87. ->get();
  88. $userIdList = $userIdList->isNotEmpty() ? $userIdList->toArray() : [];
  89. $userIdList = array_column($userIdList, 'user_id');
  90. }
  91. foreach($userIdList as $userId) {
  92. $flag = true;
  93. $customerDataList = [];
  94. while($flag) {
  95. list($customerList, $count) = $this->customerListOnJob($customerName, $userId, $addDateStart,
  96. $addDateEnd, $addWay, $gender, $payStatus, $payNumMin, $payNumMax, $tagType, $tagIdList,
  97. $lossStatus, $corpid, $page, $pageSize);
  98. if($count > 0) {
  99. foreach($customerList as $customer) {
  100. $kk = $customer['external_userid'].'-'.$customer['user_id'];
  101. if(!in_array($kk, $filterData)) {
  102. $customerDataList[] = $customer['external_userid'];
  103. }
  104. }
  105. $pages = ceil($count/500);
  106. if($page >= $pages) {
  107. $flag = false;
  108. } else {
  109. $page++;
  110. }
  111. } else {
  112. $flag = false;
  113. }
  114. }
  115. if(count($customerDataList) > 0) {
  116. if($userId != $data['takeover_userid']) {
  117. // 将数据写入
  118. $result = CustomerAssignmentTotal::query()
  119. ->insert([
  120. 'handover_userid' => $userId,
  121. 'takeover_userid' => $data['takeover_userid'],
  122. 'transfer_success_msg' => $data['transfer_success_msg'],
  123. 'external_userid' => json_encode($customerDataList),
  124. 'type' => 1,
  125. 'status' => 1,
  126. 'portrait_inheritance' => $data['portrait_inheritance'],
  127. 'enable' => 1,
  128. 'corpid' => $data['corpid'],
  129. ]);
  130. } else {
  131. $result = true;
  132. }
  133. if(!$result) {
  134. // 日志记录
  135. Log::logError($this->signature, [
  136. 'errmsg' => '客户在职迁移-插入数据失败',
  137. 'params' => $data,
  138. 'tmp' => [
  139. 'filter_data' => $filterData,
  140. 'user_id_list' => $userIdList,
  141. 'user_id' => $userId,
  142. 'customer_data_list' => $customerDataList,
  143. ],
  144. 'result' => $result,
  145. ], 'script_error');
  146. // 邮件报警
  147. $this->exceptionHandler($this->signature, json_encode([
  148. 'errmsg' => '客户在职迁移-插入数据失败',
  149. 'params' => $data,
  150. 'tmp' => [
  151. 'filter_data' => $filterData,
  152. 'user_id_list' => $userIdList,
  153. 'user_id' => $userId,
  154. 'customer_data_list' => $customerDataList,
  155. ],
  156. 'result' => $result,
  157. ]), '客户在职迁移-'.$this->signature);
  158. }
  159. } else {
  160. // 日志记录
  161. Log::logError($this->signature, [
  162. 'errmsg' => '客户在职迁移-查询客户列表为空',
  163. 'params' => $data,
  164. 'tmp' => [
  165. 'filter_data' => $filterData,
  166. 'user_id_list' => $userIdList,
  167. 'user_id' => $userId,
  168. 'customer_data_list' => $customerDataList,
  169. ],
  170. ], 'script_error');
  171. }
  172. }
  173. }
  174. public function customerAssignmentQuit($data)
  175. {
  176. $params = json_decode($data['params'], 1);
  177. $customerName = isset($params['customer_name']) ? $params['customer_name'] : null;
  178. $userIdList = isset($params['user_id_list']) ? json_decode($params['user_id_list'], 1) : null;
  179. $addDateStart = isset($params['add_date_start']) ? $params['add_date_start'] : null;
  180. $addDateEnd = isset($params['add_date_end']) ? $params['add_date_end'] : null;
  181. $addWay = isset($params['add_way']) ? $params['add_way'] : null;
  182. $payStatus = isset($params['pay_status']) ? $params['pay_status'] : null;
  183. $payNumMin = isset($params['pay_num_min']) ? $params['pay_num_min'] : null;
  184. $payNumMax = isset($params['pay_num_max']) ? $params['pay_num_max'] : null;
  185. $tagType = isset($params['tag_type']) ? $params['tag_type'] : null;
  186. $tagIdList = isset($params['tag_id_list']) ? json_decode($params['tag_id_list']) : null;
  187. $corpid = $data['corpid'];
  188. $page = 1;
  189. $pageSize = 500;
  190. $filterCustomerList = json_decode($data['filter_customer_list'], 1);
  191. $filterData = [];
  192. foreach($filterCustomerList as $value) {
  193. $filterData[] = $value['external_userid'].'-'.$value['handover_userid'];
  194. }
  195. // 判断是否筛选了客服
  196. if(empty($userIdList)) {
  197. // 没有筛选客服时,从系统中获取所有客服
  198. $userIdList = DjUser::query()
  199. ->where('corpid', $data['corpid'])
  200. ->where('enable', 1)
  201. ->get();
  202. $userIdList = $userIdList->isNotEmpty() ? $userIdList->toArray() : [];
  203. $userIdList = array_column($userIdList, 'user_id');
  204. }
  205. foreach($userIdList as $userId) {
  206. $flag = true;
  207. $customerDataList = [];
  208. while($flag) {
  209. list($customerList, $count) = $this->customerListQuit($customerName, $userId, $addDateStart,
  210. $addDateEnd, $addWay, $payStatus, $payNumMin, $payNumMax, $tagType, $tagIdList, $corpid, $page,
  211. $pageSize);
  212. if($count > 0) {
  213. foreach($customerList as $customer) {
  214. $kk = $customer['external_userid'].'-'.$customer['user_id'];
  215. if(!in_array($kk, $filterData)) {
  216. $customerDataList[] = [
  217. 'external_userid' => $customer['external_userid']
  218. ];
  219. }
  220. }
  221. $pages = ceil($count/500);
  222. if($page >= $pages) {
  223. $flag = false;
  224. } else {
  225. $page++;
  226. }
  227. } else {
  228. $flag = false;
  229. }
  230. }
  231. if(count($customerDataList) > 0) {
  232. // 将数据写入
  233. $result = CustomerAssignmentTotal::query()
  234. ->insert([
  235. 'handover_userid' => $userId,
  236. 'takeover_userid' => $data['takeover_userid'],
  237. 'transfer_success_msg' => $data['transfer_success_msg'],
  238. 'external_userid' => json_encode($customerDataList),
  239. 'type' => 2,
  240. 'status' => 1,
  241. 'portrait_inheritance' => $data['portrait_inheritance'],
  242. 'corpid' => $data['corpid']
  243. ]);
  244. if(!$result) {
  245. // 日志记录
  246. Log::logError($this->signature, [
  247. 'errmsg' => '客户在职迁移-插入数据失败',
  248. 'params' => $data,
  249. 'tmp' => [
  250. 'filter_data' => $filterData,
  251. 'user_id_list' => $userIdList,
  252. 'user_id' => $userId,
  253. 'customer_data_list' => $customerDataList,
  254. ],
  255. 'result' => $result,
  256. ], 'script_error');
  257. // 邮件报警
  258. $this->exceptionHandler($this->signature, json_encode([
  259. 'errmsg' => '客户在职迁移-插入数据失败',
  260. 'params' => $data,
  261. 'tmp' => [
  262. 'filter_data' => $filterData,
  263. 'user_id_list' => $userIdList,
  264. 'user_id' => $userId,
  265. 'customer_data_list' => $customerDataList,
  266. ],
  267. 'result' => $result,
  268. ]), '客户在职迁移-'.$this->signature);
  269. }
  270. } else {
  271. // 日志记录
  272. Log::logError($this->signature, [
  273. 'errmsg' => '客户离职迁移-查询客户列表为空',
  274. 'params' => $data,
  275. 'tmp' => [
  276. 'filter_data' => $filterData,
  277. 'user_id_list' => $userIdList,
  278. 'user_id' => $userId,
  279. 'customer_data_list' => $customerDataList,
  280. ],
  281. ], 'script_error');
  282. }
  283. }
  284. }
  285. // 客户管理列表
  286. public function customerListOnJob($customerName, $userId, $addDateStart, $addDateEnd,
  287. $addWay, $gender, $payStatus, $payNumMin, $payNumMax, $tagType, $tagIdList,
  288. $lossStatus, $corpid, $page, $pageSize)
  289. {
  290. $customerQuery = CustomerDetails::suffix($corpid)
  291. // ->where('loss_status', 1)
  292. ->where('corpid', $corpid);
  293. if(!empty($customerName)) {
  294. $customerQuery = $customerQuery->where('name', 'like', '%'.$customerName.'%');
  295. }
  296. if(!empty($userId)) {
  297. $customerQuery = $customerQuery->where('user_id', $userId);
  298. }
  299. if(!empty($addDateStart)) {
  300. $customerQuery = $customerQuery->where('createtime', '>=', strtotime($addDateStart . ' 00:00:00'));
  301. }
  302. if(!empty($addDateEnd)) {
  303. $customerQuery = $customerQuery->where('createtime', '<=', strtotime($addDateEnd . ' 23:59:59'));
  304. }
  305. if(is_numeric($addWay)) {
  306. $customerQuery = $customerQuery->where('add_way', $addWay);
  307. }
  308. if(is_numeric($gender)) {
  309. $customerQuery = $customerQuery->where('gender', $gender);
  310. }
  311. // 付款状态,付款次数筛选
  312. if(is_numeric($payStatus)) {
  313. if(0 == $payStatus) {
  314. $payNumMax=0;
  315. $payNumMin=0;
  316. }else {
  317. if(empty($payNumMin)) {
  318. $payNumMin = 1;
  319. }
  320. }
  321. if(is_numeric($payNumMax)) {
  322. $customerQuery = $customerQuery->where('pay_num', '<=', $payNumMax);
  323. }
  324. if(is_numeric($payNumMin)) {
  325. $customerQuery = $customerQuery->where('pay_num', '>=', $payNumMin);
  326. }
  327. }
  328. if(1 == $tagType) {
  329. $tagRaw = '';
  330. foreach($tagIdList as $k=>$tagId) {
  331. $tagRaw .= $tagId;
  332. if($k < count($tagIdList) -1){
  333. $tagRaw = $tagRaw.' ';
  334. }
  335. }
  336. $customerQuery = $customerQuery->whereRaw('match(`tag_list`) against ("'.$tagRaw.'" in boolean mode)');
  337. }
  338. if(2 == $tagType) {
  339. $tagRaw = '';
  340. foreach($tagIdList as $k=>$tagId) {
  341. $tagRaw .= '+'.$tagId;
  342. if($k < count($tagIdList) -1){
  343. $tagRaw = $tagRaw.' ';
  344. }
  345. }
  346. $customerQuery = $customerQuery->whereRaw('match(`tag_list`) against ("'.$tagRaw.'" in boolean mode)');
  347. }
  348. if(3 == $tagType) {
  349. $customerQuery = $customerQuery->whereNull('tag_list');
  350. }
  351. $customerQueryCount = clone $customerQuery;
  352. $count = $customerQueryCount->selectRaw('count(distinct(`external_userid`)) as count')->first();
  353. $count = $count->count;
  354. $offset = ($page - 1) * $pageSize;
  355. $data = $customerQuery->select(['customer_id', 'name', 'gender', 'external_userid', 'user_id', 'remark',
  356. 'createtime', 'add_way', 'corpid', 'pay_num', 'enable'])
  357. ->groupBy('con_user_cus')
  358. ->offset($offset)
  359. ->limit($pageSize)
  360. ->get()
  361. ->toArray();
  362. return [$data, $count];
  363. }
  364. public function customerListQuit($customerName, $userId, $addDateStart, $addDateEnd, $addWay,
  365. $payStatus, $payNumMin, $payNumMax, $tagType, $tagIdList, $corpid,
  366. $page, $pageSize)
  367. {
  368. $customerQuery = CustomerDetails::suffix($corpid)
  369. // ->where('loss_status', 2)
  370. ->where('corpid', $corpid);
  371. if(!empty($customerName)) {
  372. $customerQuery = $customerQuery->where('name', 'like', '%'.$customerName.'%');}
  373. if(!empty($userId)) {
  374. $customerQuery = $customerQuery->where('user_id', $userId);}
  375. if(!empty($addDateStart)) {
  376. $customerQuery = $customerQuery->where('createtime', '>=', strtotime($addDateStart . ' 00:00:00'));}
  377. if(!empty($addDateEnd)) {
  378. $customerQuery = $customerQuery->where('createtime', '<=', strtotime($addDateEnd . ' 23:59:59'));}
  379. if(is_numeric($addWay)) {
  380. $customerQuery = $customerQuery->where('add_way', $addWay);}
  381. // 付款状态,付款次数筛选
  382. if(is_numeric($payStatus)) {
  383. if(0 == $payStatus) {
  384. $payNumMax=0;
  385. $payNumMin=0;
  386. } else {
  387. if(empty($payNumMin)) {
  388. $payNumMin = 1;
  389. }
  390. }
  391. // $customerQuery = $customerQuery->where('pay_num', '>=', $payNumMin)
  392. // ->where('pay_num', '<=', $payNumMax);
  393. if(is_numeric($payNumMax)) {
  394. $customerQuery = $customerQuery->where('pay_num', '<=', $payNumMax);
  395. }
  396. if(is_numeric($payNumMin)) {
  397. $customerQuery = $customerQuery->where('pay_num', '>=', $payNumMin);
  398. }
  399. }
  400. if(1 == $tagType) {
  401. $tagRaw = '';
  402. foreach($tagIdList as $k=>$tagId) {
  403. $tagRaw .= $tagId;
  404. if($k < count($tagIdList) -1){
  405. $tagRaw = $tagRaw.' ';
  406. }
  407. }
  408. $customerQuery = $customerQuery->whereRaw('match(`tag_list`) against ("'.$tagRaw.'" in boolean mode)');
  409. }
  410. if(2 == $tagType) {
  411. $tagRaw = '';
  412. foreach($tagIdList as $k=>$tagId) {
  413. $tagRaw .= '+'.$tagId;
  414. if($k < count($tagIdList) -1){
  415. $tagRaw = $tagRaw.' ';
  416. }
  417. }
  418. $customerQuery = $customerQuery->whereRaw('match(`tag_list`) against ("'.$tagRaw.'" in boolean mode)');
  419. }
  420. if(3 == $tagType) {
  421. $customerQuery = $customerQuery->whereNull('tag_list');}
  422. $customerQueryCount = clone $customerQuery;
  423. $count = $customerQueryCount->selectRaw('count(distinct(`external_userid`)) as count')->first();
  424. $count = $count->count;
  425. $offset = ($page - 1) * $pageSize;
  426. $data = $customerQuery->select(['customer_id', 'name', 'gender',
  427. 'external_userid', 'user_id', 'remark', 'createtime', 'add_way', 'corpid', 'pay_num'])
  428. ->groupBy('con_user_cus')
  429. ->offset($offset)
  430. ->limit($pageSize)
  431. ->get()
  432. ->toArray();
  433. return [$data, $count];
  434. }
  435. public function exceptionHandler($key, $message, $title)
  436. {
  437. $val = RedisModel::get($key);
  438. if(empty($val)) {
  439. EmailQueue::rPush($title, $message, ['song.shen@kuxuan-inc.com'], []);
  440. RedisModel::set($key, 1);
  441. RedisModel::expire($key, 10*60);
  442. }
  443. }
  444. }