CustomService.php 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868
  1. <?php
  2. namespace app\admin\service\consultant;
  3. use app\admin\service\member\MemberService;
  4. use app\model\Consultant;
  5. use app\model\MarketCustomer;
  6. use app\model\MarketCustomerFollow;
  7. use app\model\MarketCustomerLogs;
  8. use app\model\Member;
  9. use app\model\SysDept;
  10. use support\Db;
  11. use support\exception\BusinessException;
  12. use support\Request;
  13. use Tinywan\Jwt\JwtToken;
  14. class CustomService
  15. {
  16. const DIFF_TIME = (60 * 60 * 24 * 30);
  17. /**
  18. * Notes: 返回选项配置信息
  19. * User: yb
  20. * Date: 2024/8/5
  21. * Time: 16:05
  22. * @return array
  23. */
  24. public static function config()
  25. {
  26. return MarketCustomer::config();
  27. }
  28. public static function commonSearch($params)
  29. {
  30. $where = [];
  31. $currentTime = time();
  32. $diffNums = self::DIFF_TIME;
  33. $deptIds = TeamService::getIdsByUser();
  34. if (false === $deptIds) {
  35. //无权限
  36. $where[] = ['dept_id', '=', 0];
  37. } else if (is_array($deptIds)) {
  38. //指定团队下的权限
  39. if (!empty($params['dept_id'])) {
  40. $deptId = end($params['dept_id']);
  41. $deptIds = SysDept::where('dept_super_path','like', "%/{$deptId}/%")->where('dept_category', '=', TeamService::DEPT_CATEGORY)->pluck('dept_id')->toArray();
  42. }
  43. $where[] = [function($query) use ($deptIds) {
  44. $query->whereIn('dept_id', $deptIds);
  45. }];
  46. } else {
  47. if (!empty($params['dept_id'])) {
  48. $deptId = end($params['dept_id']);
  49. $deptIds = SysDept::where('dept_super_path','like', "%/{$deptId}/%")->where('dept_category', '=', TeamService::DEPT_CATEGORY)->pluck('dept_id')->toArray();
  50. $where[] = [function($query) use ($deptIds) {
  51. $query->whereIn('dept_id', $deptIds);
  52. }];
  53. }
  54. }
  55. if (!empty($params['name'])) {
  56. $keywords = $params['name'];
  57. $where[] = [function($query) use ($keywords) {
  58. $query->orWhere('name', 'like', "%{$keywords}%")->orWhere('mobile', 'like', "%{$keywords}%");
  59. }];
  60. }
  61. if (!empty($params['report_status'])) {
  62. if ($params['report_status'] == -1) {
  63. //待审核
  64. $where[] = ['check_status', '=', 1];
  65. } else {
  66. $where[] = ['check_status', '=', 2];
  67. }
  68. if ($params['report_status'] == 1) {
  69. //已报备
  70. $where[] = [function($query) use ($diffNums, $currentTime) {
  71. $query->whereRaw("((visit_time + {$diffNums}) - {$currentTime} > 0)")->where('current_status', '=', 1);
  72. }];
  73. } else if ($params['report_status'] == 3) {
  74. //已锁定
  75. $where[] = [function($query) {
  76. $query->whereIn('current_status', [2,3,4]);
  77. }];
  78. } else if ($params['report_status'] == 2) {
  79. //已失效
  80. $where[] = [function($query) use ($diffNums, $currentTime){
  81. $query->orWhere('current_status', '=', -1)->orWhereRaw("((visit_time + {$diffNums}) - {$currentTime} <= 0 AND current_status = 1 AND check_status = 2)");
  82. }];
  83. }
  84. }
  85. if (!empty($params['consultant_name'])) {
  86. $consultantIds = Consultant::where('name', 'like', "%{$params['consultant_name']}%")->pluck('id');
  87. $where[] = [function($query) use ($consultantIds) {
  88. $query->whereIn('consultant_id', $consultantIds);
  89. }];
  90. }
  91. if (!empty($params['type'])) {
  92. $where[] = ['type', '=', $params['type']];
  93. }
  94. if (!empty($params['visit_time'])) {
  95. $datetime = $params['visit_time'];
  96. $datetime[0] = strtotime($datetime[0]);
  97. $datetime[1] = strtotime($datetime[1]);
  98. $where[] = [function($query) use ($datetime) {
  99. $query->whereBetween('visit_time', $datetime);
  100. }];
  101. }
  102. if (!empty($params['visit_date'])) {
  103. $visitDate = $params['visit_date'];
  104. $visitDate[0] = strtotime($visitDate[0].' 00:00:00');
  105. $visitDate[1] = strtotime($visitDate[1].' 23:59:59');
  106. $where[] = [function($query) use ($visitDate) {
  107. $query->whereBetween('visit_time', $visitDate);
  108. }];
  109. }
  110. if (!empty($params['created_date'])) {
  111. $createdDate = $params['created_date'];
  112. $createdDate[0] = strtotime($createdDate[0].' 00:00:00');
  113. $createdDate[1] = strtotime($createdDate[1].' 23:59:59');
  114. $where[] = [function($query) use ($createdDate) {
  115. $query->whereBetween('created_at', $createdDate);
  116. }];
  117. }
  118. if (!empty($params['current_status'])) {
  119. $currentStatus = $params['current_status'];
  120. $where[] = [function($query) use ($currentStatus){
  121. $query->where('current_status', '=', $currentStatus)->where('check_status', '=', 2);
  122. }];
  123. }
  124. if (!empty($params['consultant_id'])) {
  125. $where[] = ['consultant_id', '=', $params['consultant_id']];
  126. }
  127. if (!empty($params['custom'])) {
  128. $keywords = $params['custom'];
  129. $where[] = [function($query) use ($keywords) {
  130. $query->orWhere('name', 'like', "%{$keywords}%")->orWhere('mobile', 'like', "%{$keywords}%");
  131. }];
  132. }
  133. if (!empty($params['check_status'])) {
  134. $where[] = ['check_status', '=', $params['check_status']];
  135. }
  136. if (!empty($params['stat_report_status'])) {
  137. //已报备 1
  138. $statReportStatus = $params['stat_report_status'];
  139. if ($statReportStatus == 1) {
  140. $where[] = [function($query) use ($diffNums, $currentTime) {
  141. $query->whereRaw("((visit_time + {$diffNums}) - {$currentTime} > 0)")->where('current_status', '=', 1)->where('check_status', '=', 2);
  142. }];
  143. }
  144. //已锁定 2
  145. if ($statReportStatus == 2) {
  146. $where[] = [function($query) {
  147. $query->whereIn('current_status', [2,3,4])->where('check_status', '=', 2);
  148. }];
  149. }
  150. //已失效 -1
  151. if ($statReportStatus == -1) {
  152. $where[] = [function($query) use ($diffNums, $currentTime){
  153. $query->orWhere('current_status', '=', -1)->orWhereRaw("((visit_time + {$diffNums}) - {$currentTime} <= 0 AND current_status = 1 AND check_status = 2)")->orWhere('check_status', '=', -1);
  154. }];
  155. }
  156. }
  157. return $where;
  158. }
  159. /**
  160. * Notes: 列表
  161. * User: yb
  162. * Date: 2024/8/6
  163. * Time: 15:07
  164. * @param Request $request
  165. */
  166. public static function index(Request $request)
  167. {
  168. $format = $request->get('format', 'normal');
  169. $limit = (int)$request->get('pageSize', $format === 'tree' ? 1000 : 10);
  170. $limit = $limit <= 0 ? 10 : $limit;
  171. $params = $request->get();
  172. $page = (int)$request->get('page');
  173. $page = $page > 0 ? $page : 1;
  174. $currentTime = time();
  175. $diffNums = self::DIFF_TIME;
  176. $where = self::commonSearch($params);
  177. $paginator = MarketCustomer::where($where)->orderBy('visit_time', 'desc')->paginate($limit, '*', 'page', $page);
  178. $total = $paginator->total();
  179. $items = $paginator->items();
  180. if (!empty($items)) {
  181. $consultantKeys = [];
  182. $consultantIds = $paginator->pluck('consultant_id')->toArray();
  183. if (!empty($consultantIds)) {
  184. //去重
  185. $consultantIds = array_unique($consultantIds);
  186. //排序
  187. $consultantIds = array_values($consultantIds);
  188. //查询顾问信息
  189. $consultantList = Consultant::whereIn('id', $consultantIds)->select(['id', 'name', 'mobile'])->get();
  190. if (!$consultantList->isEmpty()) {
  191. foreach ($consultantList->toArray() as $consultantItem) {
  192. $consultantKeys[$consultantItem['id']] = $consultantItem;
  193. }
  194. }
  195. }
  196. $teamKeys = TeamService::getItemKeys();
  197. foreach ($items as &$item) {
  198. $visitTime = $item->visit_time;
  199. $visitTimeStamp = strtotime($visitTime);
  200. $diff = ($visitTimeStamp + $diffNums) - $currentTime;
  201. $item->diff_nums = ($diff > 0) ? $diff : 0;
  202. $item->consultant_name = $consultantKeys[$item->consultant_id]['name'] ?? '';
  203. $item->consultant_mobile = $consultantKeys[$item->consultant_id]['mobile'] ?? '';
  204. $item->team_name = TeamService::getTeamName($teamKeys, $item->dept_id);
  205. $item->mask_mobile = self::handlePhone($item->mobile);
  206. }
  207. }
  208. $data = [
  209. 'total' => $total,
  210. 'rows' => $items
  211. ];
  212. return json_success('success', $data);
  213. }
  214. /**
  215. * Notes: 添加客户
  216. * User: yb
  217. * Date: 2024/8/6
  218. * Time: 11:20
  219. */
  220. public static function add($params)
  221. {
  222. $params = MarketCustomer::handleNumParams($params);
  223. $mobile = $params['mobile'];
  224. //查询客户手机号是否已经存在
  225. if (MarketCustomer::checkCustomExists($mobile)) {
  226. return json_fail('客户已经登记过了');
  227. }
  228. //查询顾问信息
  229. $consultantId = $params['consultant_id'];
  230. $consultantInfo = Consultant::firstWhere(['id' => $consultantId]);
  231. if (empty($consultantInfo)) {
  232. return json_fail('顾问信息不存在');
  233. }
  234. $deptId = $consultantInfo->dept_id;
  235. $insertData = [
  236. 'name' => $params['name'],
  237. 'mobile' => $mobile,
  238. 'consultant_id' => $consultantId,
  239. 'dept_id' => $deptId,
  240. 'gender' => $params['gender'] ?? null,
  241. 'visit_type' => $params['visit_type'] ?? null,
  242. 'require_area' => $params['require_area'] ?? null,
  243. 'area' => $params['area'] ?? null,
  244. 'requirement' => $params['requirement'] ?? null,
  245. 'age_range' => $params['age_range'] ?? null,
  246. 'focus' => $params['focus'] ?? null,
  247. 'region' => $params['region'] ?? null,
  248. 'purpose' => $params['purpose'] ?? null,
  249. 'level' => $params['level'] ?? null,
  250. 'type' => $params['type'] ?? null,
  251. 'check_status' => 1,
  252. 'visit_time' => $params['visit_time'] ?? null,
  253. 'note' => $params['note'] ?? '',
  254. 'current_status' => $params['current_status'] ?? null,
  255. 'created_at' => time()
  256. ];
  257. Db::beginTransaction();
  258. try {
  259. //查询会员表中是否存在该客户
  260. // $memberId = Member::where('member_mobile', $insertData['mobile'])->value('member_id');
  261. // if (empty($memberId)) {
  262. // $result = MemberService::add([
  263. // 'account_name'=> $insertData['name'],
  264. // 'member_category' => '售房客户',
  265. // 'mobile' => $insertData['mobile'],
  266. // 'source' => 'HOUSE']);
  267. // $code = $result->getStatusCode();
  268. // if ($code == 200) {
  269. // $content = $result->rawBody();
  270. // if (is_json($content)) {
  271. // $content = json_decode($content, 1);
  272. // if ($content['code'] == 200) {
  273. // $memberId = $content['data']['member_id'];
  274. // } else {
  275. // throw new BusinessException('新增会员失败');
  276. // }
  277. // } else {
  278. // throw new BusinessException('新增会员失败');
  279. // }
  280. // } else {
  281. // throw new BusinessException('新增会员失败');
  282. // }
  283. // }
  284. // $insertData['member_id'] = $memberId;
  285. $customId = MarketCustomer::insertGetId($insertData);
  286. Db::commit();
  287. }catch (BusinessException|\Exception $e){
  288. Db::rollBack();
  289. return json_fail($e->getMessage());
  290. }
  291. if ($customId) {
  292. return json_success('添加成功');
  293. } else {
  294. return json_fail('添加失败');
  295. }
  296. }
  297. /**
  298. * Notes: 编辑客户
  299. * User: yb
  300. * Date: 2024/8/6
  301. * Time: 16:53
  302. * @param $params
  303. */
  304. public static function update($params)
  305. {
  306. $params = MarketCustomer::handleNumParams($params);
  307. $mobile = $params['mobile'];
  308. //查询客户手机号是否已经存在
  309. if (MarketCustomer::checkCustomExists($mobile, $params['id'])) {
  310. return json_fail('客户已经登记过了');
  311. }
  312. $updateData = [
  313. 'name' => $params['name'],
  314. 'mobile' => $params['mobile'],
  315. 'gender' => $params['gender'] ?? null,
  316. 'visit_type' => $params['visit_type'] ?? null,
  317. 'require_area' => $params['require_area'] ?? null,
  318. 'area' => $params['area'] ?? null,
  319. 'requirement' => $params['requirement'] ?? null,
  320. 'age_range' => $params['age_range'] ?? null,
  321. 'focus' => $params['focus'] ?? null,
  322. 'region' => $params['region'] ?? null,
  323. 'purpose' => $params['purpose'] ?? null,
  324. 'level' => $params['level'] ?? null,
  325. 'type' => $params['type'] ?? null,
  326. 'note' => $params['note'] ?? '',
  327. 'current_status' => $params['current_status'] ?? null,
  328. 'updated_at' => time()
  329. ];
  330. if (!empty($params['update_visit_time'])) {
  331. if ($params['update_visit_time'] == 1) {
  332. $updateData['visit_time'] = $params['visit_time'] ?? null;
  333. }
  334. }
  335. $result = MarketCustomer::where('id', $params['id'])->update($updateData);
  336. if ($result) {
  337. return json_success('编辑成功');
  338. } else {
  339. return json_fail('编辑失败');
  340. }
  341. }
  342. /**
  343. * Notes: 删除客户
  344. * User: yb
  345. * Date: 2024/8/2
  346. * Time: 13:33
  347. * @param $ids
  348. * @return \support\Response
  349. */
  350. public static function delete($ids)
  351. {
  352. if (!$ids) {
  353. return json_fail("数据错误");
  354. }
  355. if (!is_array($ids)) {
  356. $ids = [$ids];
  357. }
  358. try {
  359. if (is_array($ids)) {
  360. MarketCustomer::whereIn('id', $ids)->delete();
  361. } else {
  362. MarketCustomer::where('id', $ids)->delete();
  363. }
  364. } catch (\Exception $e) {
  365. return json_fail('删除失败');
  366. }
  367. return json_success('删除成功');
  368. }
  369. /**
  370. * Notes: 跟进记录
  371. * User: yb
  372. * Date: 2024/8/7
  373. * Time: 9:00
  374. * @param Request $request
  375. */
  376. public static function follow(Request $request)
  377. {
  378. $format = $request->get('format', 'normal');
  379. $limit = (int)$request->get('pageSize', $format === 'tree' ? 1000 : 10);
  380. $limit = $limit <= 0 ? 10 : $limit;
  381. $params = $request->get();
  382. $page = (int)$request->get('page');
  383. $page = $page > 0 ? $page : 1;
  384. $where = [];
  385. $whereCustom = [];
  386. $whereConsultant = [];
  387. if (!empty($params['market_customer_id'])) {
  388. $marketCustomerIds = $params['market_customer_id'];
  389. $where[] = [function($query) use ($marketCustomerIds) {
  390. $query->whereIn('market_customer_id', $marketCustomerIds);
  391. }];
  392. }
  393. if (!empty($params['consultant_id'])) {
  394. $consultantId = $params['consultant_id'];
  395. $where[] = [function($query) use ($consultantId) {
  396. $query->whereIn('consultant_id', $consultantId);
  397. }];
  398. }
  399. if (!empty($params['follow_way'])) {
  400. $where[] = ['follow_way', '=', $params['follow_way']];
  401. }
  402. if (!empty($params['custom'])) {
  403. $custom = $params['custom'];
  404. $whereCustom[] = [function($query) use ($custom) {
  405. $query->orWhere('name', 'like', "%{$custom}%")->orWhere('mobile', 'like', "%{$custom}%");
  406. }];
  407. }
  408. if (!empty($params['consultant'])) {
  409. $consultant = $params['consultant'];
  410. $whereConsultant[] = [function($query) use ($consultant) {
  411. $query->orWhere('name', 'like', "%{$consultant}%")->orWhere('mobile', 'like', "%{$consultant}%");
  412. }];
  413. }
  414. $paginator = MarketCustomerFollow::with(['custom', 'consultant'])->whereHas('custom', function($query) use ($whereCustom){
  415. $query->where($whereCustom);
  416. })->whereHas('consultant', function($query) use ($whereConsultant) {
  417. $query->where($whereConsultant);
  418. })->where($where)->orderBy('follow_time', 'desc')->paginate($limit, '*', 'page', $page);
  419. $total = $paginator->total();
  420. $items = $paginator->items();
  421. foreach ($items as &$item) {
  422. if (!empty($item->custom)) {
  423. $item->custom->mask_mobile = self::handlePhone($item->custom->mobile);
  424. }
  425. }
  426. $data = [
  427. 'total' => $total,
  428. 'rows' => $items
  429. ];
  430. return json_success('success', $data);
  431. }
  432. /**
  433. * Notes: 删除跟进记录
  434. * User: yb
  435. * Date: 2024/8/7
  436. * Time: 11:25
  437. * @param $ids
  438. */
  439. public static function deleteFollow($ids)
  440. {
  441. if (!$ids) {
  442. return json_fail("数据错误");
  443. }
  444. if (!is_array($ids)) {
  445. $ids = [$ids];
  446. }
  447. try {
  448. if (is_array($ids)) {
  449. MarketCustomerFollow::whereIn('id', $ids)->delete();
  450. } else {
  451. MarketCustomerFollow::where('id', $ids)->delete();
  452. }
  453. } catch (\Exception $e) {
  454. return json_fail('删除失败');
  455. }
  456. return json_success('删除成功');
  457. }
  458. /**
  459. * Notes: 转移客户
  460. * User: yb
  461. * Date: 2024/8/7
  462. * Time: 14:27
  463. * @param $params
  464. */
  465. public static function moveCustom($params)
  466. {
  467. $userId = JwtToken::getCurrentId();
  468. $currentConsultantId = $params['consultant_id']; //当前顾问
  469. $consultantIds = $params['move_consultant_id'] ?? [];
  470. $customIds = $params['move_market_customer_id'] ?? [];
  471. $note = $params['note'] ?? '';
  472. $consultantInfo = Consultant::firstWhere(['id' => $currentConsultantId]);
  473. if (empty($consultantInfo)) {
  474. return json_fail('顾问不存在');
  475. }
  476. $currentDeptId = $consultantInfo->dept_id; //当前部门
  477. $logsInertData = [];
  478. $now = time();
  479. $whereCustom = [];
  480. if (!empty($customIds)) {
  481. $whereCustom[] = [function($query) use ($customIds) {
  482. $query->whereIn('id', $customIds);
  483. }];
  484. }
  485. if (!empty($consultantIds)) {
  486. $whereCustom[] = [function($query) use ($consultantIds) {
  487. $query->whereIn('consultant_id', $consultantIds);
  488. }];
  489. }
  490. $customList = MarketCustomer::where($whereCustom)->select(['id','consultant_id','dept_id'])->get();
  491. if (!$customList->isEmpty()) {
  492. foreach ($customList as$item) {
  493. $logsInertData[] = [
  494. 'market_customer_id' => $item->id,
  495. 'consultant_id' => $currentConsultantId,
  496. 'dept_id' => $currentDeptId,
  497. 'before_consultant_id' => $item->consultant_id,
  498. 'before_dept_id' => $item->dept_id,
  499. 'note' => $note,
  500. 'change_user_id' => $userId,
  501. 'created_at' => $now
  502. ];
  503. }
  504. }
  505. if ($customList->isEmpty()) {
  506. return json_fail('移交的客户信息不存在');
  507. }
  508. if (empty($logsInertData)) {
  509. return json_fail('移交记录不能为空');
  510. }
  511. Db::beginTransaction();
  512. $result = false;
  513. try {
  514. foreach ($customList as $item) {
  515. $item->consultant_id = $currentConsultantId;
  516. $item->dept_id = $currentDeptId;
  517. $item->save();
  518. }
  519. $result = MarketCustomerLogs::insert($logsInertData);
  520. Db::commit();
  521. }catch (BusinessException|\Exception $e) {
  522. Db::rollBack();
  523. return json_fail($e->getMessage());
  524. }
  525. if ($result) {
  526. return json_success('移交成功');
  527. } else {
  528. return json_fail('移交失败');
  529. }
  530. }
  531. /**
  532. * Notes: 转移记录
  533. * User: yb
  534. * Date: 2024/8/7
  535. * Time: 15:33
  536. * @param Request $request
  537. */
  538. public static function moveLogs(Request $request)
  539. {
  540. $format = $request->get('format', 'normal');
  541. $limit = (int)$request->get('pageSize', $format === 'tree' ? 1000 : 10);
  542. $limit = $limit <= 0 ? 10 : $limit;
  543. $params = $request->get();
  544. $page = (int)$request->get('page');
  545. $page = $page > 0 ? $page : 1;
  546. $platform = 0;
  547. $where = [];
  548. $whereCustom = [];
  549. $whereCurrent = [];
  550. $whereBefore = [];
  551. $whereOpBack = [];
  552. $whereOpFront = [];
  553. if (!empty($params['market_customer_id'])) {
  554. $where[] = ['market_customer_id', '=', $params['market_customer_id']];
  555. }
  556. if (!empty($params['consultant_id'])) {
  557. $consultantIds = $params['consultant_id'];
  558. $where[] = [function($query) use ($consultantIds) {
  559. $query->orWhereIn('consultant_id', $consultantIds)->orWhereIn('before_consultant_id', $consultantIds);
  560. }];
  561. }
  562. if (!empty($params['custom'])) {
  563. //客户信息
  564. $custom = $params['custom'];
  565. $whereCustom[] = ['name', 'like', "%{$custom}%"];
  566. }
  567. if (!empty($params['current_consultant'])) {
  568. //当前员工信息
  569. $current = $params['current_consultant'];
  570. $whereCurrent[] = ['name', 'like', "%{$current}%"];
  571. }
  572. if (!empty($params['before_consultant'])) {
  573. //转移前员工信息
  574. $before = $params['before_consultant'];
  575. $whereBefore[] = ['name', 'like', "%{$before}%"];
  576. }
  577. if (!empty($params['platform'])) {
  578. $platform = $params['platform'];
  579. if ($platform == 1) {
  580. //后台
  581. $where[] = ['change_user_id', '<>', null];
  582. $where[] = ['change_user_id', '=', null];
  583. } else {
  584. //小程序
  585. $where[] = ['change_user_id', '=', null];
  586. $where[] = ['change_user_id', '<>', null];
  587. }
  588. }
  589. if (!empty($params['op_name'])) {
  590. $opName = $params['op_name'];
  591. if (!empty($platform)) {
  592. if ($platform == 1) {
  593. $whereOpBack[] = ['user_name', 'like', "%{$opName}%"];
  594. } else {
  595. $whereOpFront[] = ['name', 'like', "%{$opName}%"];
  596. }
  597. } else {
  598. $whereOpBack[] = [function($query) use ($opName) {
  599. $query->orWhere('user_name', 'like', "%{$opName}%");
  600. }];
  601. $whereOpFront[] = [function($query) use ($opName) {
  602. $query->orWhere('name', 'like', "%{$opName}%");
  603. }];
  604. }
  605. }
  606. $paginator = MarketCustomerLogs::with(['custom', 'beforeMan', 'currentMan', 'opBackPerson', 'opFrontPerson'])
  607. ->whereHas('custom', function ($query) use ($whereCustom) {
  608. $query->where($whereCustom);
  609. })
  610. ->whereHas('currentMan', function ($query) use ($whereCurrent) {
  611. $query->where($whereCurrent);
  612. })
  613. ->whereHas('beforeMan', function ($query) use ($whereBefore) {
  614. $query->where($whereBefore);
  615. })
  616. ->where($where)
  617. ->orderBy('created_at', 'desc')
  618. ->paginate($limit, '*', 'page', $page);
  619. $total = $paginator->total();
  620. $items = $paginator->items();
  621. foreach ($items as &$item) {
  622. if (!empty($item->custom)) {
  623. $item->custom->mask_mobile = self::handlePhone($item->custom->mobile);
  624. }
  625. }
  626. $data = [
  627. 'total' => $total,
  628. 'rows' => $items
  629. ];
  630. return json_success('success', $data);
  631. }
  632. /**
  633. * Notes: 审核客户
  634. * User: yb
  635. * Date: 2024/8/16
  636. * Time: 11:21
  637. * @param $params
  638. */
  639. public static function checkCustom($params)
  640. {
  641. $adminId = JwtToken::getCurrentId();
  642. //查询客户是否已经存在
  643. $customId = $params['id'];
  644. $checkStatus = $params['check_status'];
  645. if (!in_array($checkStatus, [-1,2])) {
  646. return json_fail('状态值非法');
  647. }
  648. $info = MarketCustomer::firstWhere(['id' => $customId]);
  649. if (empty($info)) {
  650. return json_fail('客户不存在');
  651. }
  652. $status = $info->check_status;
  653. if ($status != 1) {
  654. return json_fail('客户不是待审核状态');
  655. }
  656. $mobile = $info->mobile;
  657. if ($checkStatus == 2) {
  658. if (MarketCustomer::checkCustomExists($mobile)) {
  659. return json_fail('客户已经存在');
  660. }
  661. }
  662. $result = false;
  663. Db::beginTransaction();
  664. try {
  665. $info->check_status = $checkStatus;
  666. if ($checkStatus == -1) {
  667. //拒绝录入拒绝理由
  668. $info->check_note = $params['note'] ?? '无拒绝理由';
  669. }
  670. $info->check_time = time();
  671. $info->check_admin_id = $adminId;
  672. $result = $info->save();
  673. if ($checkStatus == 2) {
  674. //将其他待审的相同手机号的改拒绝
  675. $where = [
  676. ['mobile' , '=', $mobile],
  677. ['check_status', '=', 1],
  678. ['id', '<>', $customId]
  679. ];
  680. MarketCustomer::where($where)->update(['check_time' => time(),'check_status' => -1,'check_note' => '客户已经被其他顾问报备']);
  681. }
  682. Db::commit();
  683. }catch (BusinessException|\Exception $e){
  684. Db::rollBack();
  685. return json_fail($e->getMessage());
  686. }
  687. if ($result) {
  688. return json_success('审核成功');
  689. } else {
  690. return json_fail('审核失败');
  691. }
  692. }
  693. /**
  694. * Notes: 数据统计分析
  695. * User: yb
  696. * Date: 2024/8/17
  697. * Time: 11:27
  698. * @param $params
  699. */
  700. public static function statisticsIndex(Request $request)
  701. {
  702. $params = $request->get();
  703. $where = self::commonSearch($params);
  704. //客户总数
  705. $total = MarketCustomer::where($where)->count();
  706. //待审核
  707. $checkTotal = MarketCustomer::where($where)->where('check_status', 1)->count();
  708. //已报备
  709. $reportTotal = MarketCustomer::where($where)->where(
  710. [[function($query) {
  711. $currentTime = time();
  712. $diffNums = self::DIFF_TIME;
  713. $query->whereRaw("((visit_time + {$diffNums}) - {$currentTime} > 0) AND current_status = 1 AND check_status = 2");
  714. }]]
  715. )->count();
  716. //已来电
  717. $mobileTotal = MarketCustomer::where($where)->where([[function($query) {
  718. $query->where('check_status', '=', 2)->where('current_status', '=', 1);
  719. }]])->count();
  720. //已到访
  721. $visitTotal = MarketCustomer::where($where)->where([[function($query) {
  722. $query->where('check_status', '=', 2)->where('current_status', '=', 2);
  723. }]])->count();
  724. //已缴费
  725. $payTotal = MarketCustomer::where($where)->where([[function($query) {
  726. $query->where('check_status', '=', 2)->where('current_status', '=', 3);
  727. }]])->count();
  728. //已成交
  729. $dealTotal = MarketCustomer::where($where)->where([[function($query) {
  730. $query->where('check_status', '=', 2)->where('current_status', '=', 4);
  731. }]])->count();
  732. //已到访 + 已缴费 + 已成交 / 客户总数
  733. $rant = 0;
  734. if ($total > 0) {
  735. $rant = $payTotal + $dealTotal / $total;
  736. }
  737. $rant = sprintf('%.2f', $rant);
  738. $data = [
  739. 'total' => $total,
  740. 'check_total' => $checkTotal,
  741. 'report_total' => $reportTotal,
  742. 'mobile_total' => $mobileTotal,
  743. 'visit_total' => $visitTotal,
  744. 'pay_total' => $payTotal,
  745. 'deal_total' => $dealTotal,
  746. 'rant' => $rant,
  747. ];
  748. return json_success('请求成功', $data);
  749. }
  750. /**
  751. * Notes: 导出数据
  752. * User: yb
  753. * Date: 2024/8/17
  754. * Time: 13:01
  755. */
  756. public static function exportData(Request $request)
  757. {
  758. $currentTime = time();
  759. $diffNums = self::DIFF_TIME;
  760. $params = $request->get();
  761. $where = self::commonSearch($params);
  762. if (!empty($params['custom_ids'])) {
  763. $customIds = $params['custom_ids'];
  764. $where[] = [function($query) use ($customIds){
  765. $query->whereIn('id', $customIds);
  766. }];
  767. }
  768. $list = MarketCustomer::where($where)->orderBy('visit_time', 'desc')->get();
  769. if (!$list->isEmpty()) {
  770. $consultantKeys = [];
  771. //查询顾问信息
  772. $consultantList = Consultant::select(['id', 'name', 'mobile'])->get();
  773. if (!$consultantList->isEmpty()) {
  774. foreach ($consultantList->toArray() as $consultantItem) {
  775. $consultantKeys[$consultantItem['id']] = $consultantItem;
  776. }
  777. }
  778. $teamKeys = TeamService::getItemKeys();
  779. $returnData = [];
  780. $genderData = ['', '男', '女'];
  781. $typeData = ['', '来电', '来访'];
  782. $currentStatusData = [-1 => '无效客户', 1 => '已来电', 2 => '已到访', 3 => '已缴费', 4 => '已成交'];
  783. foreach ($list as &$item) {
  784. $visitTime = $item->visit_time;
  785. $visitTimeStamp = strtotime($visitTime);
  786. $diff = ($visitTimeStamp + $diffNums) - $currentTime;
  787. $currentStatus = $item->current_status;//当前状态
  788. $checkStatus = $item->check_status;//审核状态
  789. if ($checkStatus == 1) {
  790. $currentStatusText = '待审核';
  791. }
  792. if ($checkStatus == -1) {
  793. $currentStatusText = '已失效';
  794. }
  795. if ($checkStatus == 2) {
  796. //审核通过
  797. if ($currentStatus > 1) {
  798. $currentStatusText = $currentStatusData[$currentStatus] ?? '';
  799. }
  800. if ($currentStatus == 1) {
  801. if ($diff > 0) {
  802. $currentStatusText = $currentStatusData[$currentStatus] ?? '';
  803. } else {
  804. $currentStatusText = '已失效';
  805. }
  806. }
  807. if ($currentStatus == -1) {
  808. $currentStatusText = '无效客户';
  809. }
  810. }
  811. $returnData[] = [
  812. 'name' => $item->name,
  813. 'mobile' => $item->mobile,
  814. 'mask_mobile' => self::handlePhone($item->mobile),
  815. 'gender' => $genderData[$item->gender] ?? '',
  816. 'type' => $typeData[$item->type] ?? '',
  817. 'consultant_name' => $consultantKeys[$item->consultant_id]['name'] ?? '',
  818. 'consultant_mobile' => $consultantKeys[$item->consultant_id]['mobile'] ?? '',
  819. 'team_name' => TeamService::getTeamName($teamKeys, $item->dept_id),
  820. 'current_status' => $currentStatusText, //当前状态
  821. 'visit_time' => $item->visit_time,
  822. 'created_at' => date('Y-m-d H:i:s',strtotime($item->created_at))
  823. ];
  824. }
  825. return json_success('请求成功', $returnData);
  826. }
  827. }
  828. /**
  829. * Notes: 对手机号加密处理
  830. * User: yb
  831. * Date: 2024/8/8
  832. * Time: 15:41
  833. * @param $val
  834. * @return string|string[]
  835. */
  836. public static function handlePhone($val)
  837. {
  838. return substr_replace($val, '****', 3, 4);
  839. }
  840. }