ManagerEmp.php 200 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709
  1. <?php
  2. namespace app\empcrm\controller;
  3. use app\BaseController;
  4. use think\facade\View;
  5. use app\model\Employee;
  6. use app\model\Company;
  7. use app\model\CustomerVisitLog;
  8. use app\model\Customer;
  9. use app\logics\OrgLogic;
  10. use app\model\CustomerSource;
  11. use app\model\Org;
  12. use app\model\CustomerPortraitField;
  13. use app\model\CustomerPortraitFieldSelect;
  14. use app\model\Setting;
  15. use app\model\CustomerRecycle;
  16. use app\model\CustomersSubscribe;
  17. use think\facade\Db;
  18. use think\App;
  19. use app\model\Miniprogram;
  20. use app\model\PreformanceTasks as PreformanceTasksModel;
  21. use app\logics\PoolLogic;
  22. use app\model\CustomerExtension;
  23. use app\model\CrmImportLog;
  24. use app\model\CrmImportRecord;
  25. use PhpOffice\PhpSpreadsheet\IOFactory;
  26. use toolkits\Aec;
  27. use app\model\OutCallLog;
  28. use app\model\OutCallMbLog;
  29. use app\model\Shop;
  30. use think\facade\Log;
  31. use app\model\CustomerInvalidLog;
  32. use app\model\FishData;
  33. use think\facade\Queue;
  34. class ManagerEmp extends BaseController
  35. {
  36. //年报表
  37. public function year_report()
  38. {
  39. $request = request();
  40. $root_id = $request->empcrm->root_id;
  41. $empid = $request->empcrm->id;
  42. $team_orgs = orgSubIds($request->empcrm->org_id);
  43. $param = $this->request->only(['cid', 'date']);
  44. if (!$request->isAjax()) {
  45. $data['company_name'] = Company::where('root_id', $root_id)->value('company_name');
  46. View::assign('data', $data);
  47. return View::fetch();
  48. }
  49. $year = $param['date'];
  50. $xin = [];
  51. $weekarray = array("日", "一", "二", "三", "四", "五", "六"); //先定义一个数组
  52. for ($i = 1; $i < 13; $i++) {
  53. $month = $i;
  54. $m = $i < 10 ? '0' . $i : $i;
  55. $start = $year . '-' . $m . '-01 00:00:00';
  56. $end = date('Y-m-d', strtotime("$start +1 month -1 day"));
  57. $a = ['month' => $month, 'start' => $start, 'end' => $end . ' 23:59:59'];
  58. $xin[] = $a;
  59. }
  60. $param_sub_org = $team_orgs;
  61. $org_employee = Employee::where([['org_id', 'in', $team_orgs], ['state', '=', '在职'], ['uid', '>', 0]])->column('id');
  62. //$condition[] = ['org_id', 'in', $param_sub_org];
  63. $condition[] = ['employee_id', 'in', $org_employee];
  64. //$condition[] = ['state', 'not in', Customer::changeState('无效', 'chaos')];
  65. $condition[] = ['sign_time', 'between', [$param['date'] . '-01-01 00:00:00', $param['date'] . '-12-31 23:59:59']];
  66. //$customer_list = Customer::where($condition)->field('id,addtime,state,died')->select()->toArray();//->count();
  67. $customer_list = Customer::where($condition)->where('state', 'not in', Customer::changeState('待确认', 'chaos'))->column('id,sign_time,state,died'); //->count();
  68. //查询无效的客户
  69. $invalidcus = CustomerInvalidLog::where([['root_id', '=', $root_id], ['employee_id', 'in', $org_employee], ['cus_addtime', 'between', [$param['date'] . '-01-01 00:00:00', $param['date'] . '-12-31 23:59:59']]])->column('cus_addtime,customer_id,status');
  70. $state1 = Customer::changeState('待确认', 'chaos');
  71. $state2 = Customer::changeState('无效', 'chaos');
  72. $state3 = CustomerVisitLog::changeState('已交定', 'chaos');
  73. $state4 = CustomerVisitLog::changeState('已签单', 'chaos');
  74. $state5 = CustomerVisitLog::changeState('确认到店', 'chaos');
  75. $state6 = CustomerVisitLog::changeState('无效', 'chaos');
  76. $state7 = CustomerVisitLog::changeState('已量房', 'chaos');
  77. $state8 = CustomerVisitLog::changeState('已到场', 'chaos');
  78. $where[] = ['customer_employee_id', 'in', $org_employee];
  79. $where[] = ['confirm_date', 'between', [$param['date'] . '-01-01 00:00:00', $param['date'] . '-12-31 23:59:59']];
  80. $where[] = ['state', 'in', array_merge($state3, $state4, $state5, $state7, $state8)];
  81. $visitlog_list = CustomerVisitLog::where($where)
  82. ->group('state,customer_id')
  83. ->column('customer_id,state,confirm_date,money');
  84. //var_dump($visitlog_list);exit;
  85. //->select()->toArray();
  86. $empmod = new Empcrm($this->app);
  87. $metids = [];
  88. foreach ($visitlog_list as $key => $val) {
  89. if (in_array($val['state'], array_merge($state5, $state7, $state8))) $metids[] = $val['customer_id'];
  90. }
  91. $yesids = !empty(array_unique($metids)) ? $empmod->selBeforelog(array_unique($metids), $param['date'] . '-01-01 00:00:00') : [];
  92. $exten_where[] = ['root_id', '=', $root_id];
  93. $exten_where[] = ['addtime', 'between', [$param['date'] . '-01-01 00:00:00', $param['date'] . '-12-31 23:59:59']];
  94. $exten_list = CustomerExtension::with(['source' => function ($query) {
  95. $query->field('id,source');
  96. }])->where($exten_where)->select()->toArray();
  97. $t = ['month' => '求和', 'deposit_percen' => 0, 'exten_money' => 0, 'exten_show' => 0, 'exten_click' => 0, 'click_percen' => 0, 'clue_conversion' => 0, 'clue_money' => 0, 'valid_money' => 0, 'meet_money' => 0, 'sign_agv_money' => 0, 'ROI' => 0, 'week' => '', 'data' => [], 'clue_cont' => 0, 'valid_cont' => 0, 'valid_percen' => 0, 'meet_cont' => 0, 'meet_percen' => 0, 'deposit_cont' => 0, 'sign_cont' => 0, 'basic_money' => 0, 'other_money' => 0, 'all_money' => 0, 'invalid_no' => 0, 'invalid_yes' => 0, 'invalid_meet' => 0, 'invalid_deposit' => 0, 'invalid_sign' => 0];
  98. $meetids = [];
  99. foreach ($xin as $key => $val) {
  100. $valids = $deposids = $cud = $daystate = $wuxiao = [];
  101. $exten_money = $exten_show = $exten_click = $clue_cont = $valid = $meet = $deposit = $sign = $basic_money = $other_money = $invalid_no = $invalid_yes = $invalid_meet = $invalid_deposit = 0;
  102. foreach ($customer_list as $k => $v) {
  103. if ($v['sign_time'] >= $val['start'] && $v['sign_time'] <= $val['end']) {
  104. //if($v['died'] != 2 && !in_array($v['state'],array_merge($state1,$state2),true)) $valid++;
  105. if ($v['died'] != 2) {
  106. $valid++;
  107. $valids[] = $v['id'];
  108. }
  109. }
  110. }
  111. $clue_ids = Customer::where([['employee_id', 'in', $org_employee], ['sign_time', '>=', $val['start']], ['sign_time', '<=', $val['end']]])->column('id');
  112. $clue_cont = count($clue_ids);
  113. //添加无效的客户到有效上
  114. foreach ($invalidcus as $k => $v) {
  115. if ($v['cus_addtime'] >= $val['start'] && $v['cus_addtime'] <= $val['end'] && !in_array($v['customer_id'], $clue_ids)) {
  116. $clue_cont++;
  117. $clue_ids[] = $v['customer_id'];
  118. }
  119. if ($v['cus_addtime'] >= $val['start'] && $v['cus_addtime'] <= $val['end'] && !in_array($v['customer_id'], $valids)) {
  120. if ($v['status'] == 1) $valid++;
  121. $valids[] = $v['customer_id'];
  122. }
  123. }
  124. unset($clue_ids, $valids);
  125. foreach ($visitlog_list as $k => $v) {
  126. if ($v['confirm_date'] >= $val['start'] && $v['confirm_date'] <= $val['end']) {
  127. if (!in_array($v['customer_id'], $meetids) && in_array($v['state'], array_merge($state5, $state7, $state8), true) && in_array($v['customer_id'], $yesids)) {
  128. $meet++;
  129. $meetids[] = $v['customer_id'];
  130. }
  131. if (in_array($v['state'], $state3, true)) {
  132. $deposit++;
  133. $deposids[] = $v['customer_id'];
  134. }
  135. if (in_array($v['state'], $state4, true)) {
  136. $basic_money += $v['money'];
  137. $sign++;
  138. }
  139. if (in_array($v['state'], $state6, true)) {
  140. $invalid_no++;
  141. $wuxiao[] = $v['customer_id'];
  142. }
  143. }
  144. }
  145. foreach ($wuxiao as $k => $v) {
  146. if (in_array($v, $meetids, true)) {
  147. $invalid_meet++;
  148. }
  149. if (in_array($v, $deposids, true)) {
  150. $invalid_deposit++;
  151. }
  152. }
  153. //$valid = CustomerVisitLog::where([['customer_id', 'in', $cud], ['state', 'in', $now_status],['confirm_date','between',[$val['start'],$val['end']]]])->group('customer_id')->count();
  154. foreach ($exten_list as $k => $v) {
  155. if ($v['addtime'] >= $val['start'] && $v['addtime'] <= $val['end']) {
  156. $exten_money += $v['money'];
  157. $exten_show += $v['show'];
  158. $exten_click += $v['click'];
  159. }
  160. }
  161. $xin[$key]['exten_money'] = $exten_money;
  162. $xin[$key]['exten_show'] = $exten_show;
  163. $xin[$key]['exten_click'] = $exten_click;
  164. $xin[$key]['click_percen'] = !empty($exten_click) && !empty($exten_show) ? round($exten_click / $exten_show, 2) : 0;
  165. $xin[$key]['clue_conversion'] = !empty($exten_click) && !empty($clue_cont) ? round($clue_cont / $exten_click * 100, 2) : 0;
  166. $xin[$key]['clue_cont'] = $clue_cont;
  167. $xin[$key]['clue_money'] = !empty($clue_cont) && !empty($exten_money) ? round($exten_money / $clue_cont, 2) : 0;
  168. $xin[$key]['valid_cont'] = $valid;
  169. $xin[$key]['valid_money'] = !empty($valid_cont) && !empty($exten_money) ? round($exten_money / $valid_cont, 2) : 0;
  170. $xin[$key]['valid_percen'] = $valid && $clue_cont ? round($valid / $clue_cont * 100, 2) : 0;
  171. $xin[$key]['meet_cont'] = $meet;
  172. $xin[$key]['meet_percen'] = !empty($meet) && !empty($clue_cont) ? round($meet / $clue_cont * 100, 2) : 0;
  173. $xin[$key]['meet_money'] = !empty($meet) && !empty($exten_money) ? round($exten_money / $meet, 2) : 0;
  174. $xin[$key]['deposit_cont'] = $deposit;
  175. $xin[$key]['deposit_percen'] = !empty($deposit) && !empty($meet) ? round($deposit / $meet * 100, 2) : 0;
  176. $xin[$key]['sign_cont'] = $sign;
  177. $xin[$key]['basic_money'] = $basic_money;
  178. $xin[$key]['sign_agv_money'] = !empty($sign_cont) && !empty($basic_money) ? floor($basic_money / $sign_cont) : 0;
  179. $xin[$key]['other_money'] = $other_money;
  180. $xin[$key]['all_money'] = $basic_money + $other_money;
  181. //$xin[$key]['invalid_no'] = $invalid_no;
  182. //$xin[$key]['invalid_yes'] = $invalid_yes;
  183. $xin[$key]['invalid_meet'] = $invalid_meet;
  184. $xin[$key]['invalid_deposit'] = $invalid_deposit;
  185. //$xin[$key]['invalid_sign'] = $invalid_sign;
  186. $xin[$key]['ROI'] = !empty($basic_money) && !empty($exten_money) ? round($exten_money / $basic_money * 100, 2) : 0;
  187. //总数
  188. $t['exten_money'] += $exten_money;
  189. $t['exten_show'] += $exten_show;
  190. $t['exten_click'] += $exten_click;
  191. $t['click_percen'] += !empty($exten_click) && !empty($exten_show) ? round($exten_click / $exten_show, 2) : 0;
  192. $t['clue_conversion'] = !empty($exten_click) && !empty($clue_cont) ? round($clue_cont / $exten_click * 100, 2) : 0;
  193. $t['clue_cont'] += $clue_cont;
  194. //$t['clue_money'] = !empty($clue_cont) && !empty($exten_money) ? round($exten_money/$clue_cont,2) : 0;
  195. $t['valid_cont'] += $valid;
  196. //$t['valid_money'] = !empty($valid_cont) && !empty($exten_money) ? round($exten_money/$valid_cont,2) : 0;
  197. //$t['valid_percen'] += $clue_cont && $valid ? round($valid/$clue_cont*100,2) : 0;
  198. $t['meet_cont'] += $meet;
  199. //$t['meet_money'] = !empty($meet) && !empty($exten_money) ? round($exten_money/$meet,2) : 0;
  200. //$t['meet_percen'] += !empty($meet) && !empty($clue_cont) ? round($meet/$clue_cont*100,2) : 0;
  201. $t['deposit_cont'] += $deposit;
  202. $t['sign_cont'] += $sign;
  203. $t['basic_money'] += $basic_money;
  204. //$t['sign_agv_money'] = !empty($sign_cont) && !empty($basic_money) ? floor($basic_money/$sign_cont) : 0;
  205. $t['other_money'] += $other_money;
  206. $t['all_money'] += $other_money + $basic_money;
  207. // $t['invalid_no'] += $invalid_no;
  208. // $t['invalid_yes'] += $invalid_yes;
  209. $t['invalid_meet'] += $invalid_meet;
  210. $t['invalid_deposit'] += $invalid_deposit;
  211. //$t['invalid_sign'] += $invalid_sign;
  212. $t['ROI'] = !empty($basic_money) && !empty($exten_money) ? round($exten_money / $basic_money * 100, 2) : 0;
  213. }
  214. $t['clue_money'] = !empty($t['clue_cont']) && !empty($t['exten_money']) ? round($t['exten_money'] / $t['clue_cont'], 2) : 0;
  215. $t['valid_money'] = !empty($t['valid_cont']) && !empty($t['exten_money']) ? round($t['exten_money'] / $t['valid_cont'], 2) : 0;
  216. $t['valid_percen'] = !empty($t['clue_cont']) && !empty($t['valid_cont']) ? round($t['valid_cont'] / $t['clue_cont'] * 100, 2) : 0;
  217. $t['meet_percen'] += !empty($t['meet_cont']) && !empty($t['clue_cont']) ? round($t['meet_cont'] / $t['clue_cont'] * 100, 2) : 0;
  218. $t['meet_money'] = !empty($t['meet_cont']) && !empty($t['exten_money']) ? round($t['exten_money'] / $t['meet_cont'], 2) : 0;
  219. $t['deposit_percen'] = !empty($t['deposit_cont']) && !empty($t['meet_cont']) ? round($t['deposit_cont'] / $t['meet_cont'] * 100, 2) : 0;
  220. $t['sign_agv_money'] = !empty($t['sign_cont']) && !empty($t['basic_money']) ? floor($t['basic_money'] / $t['sign_cont']) : 0;
  221. array_push($xin, $t);
  222. return json(['code' => 0, 'data' => $xin, 'count' => 0, 'msg' => '获取成功']);
  223. }
  224. //推广明细
  225. public function extension_report()
  226. {
  227. $request = request();
  228. $root_id = $request->empcrm->root_id;
  229. $empid = $request->empcrm->id;
  230. $team_orgs = orgSubIds($request->empcrm->root_id);
  231. $param = $this->request->only(['source_id', 'date', 'page' => 1, 'limit' => 17]);
  232. $order = isset($param['order']) ? $param['order'] : 'addtime desc';
  233. $page = intval($param['page']);
  234. $limit = intval($param['limit']);
  235. if (!$request->isAjax()) {
  236. $soudata = CustomerSource::field('id,source as name')->where('root_id', $root_id)->select()->toArray();
  237. View::assign('soudata', $soudata);
  238. //客户等级 隶属计划
  239. $fields = CustomerPortraitField::with(['select'])->where([['root_id', '=', $root_id], ['keyname', 'in', ['level']]])->select()->toArray();
  240. View::assign('fields', $fields);
  241. return View::fetch();
  242. }
  243. $org_employee = Employee::where([['org_id', 'in', $team_orgs], ['state', '=', '在职'], ['uid', '>', 0]])->column('id');
  244. $where[] = ['root_id','=',$root_id];
  245. if(!empty($param['source_id'])) {
  246. is_numeric($param['source_id'])?$where[] = ['source_id','=',$param['source_id']]:$where[] = ['source_id','in',$param['source_id']];
  247. }
  248. if(!empty($param['date'])) $where[] = ['addtime','between',[$param['date'].' 00:00:00',$param['date'].' 23:59:59']];
  249. $list = CustomerExtension::with(['source'=>function($query){
  250. $query->field('id,source');
  251. }])->where($where)->page($page, $limit)->order($order)->select()->toArray();
  252. $company_name = Company::where('root_id', $root_id)->value('company_name');
  253. $weekarray = array("日", "一", "二", "三", "四", "五", "六"); //先定义一个数组
  254. foreach ($list as $key => $val) {
  255. $clue_cont = $valid = 0;
  256. $clue_list = Customer::where([['employee_id', 'in', $org_employee], ['sign_time', 'between', [$val['addtime'] . ' 00:00:00', $val['addtime'] . ' 23:59:59']], ['org_id', 'in', $team_orgs], ['source_id', '=', $val['source_id']]])->column('id,state,died');
  257. $clue_cont = count($clue_list);
  258. foreach ($clue_list as $k => $v) {
  259. if ($v['died'] != 2 && !in_array($v['state'], array_merge(Customer::changeState('待确认', 'chaos'), Customer::changeState('无效', 'chaos')), true)) $valid++;
  260. }
  261. //查询无效的客户
  262. $invalidcus = CustomerInvalidLog::where([['employee_id', 'in', $org_employee], ['source_id', '=', $val['source_id']], ['root_id', '=', $root_id], ['cus_addtime', 'between', [$val['addtime'] . ' 00:00:00', $val['addtime'] . ' 23:59:59']]])->column('cus_addtime,employee_id,status');
  263. $clue_cont += count($invalidcus);
  264. foreach ($invalidcus as $k => $v) {
  265. if ($v['status'] == 1) $valid++;
  266. }
  267. //$valid+= count($invalidcus);
  268. $list[$key]['week'] = $weekarray[date("w", strtotime($val['addtime']))];
  269. $list[$key]['company_name'] = $company_name;
  270. $list[$key]['clue_cont'] = $clue_cont;
  271. $list[$key]['valid'] = $valid;
  272. $list[$key]['danshow_money'] = !empty($val['money']) && !empty($val['show']) ? round($val['money'] / $val['show'], 2) : 0; //展现费用=费用/展现次数
  273. $list[$key]['click_percen'] = !empty($val['click']) && !empty($val['show']) ? round($val['click'] / $val['show'] * 100, 2) : 0; //点击率=点击次数/展现次数
  274. $list[$key]['click_cost'] = !empty($val['money']) && !empty($val['click']) ? round($val['money'] / $val['click'], 2) : 0; //点击成本=费用/点击次数
  275. $list[$key]['clue_conversion'] = !empty($val['click']) && !empty($clue_cont) ? round($clue_cont / $val['click'] * 100, 2) : 0; //转化线索率=线索/点击次数
  276. $list[$key]['valid_conversion'] = !empty($val['money']) && !empty($clue_cont) ? round($val['money'] / $clue_cont, 2) : 0; //有效线索转化率=有效线索/点击次数
  277. $list[$key]['valid_percen'] = !empty($valid) && !empty($clue_cont) ? round($valid / $clue_cont, 2) : 0; //有效率=有效线索/线索数
  278. $list[$key]['valid_money'] = !empty($valid) && !empty($val['money']) ? round($val['money'] / $valid, 2) : 0; //有效单价=费用/有效索数
  279. $list[$key]['clue_money'] = !empty($clue_cont) && !empty($val['money']) ? round($val['money'] / $clue_cont, 2) : 0; //线索单价=费用/线索量
  280. }
  281. $count = CustomerExtension::where($where)->count();
  282. return json(['code' => 0, 'data' => $list, 'count' => $count, 'msg' => '获取成功']);
  283. }
  284. //添加推广明细数据
  285. public function add_extension()
  286. {
  287. $request = request();
  288. $root_id = $request->empcrm->root_id;
  289. $empid = $request->empcrm->id;
  290. $param = $this->request->only(['source_id','launch_time','money','show','click']);
  291. if (!$request->isAjax()) {
  292. $soudata = CustomerSource::field('id,source as name')->where('root_id', $root_id)->select()->toArray();
  293. View::assign('soudata', $soudata);
  294. $company_name = Company::where('root_id', $root_id)->value('company_name');
  295. View::assign('company_name', $company_name);
  296. View::assign('empname', $request->empcrm->name);
  297. return View::fetch();
  298. }
  299. $add['source_id'] = $param['source_id'];
  300. $add['addtime'] = $param['launch_time'];
  301. $add['money'] = $param['money'];
  302. $add['show'] = $param['show'];
  303. $add['click'] = $param['click'];
  304. $add['root_id'] = $root_id;
  305. $add['employee_id'] = $empid;
  306. $add['org_id'] = $request->empcrm->org_id;
  307. $ms = CustomerExtension::insertGetId($add);
  308. if ($ms) {
  309. return json(['code' => 0, 'data' => $ms, 'msg' => '添加成功']);
  310. } else {
  311. return json(['code' => 1, 'data' => '', 'msg' => '添加失败']);
  312. }
  313. }
  314. //修改推广明细
  315. public function edit_extension()
  316. {
  317. $request = request();
  318. $root_id = $request->empcrm->root_id;
  319. $empid = $request->empcrm->id;
  320. $param = $this->request->only(['id','source_id','launch_time','money','show','click']);
  321. if (!$request->isAjax()) {
  322. $data = CustomerExtension::where('id',$param['id'])->find();
  323. if(empty($data)) return json(['code' => 1, 'data' =>'', 'msg'=>'id为空']);
  324. View::assign('data',$data);
  325. $soudata = CustomerSource::field('id,source as name')->where('root_id', $root_id)->select()->toArray();
  326. View::assign('soudata', $soudata);
  327. $company_name = Company::where('root_id', $root_id)->value('company_name');
  328. View::assign('company_name', $company_name);
  329. View::assign('empname', $request->empcrm->name);
  330. return View::fetch();
  331. }
  332. if (empty($param['id'])) return json(['code' => 1, 'data' => '', 'msg' => 'id为空']);
  333. $add['source_id'] = $param['source_id'];
  334. $add['addtime'] = $param['launch_time'];
  335. $add['money'] = $param['money'];
  336. $add['show'] = $param['show'];
  337. $add['click'] = $param['click'];
  338. $ms = CustomerExtension::where([['id', '=', $param['id']], ['root_id', '=', $root_id]])->update($add);
  339. if ($ms) {
  340. return json(['code' => 0, 'data' => $ms, 'msg' => '修改成功']);
  341. } else {
  342. return json(['code' => 1, 'data' => '', 'msg' => '修改失败']);
  343. }
  344. }
  345. /**
  346. * 查询部门下的员工列表
  347. */
  348. public function seL_emplist()
  349. {
  350. $request = request();
  351. $root_id = $request->empcrm->root_id;
  352. $param = $this->request->only(['org_id']);
  353. $team_orgs = orgSubIds($request->empcrm->org_id);
  354. if (!empty($param['org_id'])) $team_orgs = orgSubIds($param['org_id']);
  355. $emplist = Employee::where([['root_id', '=', $root_id], ['org_id', 'in', $team_orgs], ['uid', '>', 0], ['state', '=', '在职']])->column('id,name');
  356. return json(['code' => 0, 'data' => $emplist, 'msg' => '获取成功']);
  357. }
  358. //账户明细
  359. public function account_report()
  360. {
  361. $request = request();
  362. $root_id = $request->empcrm->root_id;
  363. $empid = $request->empcrm->id;
  364. $team_orgs = orgSubIds($request->empcrm->org_id);
  365. $param = $this->request->only(['date', 'employee_id', 'source_id', 'org_id']);
  366. if (!$request->isAjax()) {
  367. $emplist = Employee::where([['org_id', 'in', $team_orgs], ['state', '=', '在职']])->field('id,name')->select()->toArray();
  368. View::assign('emplist', $emplist);
  369. $org_list = Org::where([['id', 'in', $team_orgs]])->select()->toArray();
  370. View::assign('org_list', $org_list);
  371. $data['company_name'] = Company::where('root_id', $root_id)->value('company_name');
  372. $data['empname'] = $request->empcrm->name;
  373. View::assign('data', $data);
  374. $source_list = CustomerSource::where('root_id', '=', $root_id)->select()->toArray();
  375. View::assign('source_list', $source_list);
  376. return View::fetch();
  377. }
  378. if (!empty($param['date'])) {
  379. $newtime = explode('到', $param['date']);
  380. } else {
  381. return json(['code' => 1, 'msg' => '日期为空']);
  382. }
  383. $soud_where[] = ['root_id', '=', $root_id];
  384. $org_employee = Employee::where([['org_id', 'in', $team_orgs], ['state', '=', '在职'], ['uid', '>', 0]])->column('id');
  385. if (!empty($param['source_id'])) $soud_where[] = ['id', 'in', explode(',', $param['source_id'])];
  386. $soud_list = CustomerSource::field('id,source as name')->where($soud_where)->select()->toArray();
  387. $where[] = ['sign_time', 'between', [$newtime[0] . ' 00:00:00', $newtime[1] . ' 23:59:59']];
  388. //$where[] = ['org_id','in',$team_orgs];
  389. if (!empty($param['employee_id'])) $org_employee = [$param['employee_id']];
  390. if (!empty($param['org_id']) && empty($param['employee_id'])) {
  391. $org_employee = Employee::where([['root_id', '=', $root_id], ['org_id', 'in', orgSubIds($param['org_id'])]])->column('id');
  392. }
  393. $where[] = ['employee_id', 'in', $org_employee];
  394. $exten_where[] = ['root_id', '=', $root_id];
  395. $exten_where[] = ['addtime', 'between', [$newtime[0] . ' 00:00:00', $newtime[1] . ' 23:59:59']];
  396. if (!empty($param['employee_id'])) $exten_where[] = ['id', '=', 0];
  397. $exten_list = CustomerExtension::with(['source' => function ($query) {
  398. $query->field('id,source');
  399. }])->where($exten_where)->select()->toArray();
  400. $t = ['dd' => 0, 'dc' => 0, 'lf' => 0, 'name' => '求和', 'deposit_percen' => 0, 'exten_money' => 0, 'exten_show' => 0, 'exten_click' => 0, 'click_percen' => 0, 'clue_conversion' => 0, 'clue_money' => 0, 'valid_money' => 0, 'meet_money' => 0, 'sign_agv_money' => 0, 'ROI' => 0, 'week' => '', 'data' => [], 'clue_cont' => 0, 'valid_cont' => 0, 'valid_percen' => 0, 'meet_cont' => 0, 'meet_percen' => 0, 'deposit_cont' => 0, 'sign_cont' => 0, 'basic_money' => 0, 'other_money' => 0, 'all_money' => 0, 'invalid_no' => 0, 'invalid_yes' => 0, 'invalid_meet' => 0, 'invalid_deposit' => 0, 'invalid_sign' => 0];
  401. $state1 = CustomerVisitLog::changeState('确认到店', 'chaos');
  402. $state2 = CustomerVisitLog::changeState('已交定', 'chaos');
  403. $state3 = CustomerVisitLog::changeState('已签单', 'chaos');
  404. $state4 = CustomerVisitLog::changeState('无效', 'chaos');
  405. $state5 = Customer::changeState('无效', 'chaos');
  406. $state6 = Customer::changeState('待确认', 'chaos');
  407. $state7 = CustomerVisitLog::changeState('已量房', 'chaos');
  408. $state8 = CustomerVisitLog::changeState('已到场', 'chaos');
  409. $ismeet = [];
  410. foreach ($soud_list as $key => $val) {
  411. $soud_list[$key]['employee_id'] = !empty($param['employee_id']) ? $param['employee_id'] : '';
  412. $soud_list[$key]['org_id'] = !empty($param['org_id']) ? $param['org_id'] : '';
  413. $dd = $lf = $dc = $invalid_sign = $invalid_deposit = $exten_money = $exten_show = $exten_click = $clue_cont = $valid = $meet = $deposit = $sign = $basic_money = $other_money = $invalid_no = $invalid_yes = $invalid_meet = 0;
  414. $validids = $cusids = $vs_where = [];
  415. $customer_list = Customer::where($where)->where([['source_id', '=', $val['id']], ['state', 'not in', $state6]])->column('state', 'id');
  416. //$clue_cont = Customer::where($where)->where([['source_id','=',$val['id']]])->count();
  417. $clue_ids = Customer::where($where)->where([['source_id', '=', $val['id']]])->column('id');
  418. $del_clue_ids = Customer::where([['source_id', '=', $val['id']]])->onlyTrashed()->column('id');
  419. $clue_cont = count($clue_ids);
  420. foreach ($customer_list as $k => $v) {
  421. if (!in_array($v, $state5)) {
  422. $cusids[] = $k;
  423. $valid++;
  424. }
  425. }
  426. unset($customer_list);
  427. $validids = $cusids;
  428. //查询无效的客户
  429. $invalidcus = CustomerInvalidLog::hasWhere('customer',['source_id'=>$val['id']])->where([['CustomerInvalidLog.employee_id', 'in', $org_employee], ['CustomerInvalidLog.root_id', '=', $root_id], ['CustomerInvalidLog.source_id', '=', $val['id']], ['CustomerInvalidLog.cus_addtime', 'between', [$newtime[0] . ' 00:00:00', $newtime[1] . ' 23:59:59']]])->column('CustomerInvalidLog.customer_id,CustomerInvalidLog.employee_id,CustomerInvalidLog.status');
  430. foreach ($invalidcus as $k => $v) {
  431. if (!in_array($v['customer_id'], $validids)) {
  432. if ($v['status'] == 1) {
  433. $valid++;
  434. $validids[] = $v['customer_id'];
  435. }
  436. }
  437. if (!in_array($v['customer_id'], $clue_ids) && !in_array($v['customer_id'],$del_clue_ids)) {
  438. $clue_cont++;
  439. $clue_ids[] = $v['customer_id'];
  440. }
  441. }
  442. unset($clue_ids, $validids, $cusids);
  443. foreach ($exten_list as $k => $v) {
  444. if ($v['source_id'] == $val['id']) {
  445. $exten_money += $v['money'];
  446. $exten_show += $v['show'];
  447. $exten_click += $v['click'];
  448. }
  449. }
  450. $vs_where[] = ['customer_employee_id', 'in', $org_employee];
  451. $vs_where[] = ['confirm_date', 'between', [$newtime[0] . ' 00:00:00', $newtime[1] . ' 23:59:59']];
  452. $w = Customer::where('source_id', $val['id'])->withTrashed();
  453. $b_start = date('Y-m-d H:i:s', (strtotime($newtime[0])-1));
  454. $b_end = date('Y-m-d H:i:s', (strtotime($newtime[1]) + 86399));
  455. $visitlog_list = CustomerVisitLog::hasWhere('customer', $w)
  456. ->where([['CustomerVisitLog.customer_employee_id', 'in', $org_employee], ['CustomerVisitLog.confirm_date', 'between', [$b_start, $b_end]]])
  457. ->group('state,customer_id')->column('CustomerVisitLog.id,CustomerVisitLog.customer_id,CustomerVisitLog.state,CustomerVisitLog.money');
  458. $metids = [];
  459. foreach ($visitlog_list as $k => $v) {
  460. if (in_array($v['state'], array_merge($state1, $state2, $state3, $state7, $state8))) $metids[] = $v['customer_id'];
  461. }
  462. $empmod = new Empcrm($this->app);
  463. $yesids = !empty(array_unique($metids)) ? $empmod->selBeforelog(array_unique($metids), $newtime[0] . ' 00:00:00') : [];
  464. $isdep = $ising = $wuxiao = [];
  465. foreach ($visitlog_list as $k => $v) {
  466. if (in_array($v['state'], array_merge($state1, $state2, $state3, $state7, $state8)) && !in_array($v['customer_id'], $ismeet) && in_array($v['customer_id'], $yesids)) {
  467. $meet++;
  468. $ismeet[] = $v['customer_id'];
  469. }
  470. if (in_array($v['state'], $state1)) {
  471. $dd++;
  472. }
  473. if (in_array($v['state'], $state7)) {
  474. $lf++;
  475. }
  476. if (in_array($v['state'], $state8)) {
  477. $dc++;
  478. }
  479. if (in_array($v['state'], $state2)) {
  480. $deposit++;
  481. $isdep[] = $v['customer_id'];
  482. }
  483. if (in_array($v['state'], $state3)) {
  484. $sign++;
  485. $basic_money += $v['money'];
  486. $ising[] = $v['customer_id'];
  487. }
  488. if (in_array($v['state'], $state4)) $wuxiao[] = $v['customer_id'];
  489. }
  490. if (!empty($wuxiao)) {
  491. foreach ($wuxiao as $v) {
  492. if (in_array($v, $ismeet)) $invalid_meet++;
  493. if (in_array($v, $isdep)) $invalid_deposit++;
  494. if (in_array($v, $ising)) $invalid_sign++;
  495. }
  496. }
  497. unset($visitlog_list);
  498. $soud_list[$key]['dd'] = $dd;
  499. $soud_list[$key]['dc'] = $dc;
  500. $soud_list[$key]['lf'] = $lf;
  501. $soud_list[$key]['exten_money'] = !empty($exten_money) ? round($exten_money, 2) : 0;
  502. $soud_list[$key]['exten_show'] = $exten_show;
  503. $soud_list[$key]['exten_click'] = $exten_click;
  504. $soud_list[$key]['click_percen'] = !empty($exten_click) && !empty($exten_show) ? round($exten_click / $exten_show, 2) : 0;
  505. $soud_list[$key]['clue_conversion'] = !empty($exten_click) && !empty($clue_cont) ? round($clue_cont / $exten_click * 100, 2) : 0;
  506. $soud_list[$key]['clue_cont'] = $clue_cont;
  507. $soud_list[$key]['clue_money'] = !empty($clue_cont) && !empty($exten_money) ? round($exten_money / $clue_cont, 2) : 0;
  508. $soud_list[$key]['valid_cont'] = $valid;
  509. $soud_list[$key]['valid_money'] = !empty($valid) && !empty($exten_money) ? round($exten_money / $valid, 2) : 0;
  510. $soud_list[$key]['valid_percen'] = $valid && $clue_cont ? round($valid / $clue_cont * 100, 2) : 0;
  511. $soud_list[$key]['meet_cont'] = $meet;
  512. $soud_list[$key]['meet_percen'] = !empty($meet) && !empty($clue_cont) ? round($meet / $clue_cont * 100, 2) : 0;
  513. $soud_list[$key]['meet_money'] = !empty($meet) && !empty($exten_money) ? round($exten_money / $meet, 2) : 0;
  514. $soud_list[$key]['deposit_cont'] = $deposit;
  515. $soud_list[$key]['deposit_percen'] = !empty($deposit) && !empty($meet) ? round($deposit / $meet * 100, 2) : 0;
  516. $soud_list[$key]['sign_cont'] = $sign;
  517. $soud_list[$key]['basic_money'] = $basic_money;
  518. $soud_list[$key]['sign_agv_money'] = !empty($sign) && !empty($basic_money) ? floor($basic_money / $sign) : 0;
  519. $soud_list[$key]['other_money'] = $other_money;
  520. $soud_list[$key]['all_money'] = $basic_money + $other_money;
  521. $soud_list[$key]['invalid_no'] = $invalid_no;
  522. $soud_list[$key]['invalid_meet'] = $invalid_meet;
  523. $soud_list[$key]['invalid_deposit'] = $invalid_deposit;
  524. $soud_list[$key]['invalid_sign'] = $invalid_sign;
  525. $soud_list[$key]['ROI'] = !empty($exten_money) && !empty($basic_money) ? round($exten_money / $basic_money * 100, 2) : 0;
  526. //总数
  527. $t['dd'] += $dd;
  528. $t['dc'] += $dc;
  529. $t['lf'] += $lf;
  530. $t['exten_money'] += !empty($exten_money) ? round($exten_money, 2) : 0;
  531. $t['exten_show'] += $exten_show;
  532. $t['exten_click'] += $exten_click;
  533. $t['clue_conversion'] += !empty($exten_click) && !empty($clue_cont) ? round($clue_cont / $exten_click * 100, 2) : 0;
  534. $t['clue_cont'] += $clue_cont;
  535. $t['valid_cont'] += $valid;
  536. $t['meet_cont'] += $meet;
  537. $t['deposit_cont'] += $deposit;
  538. $t['sign_cont'] += $sign;
  539. $t['basic_money'] += $basic_money;
  540. $t['sign_agv_money'] += !empty($sign) && !empty($basic_money) ? floor($basic_money / $sign) : 0;
  541. $t['other_money'] += $other_money;
  542. $t['all_money'] += $other_money + $basic_money;
  543. $t['invalid_no'] += $invalid_no;
  544. $t['invalid_meet'] += $invalid_meet;
  545. $t['invalid_deposit'] += $invalid_deposit;
  546. $t['invalid_sign'] += $invalid_sign;
  547. }
  548. $t['exten_money'] = round($t['exten_money'], 2);
  549. $t['clue_money'] = $t['exten_money'] == 0 || $t['clue_cont'] == 0 ? 0 : round($t['exten_money'] / $t['clue_cont'], 2);
  550. $t['valid_money'] = $t['exten_money'] == 0 || $t['valid_cont'] == 0 ? 0 : round($t['exten_money'] / $t['valid_cont'], 2);
  551. $t['click_percen'] = $t['exten_show'] == 0 || $t['exten_click'] == 0 ? 0 : round($t['exten_click'] / $t['exten_show'] * 100, 2);
  552. $t['valid_percen'] = $t['clue_cont'] == 0 || $t['valid_cont'] == 0 ? 0 : round($t['valid_cont'] / $t['clue_cont'] * 100, 2);
  553. $t['meet_percen'] = $t['clue_cont'] == 0 || $t['meet_cont'] == 0 ? 0 : round($t['meet_cont'] / $t['clue_cont'] * 100, 2);
  554. $t['deposit_percen'] = $t['meet_cont'] == 0 || $t['deposit_cont'] == 0 ? 0 : round($t['deposit_cont'] / $t['meet_cont'] * 100, 2);
  555. $t['meet_money'] = $t['exten_money'] == 0 || $t['meet_cont'] == 0 ? 0 : round($t['exten_money'] / $t['meet_cont'], 2);
  556. $t['ROI'] = $t['exten_money'] == 0 || $t['basic_money'] == 0 ? 0 : round($t['exten_money'] / $t['basic_money'] * 100, 2);
  557. array_push($soud_list, $t);
  558. return json(['code' => 0, 'data' => $soud_list, 'count' => 0, 'msg' => '获取成功']);
  559. }
  560. public function account_detail()
  561. {
  562. $request = request();
  563. $root_id = $request->empcrm->root_id;
  564. $empid = $request->empcrm->id;
  565. $team_orgs = orgSubIds($request->empcrm->org_id);
  566. $param = $this->request->only(['date', 'source_id', 'org_id', 'employee_id', 'state', 'page' => 1, 'limit' => 17]);
  567. if (!$request->isAjax()) {
  568. View::assign('date', $param['date']);
  569. View::assign('state', $param['state']);
  570. View::assign('source_id', !empty($param['source_id']) ? $param['source_id'] : '');
  571. View::assign('employee_id', !empty($param['employee_id']) ? $param['employee_id'] : '');
  572. View::assign('org_id', !empty($param['org_id']) ? $param['org_id'] : '');
  573. return View::fetch();
  574. }
  575. $order = isset($param['order']) ? $param['order'] : 'id desc';
  576. $page = intval($param['page']);
  577. $limit = intval($param['limit']);
  578. //$org_employee = [$empid];
  579. $org_employee = Employee::where([['org_id', 'in', $team_orgs], ['state', '=', '在职'], ['uid', '>', 0]])->column('id');
  580. //$condition[] = ['org_id', 'in', $team_orgs];
  581. if (!empty($param['employee_id'])) $org_employee = [$param['employee_id']];
  582. if (!empty($param['org_id']) && empty($param['employee_id'])) {
  583. $org_employee = Employee::where([['root_id', '=', $root_id], ['org_id', 'in', orgSubIds($param['org_id'])]])->column('id');
  584. }
  585. $condition[] = ['employee_id', 'in', $org_employee];
  586. if (!empty($param['source_id'])) $condition[] = ['source_id', '=', $param['source_id']];
  587. //if($param['state']!='线索') $condition[] = ['state', 'not in',Customer::changeState('无效', 'chaos')];
  588. $condition[] = ['state', 'not in', Customer::changeState('无效', 'chaos')];
  589. if (empty($param['date'])) return json(['code' => 1, 'msg' => '参数错误']);
  590. if (!empty($param['date'])) {
  591. $newtime = explode('到', $param['date']);
  592. }
  593. $condition[] = ['sign_time', 'between', [$newtime[0] . ' 00:00:00', $newtime[1] . ' 23:59:59']];
  594. //$customer_list = Customer::where($condition)->column('id');
  595. $vlst = '确认到店';
  596. if ($param['state'] == '到访') {
  597. $vlst = '确认到店';
  598. } elseif ($param['state'] == '交定') {
  599. $vlst = '交定';
  600. } elseif ($param['state'] == '签单') {
  601. $vlst = '签单';
  602. } elseif ($param['state'] == '线索') {
  603. //$condition[] = ['addtime', 'between', [$newtime[0] . ' 00:00:00', $newtime[1] . ' 23:59:59']];
  604. $clue_contids = Customer::where($condition)->column('id');
  605. $delCondition = [
  606. ['org_id', 'in', orgSubIds($root_id)]
  607. ];
  608. if (!empty($param['source_id'])) $delCondition[] = ['source_id', '=', $param['source_id']];
  609. $del_clue_contids = Customer::where($delCondition)->onlyTrashed()->column('id');
  610. $wuxiaoids = CustomerInvalidLog::hasWhere('customer',['source_id'=>$param['source_id']])->where([['CustomerInvalidLog.employee_id', 'in', $org_employee], ['CustomerInvalidLog.source_id', '=', $param['source_id']], ['CustomerInvalidLog.root_id', '=', $root_id], ['CustomerInvalidLog.cus_addtime', 'between', [$newtime[0] . ' 00:00:00', $newtime[1] . ' 23:59:59']]])->column('CustomerInvalidLog.customer_id');
  611. if (!empty($wuxiaoids)) $clue_contids = array_merge($clue_contids, $wuxiaoids);
  612. $clue_contids = array_diff($clue_contids, $del_clue_contids);
  613. unset($condition);
  614. if (empty($clue_contids)) {
  615. return json(['code' => 0, 'data' => [], 'count' => 0]);
  616. }
  617. $condition = implode(',', $clue_contids);
  618. $page = ($page - 1) * 17;
  619. $empmod = new Empcrm($this->app);
  620. $data = $empmod->cus_recycle($condition, $page, $limit, $order, $root_id);
  621. return json(['code' => 0, 'data' => $data['data'], 'count' => $data['count']]);
  622. } elseif ($param['state'] == '有效') {
  623. $condition[] = ['state', 'not in', Customer::changeState('待确认', 'chaos')];
  624. //$condition[] = ['died', '<>', 2];
  625. $validids = Customer::where($condition)->column('id');
  626. $wuxiaoids = CustomerInvalidLog::hasWhere('customer',['source_id'=>$param['source_id']])->where([['CustomerInvalidLog.employee_id', 'in', $org_employee], ['CustomerInvalidLog.status', '=', 1], ['CustomerInvalidLog.source_id', '=', $param['source_id']], ['CustomerInvalidLog.root_id', '=', $root_id], ['CustomerInvalidLog.cus_addtime', 'between', [$newtime[0] . ' 00:00:00', $newtime[1] . ' 23:59:59']]])->column('CustomerInvalidLog.customer_id');
  627. if (!empty($wuxiaoids)) $validids = array_merge($validids, $wuxiaoids);
  628. unset($condition);
  629. $condition = implode(',', $validids);
  630. $page = ($page - 1) * 17;
  631. $empmod = new Empcrm($this->app);
  632. $data = $empmod->cus_recycle($condition, $page, $limit, $order, $root_id);
  633. return json(['code' => 0, 'data' => $data['data'], 'count' => $data['count']]);
  634. }
  635. $where[] = ['customer_employee_id', 'in', $org_employee];
  636. if ($vlst == '确认到店') {
  637. $where[] = ['state', 'in', array_merge(CustomerVisitLog::changeState($vlst, 'chaos'), CustomerVisitLog::changeState('已到场', 'chaos'), CustomerVisitLog::changeState('已量房', 'chaos'), CustomerVisitLog::changeState('已交定', 'chaos'), CustomerVisitLog::changeState('已签单', 'chaos'))];
  638. } else {
  639. $where[] = ['state', 'in', CustomerVisitLog::changeState($vlst, 'chaos')];
  640. }
  641. if (!empty($param['date'])) {
  642. $b_start = date('Y-m-d H:i:s', (strtotime($newtime[0])-1));
  643. $b_end = date('Y-m-d H:i:s', (strtotime($newtime[1])+86399));
  644. $where[] = ['confirm_date', 'between', [$b_start, $b_end]];
  645. }
  646. $vslogid = CustomerVisitLog::where($where)->group('customer_id')->column('customer_id');
  647. $vslogid = !empty($vslogid) ? array_unique($vslogid) : [];
  648. if (!in_array($param['state'], ['线索', '有效'])) {
  649. unset($condition);
  650. $empmod = new Empcrm($this->app);
  651. if ($vlst == '确认到店') {
  652. $vslogid = !empty(array_unique($vslogid)) ? $empmod->selBeforelog($vslogid, $newtime[0] . ' 00:00:00') : [];
  653. }
  654. $condition[] = ['id', 'in', $vslogid];
  655. if (!empty($param['source_id'])) $condition[] = ['source_id', '=', $param['source_id']];
  656. $source_cusids = Customer::where($condition)->withTrashed()->column('id');
  657. $wx_where[] = ['customer_id', 'in', $vslogid];
  658. $wx_where[] = ['employee_id', 'in', $org_employee];
  659. $wx_where[] = ['root_id', '=', $root_id];
  660. if (!empty($param['source_id'])) $wx_where[] = ['source_id', '=', $param['source_id']];
  661. $wuxiaoids = CustomerInvalidLog::where($wx_where)->column('customer_id');
  662. if (!empty($wuxiaoids)) $source_cusids = array_unique(array_merge($source_cusids, $wuxiaoids));
  663. unset($condition);
  664. $condition = implode(',', $source_cusids);
  665. $page = ($page - 1) * 17;
  666. //$empmod = new Empcrm($this->app);
  667. $data = $empmod->cus_recycle($condition, $page, $limit, $order, $root_id);
  668. return json(['code' => 0, 'data' => $data['data'], 'count' => $data['count']]);
  669. }
  670. $data = $this->selCustomer($condition, $page, $limit, $order, $root_id);
  671. $count = Customer::where($condition)->count();
  672. return json(['code' => 0, 'data' => $data, 'count' => $count]);
  673. }
  674. public function account_detail_fish()
  675. {
  676. $request = request();
  677. $root_id = $request->empcrm->root_id;
  678. $empid = $request->empcrm->id;
  679. $team_orgs = orgSubIds($request->empcrm->org_id);
  680. $param = $this->request->only(['date', 'source_id', 'org_id', 'employee_id', 'state', 'page' => 1, 'limit' => 17]);
  681. if (!$request->isAjax()) {
  682. View::assign('date', $param['date']);
  683. View::assign('state', $param['state']);
  684. View::assign('source_id', !empty($param['source_id']) ? $param['source_id'] : '');
  685. View::assign('employee_id', !empty($param['employee_id']) ? $param['employee_id'] : '');
  686. View::assign('org_id', !empty($param['org_id']) ? $param['org_id'] : '');
  687. return View::fetch();
  688. }
  689. if (empty($param['source_id'])) $param['source_id'] = 0;
  690. $order = isset($param['order']) ? $param['order'] : 'id desc';
  691. $page = intval($param['page']);
  692. $limit = intval($param['limit']);
  693. //$org_employee = [$empid];
  694. $org_employee = Employee::where([['org_id', 'in', $team_orgs], ['state', '=', '在职'], ['uid', '>', 0]])->column('id');
  695. //$condition[] = ['org_id', 'in', $team_orgs];
  696. if (!empty($param['employee_id'])) $org_employee = [$param['employee_id']];
  697. if (!empty($param['org_id']) && empty($param['employee_id'])) {
  698. $org_employee = Employee::where([['root_id', '=', $root_id], ['org_id', 'in', orgSubIds($param['org_id'])]])->column('id');
  699. }
  700. $condition[] = ['employee_id', 'in', $org_employee];
  701. $tmp_sourceids = CustomerSource::where([['root_id', '=', $root_id], ['source', 'in', ['飞鱼线索','腾讯线索']]])->column('id');
  702. $condition[] = ['source_id', 'in', $tmp_sourceids];
  703. //if($param['state']!='线索') $condition[] = ['state', 'not in',Customer::changeState('无效', 'chaos')];
  704. $condition[] = ['state', 'not in', Customer::changeState('无效', 'chaos')];
  705. if (empty($param['date'])) return json(['code' => 1, 'msg' => '参数错误']);
  706. if (!empty($param['date'])) {
  707. $newtime = explode('到', $param['date']);
  708. }
  709. $condition[] = ['sign_time', 'between', [$newtime[0] . ' 00:00:00', $newtime[1] . ' 23:59:59']];
  710. //$customer_list = Customer::where($condition)->column('id');
  711. $vlst = '飞鱼确认到店';
  712. if ($param['state'] == '飞鱼到访') {
  713. $vlst = '飞鱼确认到店';
  714. } elseif ($param['state'] == '飞鱼交定') {
  715. $vlst = '飞鱼交定';
  716. } elseif ($param['state'] == '飞鱼签单') {
  717. $vlst = '飞鱼签单';
  718. }
  719. if ($param['state'] == '飞鱼有效') {
  720. $tmp_validids = FishData::where([['is_allocation', '=', 1], ['type', 'in', [1, 2, 4]], ['root_id', '=', $root_id], ['advertiser_id', '=', $param['source_id']], ['employee_id', 'in', $org_employee]])->column('customer_id');
  721. $condition[] = ['id', 'in', $tmp_validids];
  722. $validids = Customer::where($condition)->column('id');
  723. $wuxiaoids = CustomerInvalidLog::where([['employee_id', 'in', $org_employee], ['status', '=', 1], ['root_id', '=', $root_id], ['cus_addtime', 'between', [$newtime[0] . ' 00:00:00', $newtime[1] . ' 23:59:59']]])->column('customer_id');
  724. if (!empty($wuxiaoids)) $validids = array_merge($validids, $wuxiaoids);
  725. unset($condition);
  726. $condition = implode(',', $validids);
  727. $page = ($page - 1) * 17;
  728. $empmod = new Empcrm($this->app);
  729. $data = $empmod->cus_recycle($condition, $page, $limit, $order, $root_id);
  730. return json(['code' => 0, 'data' => $data['data'], 'count' => $data['count']]);
  731. }
  732. $where[] = ['customer_employee_id', 'in', $org_employee];
  733. if ($vlst == '飞鱼交定') {
  734. $state3 = CustomerVisitLog::changeState('已交定', 'chaos');
  735. $validids = FishData::where([['is_allocation', '=', 1], ['type', 'in', [1, 2, 4]], ['root_id', '=', $root_id], ['advertiser_id', '=', $param['source_id']], ['employee_id', 'in', $org_employee]])->column('customer_id');
  736. $where[] = ['customer_id', 'in', $validids];
  737. $where[] = ['state', 'in', $state3];
  738. } elseif ($vlst == '飞鱼签单') {
  739. $state3 = CustomerVisitLog::changeState('已签单', 'chaos');
  740. $validids = FishData::where([['is_allocation', '=', 1], ['type', 'in', [1, 2, 4]], ['root_id', '=', $root_id], ['advertiser_id', '=', $param['source_id']], ['employee_id', 'in', $org_employee]])->column('customer_id');
  741. $where[] = ['customer_id', 'in', $validids];
  742. $where[] = ['state', 'in', $state3];
  743. } elseif ($vlst == '飞鱼确认到店') {
  744. $state3 = CustomerVisitLog::changeState('已交定', 'chaos');
  745. $state4 = CustomerVisitLog::changeState('已签单', 'chaos');
  746. $state5 = CustomerVisitLog::changeState('确认到店', 'chaos');
  747. $state6 = CustomerVisitLog::changeState('已到场', 'chaos');
  748. $state7 = CustomerVisitLog::changeState('已量房', 'chaos');
  749. $validids = FishData::where([['is_allocation', '=', 1], ['type', 'in', [1, 2, 4]], ['root_id', '=', $root_id], ['advertiser_id', '=', $param['source_id']], ['employee_id', 'in', $org_employee]])->column('customer_id');
  750. $where[] = ['customer_id', 'in', $validids];
  751. $where[] = ['state', 'in', array_merge($state3, $state4, $state5, $state6, $state7)];
  752. } else {
  753. $where[] = ['state', 'in', CustomerVisitLog::changeState($vlst, 'chaos')];
  754. }
  755. if (!empty($param['date'])) {
  756. $where[] = ['confirm_date', 'between', [$newtime[0] . ' 00:00:00', $newtime[1] . ' 23:59:59']];
  757. }
  758. $vslogid = CustomerVisitLog::where($where)->column('customer_id');
  759. $vslogid = !empty($vslogid) ? array_unique($vslogid) : [];
  760. if (!in_array($param['state'], ['线索', '有效'])) {
  761. unset($condition);
  762. $empmod = new Empcrm($this->app);
  763. if ($vlst == '确认到店') {
  764. $vslogid = !empty(array_unique($vslogid)) ? $empmod->selBeforelog($vslogid, $newtime[0] . ' 00:00:00') : [];
  765. }
  766. $condition[] = ['id', 'in', $vslogid];
  767. if (!empty($param['source_id']) && $vlst != '飞鱼确认到店' && $vlst != '飞鱼交定' && $vlst != '飞鱼签单') {
  768. $condition[] = ['source_id', '=', $param['source_id']];
  769. $wx_where[] = ['source_id', '=', $param['source_id']];
  770. }
  771. if ($vlst == '飞鱼确认到店' || $vlst == '飞鱼交定' || $vlst == '飞鱼签单') {
  772. $condition[] = ['source_id', 'in', $tmp_sourceids];
  773. $wx_where[] = ['source_id', 'in', $tmp_sourceids];
  774. }
  775. $source_cusids = Customer::where($condition)->withTrashed()->column('id');
  776. $wx_where[] = ['customer_id', 'in', $vslogid];
  777. $wx_where[] = ['employee_id', 'in', $org_employee];
  778. $wx_where[] = ['root_id', '=', $root_id];
  779. // if (!empty($param['source_id'])) $wx_where[] = ['source_id', '=', $param['source_id']];
  780. $wuxiaoids = CustomerInvalidLog::where($wx_where)->column('customer_id');
  781. if (!empty($wuxiaoids)) $source_cusids = array_unique(array_merge($source_cusids, $wuxiaoids));
  782. unset($condition);
  783. $condition = implode(',', $source_cusids);
  784. $page = ($page - 1) * 17;
  785. //$empmod = new Empcrm($this->app);
  786. $data = $empmod->cus_recycle($condition, $page, $limit, $order, $root_id);
  787. return json(['code' => 0, 'data' => $data['data'], 'count' => $data['count']]);
  788. }
  789. $data = $this->selCustomer($condition, $page, $limit, $order, $root_id);
  790. $count = Customer::where($condition)->count();
  791. return json(['code' => 0, 'data' => $data, 'count' => $count]);
  792. }
  793. //公用查询列表
  794. public function selCustomer($condition, $page, $limit, $order, $root_id)
  795. {
  796. $data = Customer::with(['employee', 'org', 'designer', 'source'])
  797. ->withCount(['visitLog' => function ($query) {
  798. $query->where([[CustomerVisitLog::changeState(['state', '=', '未到访'])]]);
  799. }])
  800. ->where($condition)
  801. ->page($page, $limit)->order($order)->select();
  802. $data = $data->visible(['id', 'employee_id', 'name', 'introduce', 'community_name', 'phone', 'level', 'state', 'square', 'revisit_time', 'addtime', 'last_contact_date', 'org_id', 'protected_to', 'is_resource', 'employee.name', 'org_name', 'designer.name', 'visit_log_count', 'activity_frequency_count', 'source_id', 'source.source', 'phone1', 'phone2', 'remark', 'crm_res_id', 'agents_id', 'sign_time', 'house_delivery_time', 'first_visit_date', 'ext', 'transfer_info', 'deposit_money', 'signed_money', 'package_id'])->toArray();
  803. $setting = Setting::where([['name', '=', 'pubpool'], ['root_id', '=', $root_id]])->find();
  804. if (!empty($setting)) {
  805. $setting_content = json_decode($setting['content'], true);
  806. } else {
  807. $setting_content = [];
  808. }
  809. foreach ($data as &$item) {
  810. $item['un_protected'] = false;
  811. if (!empty($item['protected_to']) && time() > strtotime($item['protected_to'])) {
  812. $state_n = Customer::changeState($item['state'], 'n');
  813. if (isset($setting_content[$state_n]['state']) && $setting_content[$state_n]['state'] == 1) {
  814. $item['un_protected'] = true;
  815. }
  816. }
  817. if ($item['state'] == '已签单') $item['state'] = '已转单';
  818. if ($item['state'] == '已交定') $item['state'] = '已签单';
  819. $item['square'] = floatval($item['square']);
  820. $item['phone'] = substr_replace($item['phone'], '******', 3, 6);
  821. $item['phone1'] = $item['phone1'] ? substr_replace($item['phone1'], '******', 3, 6) : '';
  822. $item['phone2'] = $item['phone2'] ? substr_replace($item['phone2'], '******', 3, 6) : '';
  823. $item['jiaofang'] = !empty($item['house_delivery_time']) ? (str_replace('/', '-', $item['house_delivery_time']) <= date('Y-m-d', time()) ? '现房' : $item['house_delivery_time']) : '';
  824. $vlotime = CustomerVisitLog::where([['customer_id', '=', $item['id']], [CustomerVisitLog::changeState(['state', '=', '未到访'])]])->order('addtime desc')->value('addtime');
  825. //$fisttime = CustomerVisitLog::where([['customer_id','=',$item['id']],['customer_employee_id','=',$item['employee_id']],[CustomerVisitLog::changeState(['state', '=', '确认到店'])]])->order('addtime asc')->value('addtime');
  826. $fisttime = CustomerVisitLog::where([['customer_id', '=', $item['id']], [CustomerVisitLog::changeState(['state', '=', '确认到店'])]])->order('addtime asc')->value('addtime');
  827. //$jiaodingtime = CustomerVisitLog::where([['customer_id','=',$item['id']],['customer_employee_id','=',$item['employee_id']],[CustomerVisitLog::changeState(['state', '=', '已交定'])]])->order('addtime desc')->value('addtime');
  828. $jiaodingtime = CustomerVisitLog::where([['customer_id', '=', $item['id']], [CustomerVisitLog::changeState(['state', '=', '已交定'])]])->order('addtime desc')->value('addtime');
  829. $item['sign'] = CustomerVisitLog::where([['customer_id', '=', $item['id']], ['customer_employee_id', '=', $item['employee_id']], [CustomerVisitLog::changeState(['state', '=', '已签单'])]])->find();
  830. $item['fisttime'] = $fisttime ? $fisttime : '';
  831. $item['jiaoding_time'] = $jiaodingtime ? $jiaodingtime : '';
  832. }
  833. return $data;
  834. }
  835. //设计师报表
  836. public function designer_report()
  837. {
  838. $request = request();
  839. $root_id = $request->empcrm->root_id;
  840. $empid = $request->empcrm->id;
  841. $is_manager = $request->empcrm->is_manager;
  842. $team_orgs = orgSubIds($request->empcrm->org_id);
  843. $param = $this->request->only(['date', 'source_id', 'org_id']);
  844. if (!$request->isAjax()) {
  845. $org_data = Org::where([['id', 'in', $team_orgs]])->field('id,name')->select(); //->toArray();
  846. View::assign('org_data', $org_data);
  847. $data['company_name'] = Company::where('root_id', $root_id)->value('company_name');
  848. $data['empname'] = $request->empcrm->name;
  849. View::assign('data', $data);
  850. $soudata = CustomerSource::field('id,source as name')->where('root_id', $root_id)->select()->toArray();
  851. View::assign('soudata', $soudata);
  852. View::assign('is_manager', $is_manager);
  853. return View::fetch();
  854. }
  855. // 获取部门列表
  856. $param_sub_org = $team_orgs;
  857. if (!empty($param['org_id'])) $param_sub_org = [$param['org_id']];
  858. if (!empty($param['date'])) {
  859. $newtime = explode('到', $param['date']);
  860. } else {
  861. return json(['code' => 1, 'msg' => '日期为空']);
  862. }
  863. //层级以下所有客户指派的设计师
  864. $designer_where = [
  865. ['org_id', 'in', $param_sub_org],
  866. ['designer_id', '>', 0],
  867. ['addtime', 'between', [$newtime[0] . ' 00:00:00', $newtime[1] . ' 23:59:59']]
  868. ];
  869. if (!empty($param['source_id'])) $designer_where[] = ['source_id', '=', $param['source_id']];
  870. $designer_id = Customer::where($designer_where)->group('designer_id')->column('designer_id');
  871. //查询无效后的设计师
  872. $wxdesignerids = CustomerInvalidLog::where([['root_id', '=', $root_id], ['status', '=', 1], ['org_id', 'in', $param_sub_org], ['cus_addtime', 'between', [$newtime[0] . ' 00:00:00', $newtime[1] . ' 23:59:59']], ['designer_id', '>', 0]])->group('designer_id')->column('designer_id');
  873. if (!empty($wxdesignerids)) $designer_id = array_unique(array_merge($designer_id, $wxdesignerids));
  874. $designer_list = Employee::where([['id', 'in', $designer_id], ['root_id', '=', $root_id], ['state', '=', '在职'], ['uid', '>', 0]])->field('id,name')->select()->toArray();
  875. // 客户
  876. //$designer_ids = !empty($designer_list) ? array_column($designer_list, 'id') : [];
  877. $customer_id = Customer::where([['org_id', 'in', $param_sub_org], ['designer_id', '>', 0]])->column('id');
  878. $where = [
  879. ['addtime', 'between', [$newtime[0] . ' 00:00:00', $newtime[1] . ' 23:59:59']],
  880. ['id', 'in', $customer_id]
  881. ];
  882. if (!empty($param['source_id'])) $where[] = ['source_id', '=', $param['source_id']];
  883. $customer_list = Customer::where($where)->field('id,name,state,source_id,employee_id,designer_id,died')->select()->toArray();
  884. $invalidcus = CustomerInvalidLog::where([
  885. ['cus_addtime', 'between', [$newtime[0].' 00:00:00',$newtime[1].' 23:59:59']],
  886. ['designer_id','in',$designer_id],
  887. ['root_id','=',$root_id]
  888. ])->column('designer_id,employee_id,status');
  889. $t = ['name' => '求和', 'deposit_percen' => 0, 'dai_confirmed' => 0, 'exten_money' => 0, 'exten_show' => 0, 'exten_click' => 0, 'click_percen' => 0, 'clue_conversion' => 0, 'clue_money' => 0, 'valid_money' => 0, 'meet_money' => 0, 'sign_agv_money' => 0, 'ROI' => 0, 'week' => '', 'data' => [], 'clue_cont' => 0, 'valid_cont' => 0, 'valid_percen' => 0, 'meet_cont' => 0, 'meet_percen' => 0, 'deposit_cont' => 0, 'sign_cont' => 0, 'basic_money' => 0, 'other_money' => 0, 'all_money' => 0, 'invalid_no' => 0, 'invalid_yes' => 0, 'invalid_meet' => 0, 'invalid_deposit' => 0, 'invalid_sign' => 0];
  890. foreach ($designer_list as $key => $val) {
  891. $dai_confirmed = $exten_money = $exten_show = $exten_click = $clue_cont = $valid = $meet = $deposit = $sig· = $basic_money = $other_money = $invalid_no = $invalid_yes = $invalid_meet = 0;
  892. $cusids = [];
  893. $vs_where = [];
  894. foreach ($customer_list as $k => $v) {
  895. if (in_array($val['id'], [$v['employee_id'], $v['designer_id']])) {
  896. $cusids[] = $v['id'];
  897. $clue_cont++;
  898. if ($v['died'] != 2 && !in_array($v['state'], array_merge(Customer::changeState('无效', 'chaos'), Customer::changeState('待确认', 'chaos')), true)) $valid++;
  899. if (in_array($v['state'], Customer::changeState('待确认', 'chaos'))) $dai_confirmed++;
  900. }
  901. }
  902. //处理无效的客户还原到员工身上为有效
  903. foreach($invalidcus as $k=>$v){
  904. if(in_array($val['id'],[$v['employee_id'],$v['designer_id']])){
  905. $clue_cont++;
  906. if($v['status'] == 1) $valid++;
  907. }
  908. }
  909. // 见面量只统计一次(到场、到店、量房)
  910. if (empty($param['source_id'])) {
  911. $visilog = CustomerVisitLog::where([
  912. ['employee_id', '=', $val['id']],
  913. ['customer_id', 'in', $customer_id],
  914. ['confirm_date', 'between', [$newtime[0] . ' 00:00:00', $newtime[1] . ' 23:59:59']],
  915. ['state', 'in', array_merge(CustomerVisitLog::changeState('确认到店', 'chaos'), CustomerVisitLog::changeState('已到场', 'chaos'), CustomerVisitLog::changeState('已量房', 'chaos'))]
  916. ])->column('customer_id');
  917. } else {
  918. $visilog = CustomerVisitLog::hasWhere('customer',['source_id'=>$param['source_id']])
  919. ->where([
  920. ['CustomerVisitLog.employee_id', '=', $val['id']],
  921. ['CustomerVisitLog.customer_id', 'in', $customer_id],
  922. ['CustomerVisitLog.confirm_date', 'between', [$newtime[0] . ' 00:00:00', $newtime[1] . ' 23:59:59']],
  923. ['CustomerVisitLog.state','in',array_merge(CustomerVisitLog::changeState('确认到店','chaos'), CustomerVisitLog::changeState('已到场','chaos'), CustomerVisitLog::changeState('已量房','chaos'))]
  924. ])->column('CustomerVisitLog.customer_id');
  925. }
  926. $meet = 0;
  927. if (!empty(array_unique($visilog))) {
  928. $new = new Empcrm($this->app);
  929. $meet = $new->selBeforelog(array_unique($visilog), $newtime[0] . ' 00:00:00');
  930. $meet = count($meet);
  931. }
  932. $vs_where[] = ['customer_id', 'in', $cusids];
  933. $vs_where[] = ['confirm_date', 'between', [$newtime[0] . ' 00:00:00', $newtime[1] . ' 23:59:59']];
  934. //$valid = CustomerVisitLog::where($vs_where)->where('state', 'in', $now_status)->group('customer_id')->count();
  935. $deposit = CustomerVisitLog::where($vs_where)->where('state', 'in', CustomerVisitLog::changeState('已交定', 'chaos'))->group('customer_id')->count();
  936. $sign = CustomerVisitLog::where($vs_where)->where('state', 'in', CustomerVisitLog::changeState('已签单', 'chaos'))->group('customer_id')->count();
  937. //$meet = CustomerVisitLog::where($vs_where)->where('state', 'in', CustomerVisitLog::changeState('确认到店', 'chaos'))->group('customer_id')->count();
  938. //$basic_money = CustomerVisitLog::where($vs_where)->where('state','in',array_merge(CustomerVisitLog::changeState('已交定','chaos'),CustomerVisitLog::changeState('已签单','chaos')))->sum('money');
  939. $basic_money = CustomerVisitLog::where($vs_where)->where('state', 'in', CustomerVisitLog::changeState('已签单', 'chaos'))->sum('money');
  940. $wuxiao = CustomerVisitLog::where($vs_where)->where('state', 'in', CustomerVisitLog::changeState('无效', 'chaos'))->group('customer_id')->column('customer_id');
  941. $invalid_meet = CustomerVisitLog::where('state', 'in', CustomerVisitLog::changeState('确认到店', 'chaos'))->where([['customer_id', 'in', $wuxiao]])->group('customer_id')->count();
  942. $invalid_deposit = CustomerVisitLog::where('state', 'in', CustomerVisitLog::changeState('已交定', 'chaos'))->where([['customer_id', 'in', $wuxiao]])->group('customer_id')->count();
  943. $invalid_sign = CustomerVisitLog::where('state', 'in', CustomerVisitLog::changeState('已签单', 'chaos'))->where([['customer_id', 'in', $wuxiao]])->group('customer_id')->count();
  944. $designer_list[$key]['clue_cont'] = $clue_cont;
  945. $designer_list[$key]['valid_cont'] = $valid;
  946. $designer_list[$key]['valid_percen'] = $valid && $clue_cont ? round($valid / $clue_cont * 100, 2) : 0;
  947. $designer_list[$key]['dai_confirmed'] = $dai_confirmed;
  948. $designer_list[$key]['meet_cont'] = $meet;
  949. $designer_list[$key]['meet_percen'] = !empty($meet) && !empty($clue_cont) ? round($meet / $clue_cont * 100, 2) : 0;
  950. $designer_list[$key]['deposit_cont'] = $deposit;
  951. $designer_list[$key]['deposit_percen'] = !empty($deposit) && !empty($meet) ? round($deposit / $meet * 100, 2) : 0;
  952. $designer_list[$key]['sign_cont'] = $sign;
  953. $designer_list[$key]['basic_money'] = $basic_money;
  954. $designer_list[$key]['sign_agv_money'] = !empty($sign_cont) && !empty($basic_money) ? floor($basic_money / $sign_cont) : 0;
  955. $designer_list[$key]['other_money'] = 0;
  956. $designer_list[$key]['all_money'] = $basic_money;
  957. //$xin[$key]['invalid_no'] = $invalid_no;
  958. //$xin[$key]['invalid_yes'] = $invalid_yes;
  959. $designer_list[$key]['invalid_meet'] = $invalid_meet;
  960. $designer_list[$key]['invalid_deposit'] = $invalid_deposit;
  961. $designer_list[$key]['invalid_sign'] = $invalid_sign;
  962. //总数
  963. $t['clue_cont'] += $clue_cont;
  964. $t['valid_cont'] += $valid;
  965. // $t['valid_percen'] += !empty($valid) && !empty($clue_cont) ? round($valid/$clue_cont*100,2) : 0;
  966. //$t['valid_percen'] += $designer_list[$key]['valid_percen'];
  967. $t['dai_confirmed'] += $dai_confirmed;
  968. $t['meet_cont'] += $meet;
  969. // $t['meet_percen'] += !empty($meet) && !empty($clue_cont) ? round($meet/$clue_cont*100,2) : 0;
  970. $t['deposit_cont'] += $deposit;
  971. // $t['deposit_percen'] += !empty($deposit) && !empty($meet) ? round($deposit/$meet*100,2) : 0;
  972. $t['sign_cont'] += $sign;
  973. $t['basic_money'] += $basic_money;
  974. $t['sign_agv_money'] += !empty($sign_cont) && !empty($basic_money) ? floor($basic_money / $sign_cont) : 0;
  975. $t['other_money'] += 0;
  976. $t['all_money'] += $basic_money;
  977. // $t['invalid_no'] += $invalid_no;
  978. // $t['invalid_yes'] += $invalid_yes;
  979. $t['invalid_meet'] += $invalid_meet;
  980. $t['invalid_deposit'] += $invalid_deposit;
  981. $t['invalid_sign'] += $invalid_sign;
  982. }
  983. $t['valid_percen'] = $t['clue_cont'] == 0 ? 0 : round($t['valid_cont'] / $t['clue_cont'] * 100, 2);
  984. $t['meet_percen'] = $t['clue_cont'] == 0 ? 0 : round($t['meet_cont'] / $t['clue_cont'] * 100, 2);
  985. $t['deposit_percen'] = $t['meet_cont'] == 0 ? 0 : round($t['deposit_cont'] / $t['meet_cont'] * 100, 2);
  986. array_push($designer_list, $t);
  987. return json(['code' => 0, 'data' => $designer_list, 'count' => 0, 'msg' => '获取成功']);
  988. }
  989. //校对
  990. public function proofread()
  991. {
  992. $request = request();
  993. $root_id = $request->empcrm->root_id;
  994. $empid = $request->empcrm->id;
  995. $team_orgs = orgSubIds($request->empcrm->org_id);
  996. $param = $this->request->only(['phone', 'org_id', 'source_id', 'channel_id']);
  997. $is_manager = request()->empcrm->is_manager;
  998. if (!$request->isAjax()) {
  999. $data['company_name'] = Company::where('root_id', $root_id)->value('company_name');
  1000. $data['empname'] = $request->empcrm->name;
  1001. View::assign('data', $data);
  1002. $all_orgs = orgSubIds($request->empcrm->root_id);
  1003. $org_list = Org::where('id', 'in', $all_orgs)->field('id,name')->select()->toArray();
  1004. View::assign('org_list', $org_list);
  1005. $source_list = CustomerSource::where('root_id', $root_id)->column('id,source');
  1006. View::assign('source_list', $source_list);
  1007. View::assign('root_id', $root_id);
  1008. return View::fetch();
  1009. }
  1010. if (empty($param['phone'])) return json(['code' => 1, 'data' => '', 'msg' => '手机号为空']);
  1011. $pharr = explode(',', $param['phone']);
  1012. foreach ($pharr as $key => $val) {
  1013. $xin[] = cypherphone(trim($val));
  1014. }
  1015. if (!empty($param['org_id'])) {
  1016. $team_orgs = orgSubIds($param['org_id']);
  1017. }
  1018. if (empty($param['org_id'])) {
  1019. $team_orgs = orgSubIds($request->empcrm->root_id);
  1020. }
  1021. //$where[] = ['phone|phone1|phone2', 'in', $xin];
  1022. $where[] = ['phone', 'in', $xin];
  1023. $where[] = ['org_id', 'in', $team_orgs];
  1024. $fish_where[] = ['telephone', 'in', $pharr];
  1025. $fish_where[] = ['org_id', 'in', $team_orgs];
  1026. if (empty($param['channel_id'])) {
  1027. if (!empty($param['source_id'])) $where[] = ['source_id', '=', $param['source_id']];
  1028. $customer_list = Customer::with(['source' => function ($query) {
  1029. $query->field('id,source');
  1030. }, 'employee' => function ($query) {
  1031. $query->field('id,name');
  1032. }, 'org'])->where($where)->field('id,name,phone,phone1,phone2,community_name,square,ext,house_status,source_id,state,employee_id,is_resource,org_id,sign_time')->select()->toArray();
  1033. $visit_state = [7=>'已到店', 8=>'已量房', 9=>'已到场', 2=>'已签单', 3=>'已转单', 15=>'已卖卡'];
  1034. foreach ($customer_list as $key => $val) {
  1035. if ($val['state'] == '无效') {
  1036. $customer_employee_id = CustomerVisitLog::where([['customer_id', '=', $val['id']], ['state', 'in', CustomerVisitLog::changeState('无效', 'chaos')]])->order('addtime desc')->value('customer_employee_id');
  1037. $customer_list[$key]['employee'] = $customer_employee_id ? Employee::where([['root_id', '=', $root_id], ['id', '=', $customer_employee_id]])->field('id,name')->find() : '';
  1038. }
  1039. //不是管理员则无法查看详情
  1040. if ($is_manager == 0) {
  1041. $customer_list[$key]['id'] = 0;
  1042. if ($val['employee_id'] == $empid) {
  1043. $customer_list[$key]['id'] = $val;
  1044. }
  1045. }
  1046. // 查询客户状态
  1047. $customerState = CustomerVisitLog::where(['customer_id'=>$val['id']])->group('state')->column('state');
  1048. $customer_list[$key]['state'] = '';
  1049. $stateForCustomer = [];
  1050. foreach($customerState as $s) {
  1051. if(isset($visit_state[$s])) $stateForCustomer[] = $visit_state[$s];
  1052. }
  1053. $customer_list[$key]['state'] = !empty($stateForCustomer) ? implode(',', $stateForCustomer) : Customer::changeState($val['state'], 'state');
  1054. }
  1055. $xin = $nopr = $pr = [];
  1056. foreach ($customer_list as $k => $v) {
  1057. $v['phone1'] = !empty($v['phone1']) ? substr_replace($v['phone1'], '****', 3, 4) : '';
  1058. $v['phone2'] = !empty($v['phone2']) ? substr_replace($v['phone2'], '****', 3, 4) : '';
  1059. $xin[] = ['data' => $v, 'phone' => $v['phone']];
  1060. $pr[] = $v['phone'];
  1061. // if(!empty($v['phone1'])){
  1062. // $pr[] = $v['phone1'];
  1063. // }
  1064. // if(!empty($v['phone2'])){
  1065. // $pr[] = $v['phone2'];
  1066. // }
  1067. }
  1068. foreach ($pharr as $key => $val) {
  1069. if (!in_array($val, $pr)) {
  1070. $nopr[] = ['data' => null, 'phone' => $val];
  1071. }
  1072. }
  1073. //查询回收站是否存在
  1074. foreach ($nopr as $key => $val) {
  1075. $nopr[$key]['data'] = CustomerRecycle::with(['source' => function ($query) {
  1076. $query->field('id,source');
  1077. }, 'org'])->where([['org_id', 'in', $team_orgs], ['phone', '=', cypherphone($val['phone'])]])
  1078. ->field('id,name,phone,phone1,phone2,community_name,square,ext,house_status,source_id,state,employee_id,is_resource,org_id')->find();
  1079. }
  1080. $new = array_merge($xin, $nopr);
  1081. // 按照校验手机号排序
  1082. $new_list = [];
  1083. $pharr = array_unique($pharr);
  1084. foreach ($pharr as $k => $v) {
  1085. foreach ($new as $kk => $vv) {
  1086. if ($vv['phone'] == $v) {
  1087. $new_list[] = $vv;
  1088. }
  1089. }
  1090. }
  1091. } else {
  1092. //,phone1,phone2,community_name,square,ext,house_status,source_id,state,employee_id,is_resource,org_id,sign_time
  1093. $new_list = [];
  1094. $fish_list = FishData::with(['org'])->where($fish_where)->field('name,telephone,location,clue_state,clue_owner_name,advertiser_name,create_time_detail,is_allocation,org_id')->select()->toArray();
  1095. foreach ($pharr as $k => $v) {
  1096. $new_list[$k]['phone'] = $v;
  1097. $new_list[$k]['data'] = '';
  1098. foreach ($fish_list as $ky => $vy) {
  1099. if ($vy['telephone'] == $v) {
  1100. $tmp_val = [
  1101. 'community_name' => $vy['location'],
  1102. 'square' => '未知',
  1103. 'house_status' => '未知',
  1104. 'employee' => ['name' => $vy['clue_owner_name']],
  1105. 'source' => ['source' => $vy['advertiser_name']],
  1106. 'sign_time' => $vy['create_time_detail'],
  1107. 'state' => $vy['is_allocation'] == 1 ? '已转化' : '未转化',
  1108. 'org_name' => $vy['org_name'],
  1109. ];
  1110. $new_list[$k]['data'] = $tmp_val;
  1111. }
  1112. }
  1113. }
  1114. }
  1115. return json(['code' => 0, 'data' => $new_list, 'msg' => '获取成功']);
  1116. }
  1117. /*
  1118. * 人员树
  1119. */
  1120. public function get_person()
  1121. {
  1122. $root_id = request()->empcrm->root_id;
  1123. //树形
  1124. $where = [
  1125. ['path', 'like', $root_id . '-%'],
  1126. ['status', '=', 1]
  1127. ];
  1128. $allnodes = Org::where($where)->field('id value,id,pid,name')->order('level asc, id asc')->select()->toArray();
  1129. $tree = $this->treeV2($allnodes, 0);
  1130. return json($tree);
  1131. }
  1132. private function treeV2($data, $pid = 0)
  1133. {
  1134. $new_arr = [];
  1135. foreach ($data as $k => $v) {
  1136. if ($v['pid'] == $pid) {
  1137. $children = $this->treeV2($data, $v['id']);
  1138. $v['children'] = $children;
  1139. $new_arr[] = $v;
  1140. }
  1141. }
  1142. return $new_arr;
  1143. }
  1144. /**
  1145. * 获取org ids array
  1146. * @param integer $orgid 目标节点id
  1147. * @return array $orgids 子节点ids数组
  1148. */
  1149. function designer_orgid($orgid)
  1150. {
  1151. $theorg = Org::find($orgid);
  1152. if ($theorg) {
  1153. $orgids = Org::where([['path', 'like', $theorg->path . '%'], ['org_type', '=', 2]])->column('id');
  1154. return $orgids;
  1155. } else {
  1156. return [];
  1157. }
  1158. }
  1159. //资源库管理
  1160. public function resource()
  1161. {
  1162. $request = request();
  1163. $root_id = $request->empcrm->root_id;
  1164. $empid = $request->empcrm->id;
  1165. $org_id = $request->empcrm->org_id;
  1166. $is_manager = $request->empcrm->is_manager;
  1167. if (!$request->isAjax()) {
  1168. //公海
  1169. $pool = PoolLogic::struc();
  1170. View::assign('pool', $pool);
  1171. // 部门
  1172. $org = OrgLogic::struc($root_id);
  1173. View::assign('org', $org);
  1174. $orgids = orgSubIds($root_id);
  1175. View::assign('orgids', json_encode($orgids));
  1176. View::assign('empid', $empid);
  1177. // View::assign('manager', $request->employee->is_manager);
  1178. $data = CustomerSource::field('id,source')->where(['root_id' => $root_id])->select();
  1179. View::assign('source', $data);
  1180. return View::fetch();
  1181. }
  1182. $param = $request->only(['page', 'limit', 'org_pool', 'state' => '', 'source' => '', 'person' => '', 'start_date' => '', 'end_date' => '']);
  1183. if (isset($param['org_pool']) && $param['org_pool']) {
  1184. $org = $param['org_pool'];
  1185. } else {
  1186. $org = $root_id;
  1187. }
  1188. // $where[] = ['id','>',0];
  1189. $where[] = ['org_id', '=', $org_id];
  1190. // $where1[] = ['employee_id','=',$empid];
  1191. // $where1[] = ['upload_source','=',1];
  1192. // $whereOr[] = ['org_id', '=', $org_id];
  1193. // $whereOr[] = ['employee_id', 'NULL',null];
  1194. //分配状态
  1195. if ($param['state'] !== '') $where[] = ['state', '=', $param['state']];
  1196. //来源渠道
  1197. if ($param['source'] !== '') $where[] = ['source', '=', $param['source']];
  1198. // 导入人员
  1199. if ($param['person'] !== '') $where[] = ['employee_id', '=', $param['person']];
  1200. //开始时间
  1201. if ($param['start_date'] !== '') $where[] = ['addtime', '>=', $param['start_date']];
  1202. //结束时间
  1203. if ($param['end_date'] !== '') $where[] = ['addtime', '<=', $param['end_date'] . ' 23:59:59'];
  1204. //$data = CrmImportLog::where($where)->whereOr($whereOr)->with(['employee', 'org', 'optname'])->page($param['page'])->limit($param['limit'])->order('addtime', 'desc')->select();
  1205. $data = CrmImportLog::where($where)
  1206. // ->where(
  1207. // function($query) use ($whereOr,$where1){
  1208. // $query->whereOr([$whereOr,$where1]);
  1209. // }
  1210. // )
  1211. ->with(['employee', 'org', 'optname'])->page($param['page'])->limit($param['limit'])->order('addtime', 'desc')->select();
  1212. //获取所有资源id
  1213. $listids = CrmImportLog::where('id', '>', 0)->column('pid,id');
  1214. foreach ($data as &$item) {
  1215. if ($item->pid == 0) {
  1216. $from = '数据导入';
  1217. } else {
  1218. $cil = CrmImportLog::with('org')->find($item->pid);
  1219. $from = $cil->org_info . ' 资源库';
  1220. }
  1221. $item['from'] = $from;
  1222. $item['belong'] = $item->org_info;
  1223. if (empty($item['pid'])) $item['employee_name'] = $item['employee_opt_name'] ?: $item['employee_name'];
  1224. if ($item['pid']) {
  1225. $pidarr = $this->getInfo($item['id'], $listids, 0);
  1226. $ppid = !empty($pidarr[count($pidarr) - 1]['id']) ? $pidarr[count($pidarr) - 1]['id'] : 0;
  1227. $pid_data = CrmImportLog::with(['employee', 'optname'])->where('id', '=', $ppid)->find();
  1228. $item['employee_name'] = !empty($pid_data['employee_name']) ? $pid_data['employee_name'] : $pid_data['employee_opt_name'];
  1229. }
  1230. $item['source_name'] = '';
  1231. if ($item['source']) {
  1232. $source_name = CustomerSource::where('id', intval($item['source']))->value('source');
  1233. if ($source_name) {
  1234. $item['source_name'] = $source_name;
  1235. } else {
  1236. $item['source_name'] = '其他';
  1237. }
  1238. }
  1239. $where1[] = ['employee_id', '=', NULL];
  1240. $where1[] = ['crm_res_id', '=', $item['id']];
  1241. $ispid = !empty($item['pid']) ? 1 : 0;
  1242. $where1[] = ['is_distribution', '=', $ispid];
  1243. $where1[] = ['state', 'not in', Customer::changeState('无效', 'chaos')];
  1244. $left_num = Customer::where($where1)->count();
  1245. unset($where1);
  1246. $item['left_num'] = $left_num;
  1247. if ($item['pid']) $item['y_count'] = $item['count'] - $item['left_num'];
  1248. if (empty($item['pid'])) $item['y_count'] = $item['avaliable_count'] - $item['left_num'];
  1249. $item['state_name'] = $item['state'] == 0 ? '未分配' : '已分配';
  1250. }
  1251. $count = CrmImportLog::where($where)
  1252. // ->where(
  1253. // function($query) use ($whereOr,$where1){
  1254. // $query->whereOr([$whereOr,$where1]);
  1255. // }
  1256. // )
  1257. ->count();
  1258. //查询资源库分组是否是最高层
  1259. $org_pid = Org::where('id', $org)->value('pid');
  1260. return json(['code' => 0, 'data' => $data, 'count' => $count, 'org' => $org_pid]);
  1261. }
  1262. //添加导入资源
  1263. public function importing()
  1264. {
  1265. $data = CustomerSource::field('id,source')->where(['root_id' => request()->empcrm->root_id])->select();
  1266. View::assign('source', $data);
  1267. $old_source = CrmImportLog::where('employee_id', request()->empcrm->id)->order('id desc')->value('source');
  1268. View::assign('old_source', $old_source);
  1269. return View::fetch();
  1270. }
  1271. private function checkphone($value)
  1272. {
  1273. if (preg_match("/^1[356789]\d{9}$/", $value)) {
  1274. return true;
  1275. } else {
  1276. return false;
  1277. }
  1278. }
  1279. /**
  1280. * 导入前日志存储
  1281. */
  1282. public function importLog()
  1283. {
  1284. $request = request();
  1285. $param = $request->only(['file_name', 'source', 'file']);
  1286. $empid = $request->empcrm->id;
  1287. $org_id = $request->empcrm->org_id;
  1288. $root_id = $request->empcrm->root_id;
  1289. $logData = [
  1290. 'name' => $param['file_name'],
  1291. 'employee_id' => $empid,
  1292. 'org_id' => $org_id,
  1293. 'count' => 0,
  1294. 'avaliable_count' => 0,
  1295. 'bad_phone_num' => 0,
  1296. 'left_num' => 0,
  1297. 'price' => '',
  1298. 'source' => $param['source'],
  1299. 'repeat_phone_number' => 0,
  1300. 'path'=> $param['file'],
  1301. 'root_id'=> $root_id,
  1302. 'upload_source' => 1
  1303. ];
  1304. $data = CrmImportLog::create($logData);
  1305. if ($data == false) {
  1306. return json(['code' => 1, 'msg' => '添加失败']);
  1307. }
  1308. $data->status = 1;
  1309. $data->save();
  1310. $jobHandlerClassName = 'app\jobs\CrmImport';
  1311. $jobQueueName = 'crm_import';
  1312. $orderData = ['id'=> $data->id]; //这个是需要传到消费者的数据
  1313. Queue::later(0, $jobHandlerClassName, $orderData, $jobQueueName);
  1314. return json(['code' => 0, 'msg' => '正在导入中,请刷新列表查看']);
  1315. }
  1316. /**
  1317. * 获取导入失败的客户
  1318. */
  1319. public function get_error_customers(){
  1320. $param = request()->only(['page' => 1, 'limit' => 10, 'keyword' => '', 'id' => 0]);
  1321. $list = CrmImportRecord::where([['log_id', '=', $param['id']], ['content', 'not null', null]])->order('id asc')->column('content');
  1322. $new_list = [];
  1323. foreach($list as $k => $v){
  1324. if (!empty($v)) {
  1325. $one = json_decode($v);
  1326. $new_list = array_merge($new_list, $one);
  1327. }
  1328. }
  1329. $count = count($new_list);
  1330. $data = array_slice($new_list, ($param['page'] - 1) * $param['limit'], $param['limit']);
  1331. return json(['code' => 0, 'data' => $data, 'count' => $count]);
  1332. }
  1333. /**
  1334. * 客户excel添加
  1335. */
  1336. public function add()
  1337. {
  1338. $request = request();
  1339. $orgIds = orgSubIds($request->empcrm->root_id);
  1340. $logId = $request->param('log_id');
  1341. $sourceId = $request->param('source_id');
  1342. $log = CrmImportLog::where('id', $logId)->find();
  1343. if (empty($log) || !in_array($log->org_id, $orgIds)) return json(['code' => 1, 'msg' => '请求错误,记录不存在']);
  1344. $orgIds = orgSubIds($request->empcrm->root_id);
  1345. $datas = $request->param('customers');
  1346. if (count($datas) == 0) return json(['code' => 1, 'msg' => '请求错误,未传输数据']);
  1347. //客户来源扩展字段
  1348. $ext_where = [
  1349. ['root_id', '=', $request->empcrm->root_id],
  1350. ['keyname', '=', 'source_id']
  1351. ];
  1352. $ext = [];
  1353. $source_field_id = CustomerPortraitField::where($ext_where)->value('id');
  1354. if ($source_field_id) $ext[] = ['id' => (string)$source_field_id, 'keyname' => 'source_id', 'value' => $sourceId];
  1355. $unit_number_id = CustomerPortraitField::where([['root_id', '=', $request->empcrm->root_id], ['keyname', '=', 'unit_number']])->find();
  1356. $house_location = CustomerPortraitField::where([['root_id', '=', $request->empcrm->root_id], ['keyname', '=', 'house_location']])->find();
  1357. //error 手机号错误数量 repeat 手机号重复数量
  1358. $rs = ['ok' => 0, 'error' => 0, 'repeat' => 0];
  1359. $phones = [];
  1360. $aec = new Aec(config('app.aec_key'), config('app.aec_iv'));
  1361. foreach ($datas as $k => &$data) {
  1362. $data['phone1'] = $data['phone2'] = '';
  1363. ////2023-02-15 修改手机号可以输入多个
  1364. $s = true;
  1365. $ls_phone = explode('、', $data['phone']);
  1366. if (!empty($ls_phone) && is_array($ls_phone)) {
  1367. $p = 0;
  1368. foreach ($ls_phone as $k2 => $v2) {
  1369. if ($this->checkphone($v2)) {
  1370. $field = $p ? 'phone' . $p : 'phone';
  1371. $data[$field] = $aec->encrypt($v2);
  1372. $p += 1;
  1373. }
  1374. if ($p > 2) break; //只取三个有效手机号
  1375. }
  1376. if ($p > 0) $s = false;
  1377. }
  1378. if ($s) {
  1379. unset($datas[$k]);
  1380. $rs['error']++;
  1381. continue;
  1382. }
  1383. // 数据处理
  1384. $data['house_type'] = mb_strlen($data['house_type']) > 20 ? mb_substr($data['house_type'], 0, 20) : trim($data['house_type']);
  1385. $data['age_range'] = mb_strlen($data['age_range']) > 5 ? mb_substr($data['age_range'], 0, 5) : trim($data['age_range']);
  1386. $data['name'] = mb_strlen($data['name']) > 20 ? mb_substr($data['name'], 0, 20) : trim($data['name']);
  1387. $data['crm_res_id'] = $log->id;
  1388. $data['state'] = 0;
  1389. $data['sex'] = ($data['sex'] == '男') ? 1 : 2;
  1390. $data['org_id'] = $request->empcrm->org_id;
  1391. $data['is_resource'] = 1;
  1392. $data['bad_phone'] = 0;
  1393. $data['source_id'] = $sourceId;
  1394. $ext1 = $ext;
  1395. if ($data['unit_number'] && !$unit_number_id->isEmpty()) $ext1[] = ['id' => (string)$unit_number_id->id, 'keyname' => 'unit_number', 'value' => $data['unit_number']];
  1396. if ($data['house_location'] && !$house_location->isEmpty()) $ext1[] = ['id' => (string)$house_location->id, 'keyname' => 'house_location', 'value' => $data['house_location']];
  1397. $data['ext'] = $ext1 ? json_encode($ext1) : NULL;
  1398. unset($data['unit_number']);
  1399. unset($data['house_location']);
  1400. $data['level'] = in_array($data['level'], ['A', 'B', 'C', 'D']) ? trim($data['level']) : null;
  1401. $rs['ok']++;
  1402. }
  1403. Db::startTrans();
  1404. try {
  1405. Customer::insertAll($datas);
  1406. $log->bad_phone_num -= $rs['ok'];
  1407. $log->avaliable_count += $rs['ok'];
  1408. $log->left_num += $rs['ok'];
  1409. $log->save();
  1410. Db::commit();
  1411. } catch (\Exception $e) {
  1412. trace($e->getMessage(), 'error');
  1413. // 回滚事务
  1414. Db::rollback();
  1415. return json(['code' => 1, 'msg' => $e->getMessage()]);
  1416. }
  1417. return json(['code' => 0, 'msg' => '保存成功', 'data' => $rs]);
  1418. }
  1419. /**
  1420. * 获取公司人员
  1421. * 分配弹框页面接口
  1422. */
  1423. public function get_persons()
  1424. {
  1425. $request = request();
  1426. $root_id = $request->empcrm->root_id;
  1427. $org_id = $request->empcrm->org_id;
  1428. $param = $request->only(['page' => 1, 'limit' => 10000, 'keyword' => '', 'type' => 1, 'ids' => '']);
  1429. $orgids = orgSubIds($org_id);
  1430. $where = [
  1431. ['root_id', '=', $root_id],
  1432. ['org_id', 'in', $orgids],
  1433. ['uid', '>', 0],
  1434. ['state', '=', '在职']
  1435. ];
  1436. if ($param['type'] == 1 && $param['keyword']) {
  1437. $benorg = Org::where('id', $org_id)->value('path');
  1438. $org_ids = Org::where([['path', 'like', $benorg . '%'], ['id', '<>', $org_id], ['name', 'like', '%' . $param['keyword'] . '%']])->column('id');
  1439. $where[] = ['org_id', 'in', $org_ids];
  1440. } elseif ($param['type'] == 2 && $param['keyword']) {
  1441. $where[] = ['name', 'like', '%' . $param['keyword'] . '%'];
  1442. }
  1443. $list = Employee::with(['org' => function ($query) {
  1444. $query->field(['id', 'name'])->bind(['org_name' => 'name']);
  1445. }])->where($where)->field('id,org_id,name')->page($param['page'], $param['limit'])->order('id asc')->select();
  1446. $count = Employee::where($where)->count();
  1447. if ($param['ids']) {
  1448. $arr = explode(',', $param['ids']);
  1449. foreach ($list as $k => $v) {
  1450. $list[$k]['checked'] = in_array($v['id'], $arr);
  1451. }
  1452. } else {
  1453. foreach ($list as $k => $v) {
  1454. $list[$k]['checked'] = false;
  1455. }
  1456. }
  1457. return json(['code' => 0, 'data' => $list, 'count' => $count]);
  1458. }
  1459. /**
  1460. * 删除资源
  1461. */
  1462. public function delete_new()
  1463. {
  1464. $id = input('id', 0);
  1465. $root_id = request()->empcrm->root_id;
  1466. $empid = request()->empcrm->id;
  1467. $orgids = orgSubIds($root_id);
  1468. if ($id > 0) {
  1469. $where[] = ['id', '=', $id];
  1470. $where[] = ['org_id', 'in', $orgids];
  1471. $info = CrmImportLog::where($where)->findOrEmpty();
  1472. $listids = CrmImportLog::where([['id', '>', $info['id']], ['org_id', 'in', $orgids]])->column('id,pid');
  1473. $ids = $this->getAllLowerLevelId($listids, $info['id']);
  1474. $info->delete();
  1475. CrmImportLog::where([['id', 'in', $ids]])->useSoftDelete('delete_time', time())->delete();
  1476. //记录操作删除资源库信息
  1477. $msg = '操作回收客户员工id:' . $empid . '要删除资源库的id' . $id;
  1478. trace($msg,'资源删除');
  1479. return json(['code' => 0, 'data' => '删除成功', 'msg' => '删除成功']);
  1480. // if ($info->state == 0) {
  1481. // $info->delete();
  1482. // CrmImportLog::where([['id', 'in', $ids]])->useSoftDelete('delete_time', time())->delete();
  1483. // //CrmImportLog::where($where)->delete();
  1484. // if ($info->count > 0) Customer::where([['crm_res_id', '=', $id]])->useSoftDelete('delete_time', time())->delete();
  1485. // //记录操作删除资源库信息
  1486. // $msg = '操作回收客户员工id:' . $empid . '要删除资源库的id' . $id;
  1487. // Log::write($msg);
  1488. // return json(['code' => 0, 'data' => '删除成功', 'msg' => '删除成功']);
  1489. // } else {
  1490. // $iscus = Customer::where([['crm_res_id', 'in', $ids], ['org_id', 'in', $orgids], ['state', 'in', Customer::changeState('待确认', 'chaos')]])->count();
  1491. // $bencus = Customer::where([['crm_res_id', '=', $info['id']], ['org_id', 'in', $orgids], ['employee_id', 'NOTNULL', null], ['state', 'in', Customer::changeState('待确认', 'chaos')]])->count();
  1492. // if ($iscus && $bencus) return json(['code' => 1, 'msg' => '请先回收未转化为客户的资源']);
  1493. // //删除已经回收的客户
  1494. // //$isdelcus = Customer::where([['crm_res_id','=',$info['id']],['state','in',Customer::changeState('待确认','chaos')]])->delete();
  1495. // $info->delete();
  1496. // CrmImportLog::where([['id', 'in', $ids]])->useSoftDelete('delete_time', time())->delete();
  1497. // return json(['code' => 0, 'data' => '删除成功', 'msg' => '删除成功']);
  1498. // }
  1499. }
  1500. return json(['code' => 1, 'data' => '删除失败', 'msg' => '删除失败']);
  1501. }
  1502. /**
  1503. * 获取部门树
  1504. * 分配弹框页面接口
  1505. */
  1506. public function get_orgs()
  1507. {
  1508. $root_id = request()->empcrm->root_id;
  1509. $keyword = input('keyword', '');
  1510. $pids = input('pid', 0);
  1511. //获取本人部门及子部门
  1512. $org_id = request()->empcrm->org_id;
  1513. $org_data = Org::find($org_id);
  1514. $where = [
  1515. ['path', 'like', $org_data->path . '%'],
  1516. ['status', '=', 1]
  1517. ];
  1518. if ($pids) $where[] = ['id', '<>', $org_id];
  1519. $count = Employee::where([['root_id', '=', $root_id], ['state', 'like', '%在职%'], ['uid', '>', 0]])->group('org_id')->column('count(*) count', 'org_id');
  1520. $allnodes = Org::where($where)->field('id,pid,name title,level,org_type,info,path')->order('level asc, id asc')->select()->toArray();
  1521. foreach ($allnodes as $k => $v) {
  1522. $allnodes[$k]['count'] = isset($count[$v['id']]) ? $count[$v['id']] : 0; //本部门人数
  1523. $allnodes[$k]['all_count'] = 0; //包含子部门总数
  1524. $allnodes[$k]['org_class'] = 'org_' . $v['id'];
  1525. $allnodes[$k]['per_class'] = 'per_org_' . $v['id'];
  1526. $allnodes[$k]['type'] = 'org';
  1527. foreach ($allnodes as $k2 => $v2) {
  1528. if (strpos($v2['path'], $v['path']) !== false) {
  1529. $allnodes[$k]['all_count'] = isset($count[$v2['id']]) ? $count[$v2['id']] + $allnodes[$k]['all_count'] : $allnodes[$k]['all_count'];
  1530. }
  1531. }
  1532. $allnodes[$k]['title'] = $allnodes[$k]['title'] . ' (' . $allnodes[$k]['all_count'] . ')';
  1533. }
  1534. // var_dump($allnodes);
  1535. // exit;
  1536. //$newpid = $pids ? $org_data->id : $org_data->pid;
  1537. $tree = $this->tree($allnodes, $org_data->id);
  1538. return json(['code' => 0, 'data' => $tree, 'checkOrg' => '']);
  1539. }
  1540. public function tree($data, $pid = 0)
  1541. {
  1542. $new_arr = [];
  1543. foreach ($data as $k => $v) {
  1544. if ($v['pid'] == $pid) {
  1545. $children = $this->tree($data, $v['id']);
  1546. $v['children'] = $children;
  1547. if (empty($v['children'])) $v['disabled'] = true;
  1548. $new_arr[] = $v;
  1549. }
  1550. }
  1551. return $new_arr;
  1552. }
  1553. //资源库迭代新增接口
  1554. /**
  1555. *
  1556. */
  1557. public function distribution()
  1558. {
  1559. $root_id = request()->empcrm->root_id;
  1560. $orgids = orgSubIds($root_id);
  1561. $id = input('id', 0); //资源id
  1562. $count = input('count', 0); //可分配资源数量
  1563. $customer_id = input('customer_id', '');
  1564. $data = CrmImportLog::where([['id', '=', $id], ['org_id', 'in', $orgids]])->find();
  1565. $fen = $this->sel_ywassign($id, $orgids, $data);
  1566. if (empty($customer_id)) $count = $fen['left_num'];
  1567. View::assign('id', $id);
  1568. View::assign('pid', $data['pid']);
  1569. View::assign('count', $count);
  1570. View::assign('customer_id', $customer_id);
  1571. return View::fetch();
  1572. }
  1573. /**
  1574. * 获取子部门
  1575. */
  1576. public function get_child_orgs($id)
  1577. {
  1578. $info = Org::where('id', $id)->findOrEmpty();
  1579. $path = $info->path;
  1580. $ids = Org::where([['path', 'like', $path . '%']])->column('id,name');
  1581. return json(['code' => 0, 'data' => array_column($ids, 'id'), 'param' => $ids]);
  1582. }
  1583. /**
  1584. * 分配资源
  1585. * 分配弹框页面接口
  1586. * type=org分配给部门,person分配给员工,
  1587. * resources_id批量分配时资源id ,必传
  1588. * content 被分配部门id/员工id和数量 [{con_id:1,count:2},{con_id:89,count:4}]
  1589. * customer_id 手动分配时选择的客户id
  1590. */
  1591. public function distribution_resources()
  1592. {
  1593. $request = request();
  1594. $root_id = $request->empcrm->root_id;
  1595. $orgids = orgSubIds($root_id);
  1596. $param = $request->only(['type' => 'org', 'resources_id' => 0, 'content' => [], 'customer_id' => '']);
  1597. if (empty($param['content']) || !is_array($param['content'])) return json(['code' => 1, 'data' => '请选择分配对象', 'msg' => '请选择分配对象']);
  1598. $customer = $param['customer_id'] ? explode(',', $param['customer_id']) : Customer::where([['crm_res_id', '=', $param['resources_id']], ['employee_id', '=', null], ['bad_phone', '=', 0], ['is_resource', '=', 1]])->column('id');
  1599. shuffle($customer); //随机分配
  1600. $count = count($customer);
  1601. $all_count = array_sum(array_column($param['content'], 'count'));
  1602. if ($all_count > $count) return json(['code' => 1, 'data' => '分配数量不能大于资源总数', 'msg' => '分配数量不能大于资源总数']);
  1603. // 查询老记录
  1604. $metaLog = CrmImportLog::find($param['resources_id']);
  1605. $repeat = [];
  1606. //指派类型
  1607. if ($param['type'] == 'org') {
  1608. foreach ($param['content'] as $k => $v) {
  1609. $con = array_slice($customer, 0, $v['count']);
  1610. $param['content'][$k]['customer'] = $con;
  1611. $customer = array_diff($customer, $con);
  1612. }
  1613. //指派到部门
  1614. foreach ($param['content'] as $key => $val) {
  1615. if ($val['count'] > 0) {
  1616. $log = CrmImportLog::create([
  1617. 'pid' => $param['resources_id'],
  1618. 'employee_id' => NULL,
  1619. 'org_id' => $val['con_id'],
  1620. 'name' => $metaLog->name,
  1621. 'count' => $val['count'],
  1622. 'state' => 0,
  1623. 'left_num' => $val['count'],
  1624. 'source' => $metaLog->source
  1625. ]);
  1626. $where[] = ['id', 'in', $val['customer']];
  1627. Customer::where($where)->update([
  1628. 'employee_id' => NULL,
  1629. 'org_id' => $val['con_id'],
  1630. 'is_resource' => 1,
  1631. 'crm_res_id' => $log->id,
  1632. 'is_distribution' => 1
  1633. ]);
  1634. unset($where);
  1635. }
  1636. }
  1637. } elseif ($param['type'] == 'person') {
  1638. //分配到人去重
  1639. $eids = array_column($param['content'], 'con_id');
  1640. $phones = Customer::where([['employee_id', 'in', $eids]])->column('employee_id,name,phone,phone1,phone2');
  1641. $phone_emp = []; //待分配的业务员
  1642. foreach ($phones as $k => $v) {
  1643. $phone_emp[$v['employee_id']] = isset($phone_emp[$v['employee_id']]) ? $phone_emp[$v['employee_id']] : [];
  1644. array_push($phone_emp[$v['employee_id']], $v['phone'], $v['phone1'], $v['phone2']);
  1645. }
  1646. foreach ($phone_emp as $k2 => $v2) {
  1647. $phone_emp[$k2] = array_unique(array_filter($v2));
  1648. }
  1649. foreach ($param['content'] as $k3 => $v3) {
  1650. //原有手机号
  1651. $param['content'][$k3]['phones'] = isset($phone_emp[$v3['con_id']]) ? $phone_emp[$v3['con_id']] : [];
  1652. //分配的客户
  1653. $param['content'][$k3]['cids'] = [];
  1654. }
  1655. //分配
  1656. $customer = Customer::where([['id', 'in', $customer], ['employee_id', '=', null]])->column('id,name,phone,phone1,phone2');
  1657. foreach ($customer as $k4 => $v4) {
  1658. $ls_phones = array_filter([$v4['phone'], $v4['phone1'], $v4['phone2']]);
  1659. $i = 0;
  1660. foreach ($param['content'] as $k5 => $v5) {
  1661. //没有分配完成
  1662. if ($v5['count'] > count($v5['cids'])) {
  1663. //并且手机号不重复
  1664. if ($v5['phones'] == []) {
  1665. $param['content'][$k5]['cids'][] = $v4['id'];
  1666. $i = 1;
  1667. break;
  1668. } else {
  1669. $phone_diff = array_intersect($v5['phones'], $ls_phones);
  1670. if ($phone_diff) {
  1671. continue; //手机号重复 分配给下一个客户
  1672. } else {
  1673. $param['content'][$k5]['cids'][] = $v4['id'];
  1674. $i = 1;
  1675. break;
  1676. }
  1677. }
  1678. }
  1679. }
  1680. //无法分配
  1681. if ($i == 0) {
  1682. $repeat[$v4['id']] = $v4['name'];
  1683. }
  1684. }
  1685. //分配
  1686. $visitlog = [];
  1687. $date = date('Y-m-d');
  1688. foreach ($param['content'] as $k6 => $v6) {
  1689. if ($v6['cids']) {
  1690. $emp = Employee::where('id', $v6['con_id'])->findOrEmpty();
  1691. Customer::where([['id', 'in', $v6['cids']]])->update([
  1692. 'employee_id' => $v6['con_id'],
  1693. 'org_id' => $emp->org_id,
  1694. 'is_resource' => 0,
  1695. 'is_distribution' => 1,
  1696. 'employee_time' => date('Y-m-d H:i:s'),
  1697. 'remark' => '',
  1698. 'valid_time' => null,
  1699. 'state' => 0
  1700. ]);
  1701. CustomerVisitLog::where([['customer_id', 'in', $v6['cids']], ['data_type', '=', 'out_call']])->delete();
  1702. OutCallLog::where([['customer_id', 'in', $v6['cids']]])->update(['is_redistribution' => 1]);
  1703. OutCallMbLog::where([['customer_id', 'in', $v6['cids']]])->update(['is_redistribution' => 1]);
  1704. //添加跟进记录
  1705. foreach ($v6['cids'] as $v7) {
  1706. $visitlog[] = [
  1707. 'customer_id' => $v7,
  1708. 'type' => 1,
  1709. 'remark' => '资源库分配',
  1710. 'employee_id' => $v6['con_id'],
  1711. 'user_id' => $emp->uid,
  1712. 'state' => '待确认',
  1713. 'next_contact_date' => $date
  1714. ];
  1715. }
  1716. }
  1717. }
  1718. if ($visitlog) CustomerVisitLog::insertAll($visitlog);
  1719. } else {
  1720. return json(['code' => 1, 'data' => '数据错误', 'msg' => '数据错误']);
  1721. }
  1722. //查询未分配数量
  1723. $left_num = Customer::where([['crm_res_id', '=', $param['resources_id']], ['employee_id', '=', null]])->count();
  1724. CrmImportLog::where('id', $param['resources_id'])->update(['state' => 1, 'left_num' => $left_num]);
  1725. $j = 0;
  1726. if ($param['type'] == 'person') {
  1727. foreach ($param['content'] as $v7) {
  1728. if ($v7['count'] > count($v7['cids'])) $j = 1;
  1729. }
  1730. }
  1731. if ($repeat && $j == 1) {
  1732. $name = implode(',', array_values($repeat));
  1733. return json(['code' => 1, 'data' => '客户:' . $name . '。手机号重复无法分配', 'msg' => '客户:' . $name . '。手机号重复无法分配']);
  1734. } else {
  1735. return json(['code' => 0, 'data' => '分配完成', 'msg' => '分配完成']);
  1736. }
  1737. }
  1738. /**
  1739. * 已分配客户筛选多种状态处理
  1740. */
  1741. public function cus_arrstatus($state, $where)
  1742. {
  1743. $arr_state = explode(',', $state);
  1744. $allids = [];
  1745. $newids = [];
  1746. $cids = Customer::where($where)->column('id');
  1747. foreach ($arr_state as $key => $val) {
  1748. $arr = ['已到店', '已量房', '已到场', '已交定', '已签单'];
  1749. $v_where[] = ['customer_id', 'in', $cids];
  1750. if (in_array($val, $arr)) {
  1751. $v_where[] = ['state', 'in', CustomerVisitLog::changeState($val, 'chaos')];
  1752. $ids = CustomerVisitLog::where($v_where)->group('customer_id')->column('customer_id');
  1753. unset($v_where);
  1754. $allids[] = $ids;
  1755. } elseif ($val == '待确认') {
  1756. //排除有效就是待确认
  1757. $ids = Customer::where($where)->where('state', 'in', Customer::changeState('待确认', 'chaos'))->column('id');
  1758. $allids[] = $ids;
  1759. } elseif ($val == '有效') {
  1760. //2023-02-02修改 有效状态 客户表state字段不为待确认和无效,就是有效
  1761. $state1 = Customer::changeState('待确认', 'chaos');
  1762. $state2 = Customer::changeState('无效', 'chaos');
  1763. $allids[] = Customer::where($where)->where('state', 'not in', array_merge($state1, $state2))->column('id');
  1764. } elseif ($val == '无效') {
  1765. $state = Customer::changeState('无效', 'chaos');
  1766. $allids[] = Customer::where($where)->where('state', 'in', $state)->column('id');
  1767. }
  1768. }
  1769. foreach ($allids as $key => $val) {
  1770. foreach ($val as $k => $v) {
  1771. $newids[] = $v;
  1772. }
  1773. }
  1774. $newids = array_unique($newids);
  1775. return $newids;
  1776. }
  1777. /**
  1778. * 查询所有资源的下级
  1779. */
  1780. function getAllLowerLevelId($list, $p_id = '0', $isFirstTime = true)
  1781. {
  1782. static $arr = [];
  1783. if ($isFirstTime) {
  1784. $arr = [];
  1785. }
  1786. foreach ($list as $key => $val) {
  1787. if ($val['pid'] == $p_id) {
  1788. $arr[] = $val['id'];
  1789. $this->getAllLowerLevelId($list, $val['id'], false);
  1790. }
  1791. }
  1792. return $arr;
  1793. }
  1794. /**
  1795. * 查询所有资源的上级
  1796. */
  1797. function getParentIds($id, $list, $parents = [])
  1798. {
  1799. //改变数组的key值
  1800. $list = array_column($list, NULL, 'id');
  1801. if (!isset($list[$id])) {
  1802. return [];
  1803. }
  1804. $parents[] = $id;
  1805. $info = $list[$id];
  1806. if ($info['pid'] == 0) {
  1807. return $parents;
  1808. }
  1809. return $this->getParentIds($info['pid'], $list, $parents);
  1810. }
  1811. /**
  1812. * 已分配客户列表
  1813. * 分配弹框页面接口
  1814. */
  1815. public function get_customers()
  1816. {
  1817. $request = request();
  1818. $root_id = $request->empcrm->root_id;
  1819. $empid = $request->empcrm->id;
  1820. $param = $request->only(['page' => 1, 'limit' => 10, 'keyword' => '', 'type' => 1, 'id' => 0, 'keyword3' => '', 'state' => '', 'recovery' => 0, 'ids' => '', 'call_state', 'pid' => 0]);
  1821. $orgids = orgSubIds($root_id);
  1822. //分配记录
  1823. //$ids = CrmImportLog::where('pid|id', $param['id'])->column('id');
  1824. $listid = CrmImportLog::where([['id', '>', 0], ['org_id', 'in', $orgids]])->field('id,pid')->select()->toArray();
  1825. $ids = $this->getAllLowerLevelId($listid, $param['id'], $is_first_time = true);
  1826. if (in_array($param['id'], array_column($listid, 'id'))) {
  1827. $ids[] = $param['id'];
  1828. } else {
  1829. return json(['code' => 1, 'msg' => '参数错误']);
  1830. }
  1831. if ($param['pid']) {
  1832. $ids = array_diff($ids, [$param['id']]);
  1833. //查询分配到本部门员工上的客户
  1834. $benids = Customer::where([['crm_res_id', '=', $param['id']], ['org_id', 'in', $orgids]])
  1835. ->where(function ($query) {
  1836. $query->whereOr([['employee_id', 'NOTNULL', NULL], ['state', 'in', Customer::changeState('无效', 'chaos')]]);
  1837. })->column('id');
  1838. }
  1839. //已分配的数量包括,已经分配 和 曾经分配过当前处于无效状态的客户 和 包括分配到部门资源库的
  1840. $customer_id = Customer::where([['crm_res_id', 'in', $ids], ['org_id','in',$orgids],['is_distribution', '=', 1]])->withTrashed()->column('id'); //分配到人
  1841. if(!empty($benids)) $customer_id = array_merge($customer_id,$benids);
  1842. // var_dump($customer_id);
  1843. // exit;
  1844. $where[] = ['id', 'in', $customer_id];
  1845. if ($param['type'] == 1 && $param['keyword']) {
  1846. $org_ids = Org::where([['path', 'like', request()->empcrm->root_id . '-%'], ['name', 'like', '%' . $param['keyword'] . '%']])->column('id');
  1847. $where[] = ['org_id', 'in', $org_ids];
  1848. } elseif ($param['type'] == 2 && $param['keyword']) {
  1849. $emp_ids = Employee::where([['name', 'like', '%' . $param['keyword'] . '%'], ['uid', '>', 0], ['root_id', '=', request()->empcrm->root_id], ['state', '=', '在职']])->column('id');
  1850. // $where[] = ['name', 'like', '%' . $param['keyword'] . '%'];
  1851. $where[] = ['employee_id', 'in', $emp_ids];
  1852. }
  1853. //小区,手机号搜索
  1854. if ($param['keyword3']) {
  1855. $ids = [];
  1856. $keyword = Customer::where($where)->field('id,community_name,phone,phone1,phone2')->select();
  1857. foreach ($keyword as $key => $val) {
  1858. $str = $val['community_name'] . $val['phone'] . $val['phone1'] . $val['phone2'];
  1859. if (strpos($str, $param['keyword3']) !== false) $ids[] = $val['id'];
  1860. }
  1861. $where[] = ['id', 'in', $ids];
  1862. }
  1863. //状态搜索
  1864. if ($param['state']) {
  1865. $state_ids = $this->cus_arrstatus($param['state'], $where);
  1866. unset($where);
  1867. $where[] = ['id', 'in', $state_ids];
  1868. }
  1869. //打电话状态筛选
  1870. if (!empty($param['call_state'])) {
  1871. //电话未联系和未接通
  1872. $call_list = OutCallLog::where([['customer_id', 'in', $customer_id]])->order('addtime desc')->field('id,status,customer_id')->select()->toArray();
  1873. $call_ids = [];
  1874. $call_status = [];
  1875. $no_connect_ids = [];
  1876. $call_all = [];
  1877. foreach ($call_list as $key => $val) {
  1878. if (!in_array($val['customer_id'], $call_ids)) {
  1879. $call_ids[] = $val['customer_id'];
  1880. $call_status[$val['customer_id']] = $val['status'];
  1881. }
  1882. $call_all[$val['customer_id']][] = $val;
  1883. }
  1884. foreach ($call_status as $key => $val) {
  1885. if (in_array($val, [-1, -2])) $no_connect_ids[] = $key;
  1886. }
  1887. $no_call_ids = array_diff($customer_id, $call_ids) ? array_diff($customer_id, $call_ids) : [];
  1888. unset($where);
  1889. if ($param['call_state'] == '已联系') {
  1890. //2023-02-02 已联系包括打电话和remark不为空的客户
  1891. $id1 = array_column($call_list, 'customer_id');
  1892. $id2 = Customer::whereOr([[['id', 'in', $customer_id], ['remark', '<>', '']], [['id', 'in', $id1]]])->column('id');
  1893. $where[] = ['id', 'in', $id2];
  1894. // if (!empty($state_ids) && !empty($call_ids)) {
  1895. // $call_ids = array_intersect($state_ids, $call_ids);
  1896. // }
  1897. // $where[] = ['id', 'in', $call_ids];
  1898. }
  1899. if ($param['call_state'] == '未联系') {
  1900. //2023-02-02 未打电话并且remark为空
  1901. $id1 = array_column($call_list, 'customer_id');
  1902. $id2 = Customer::whereOr([[['id', 'in', $customer_id], ['remark', '<>', '']], [['id', 'in', $id1]]])->column('id');
  1903. $where[] = ['id', 'not in', $id2];
  1904. // if (!empty($state_ids) && !empty($no_call_ids)) {
  1905. // $no_call_ids = array_intersect($state_ids, $no_call_ids);
  1906. // }
  1907. $where[] = ['id', 'in', $no_call_ids];
  1908. }
  1909. if ($param['call_state'] == '未接通') {
  1910. if (!empty($state_ids) && !empty($no_connect_ids)) {
  1911. $no_connect_ids = array_intersect($state_ids, $no_connect_ids);
  1912. }
  1913. $where[] = ['id', 'in', $no_connect_ids];
  1914. }
  1915. }
  1916. //回收客户
  1917. if ($param['recovery'] == 1) {
  1918. //记录操作回收信息
  1919. $msg = '操作回收客户员工id:'.$empid.'回收到资源库的id'.$param['id'].'要回收的客户id'.$param['ids'];
  1920. //Log::write($msg);
  1921. if (empty($param['ids'])) return json(['code' => 1, 'data' => '请选择要回收的客户', 'msg' => '请选择要回收的客户']);
  1922. unset($where);
  1923. $where[] = ['id', 'in', explode(',', $param['ids'])];
  1924. $where[] = ['org_id', 'in', $orgids];
  1925. //$list = Customer::where($where)->field('id,name,employee_id,org_id,designer_id,crm_res_id,state')->select()->toArray();
  1926. $list = Customer::where($where)->column('id,name,employee_id,crm_res_id,state');
  1927. if (empty($list)) return json(['code' => 1, 'msg' => '客户不存在']);
  1928. $repeat_name = [];
  1929. foreach ($list as $item_key => $item_val) {
  1930. if (!in_array($item_val['state'], Customer::changeState('待确认', 'chaos'), true)) {
  1931. unset($list[$item_key]);
  1932. $repeat_name[] = $item_val['name'];
  1933. }
  1934. }
  1935. if (empty($list)) {
  1936. if ($repeat_name) {
  1937. $name = implode(',', $repeat_name);
  1938. return json(['code' => 1, 'data' => '客户“' . $name . '”已经标记为有效无法回收', 'msg' => '客户“' . $name . '”已经标记为有效无法回收']);
  1939. } else {
  1940. return json(['code' => 0, 'data' => '回收完成', 'msg' => '回收完成']);
  1941. }
  1942. }
  1943. //---end 2023-01-04--------//已经交定签单不能回收
  1944. $info = CrmImportLog::where([['id', '=', $param['id']], ['org_id', 'in', $orgids]])->find();
  1945. if (empty($info)) return json(['code' => 1, 'msg' => '数据不存在']);
  1946. $listids = CrmImportLog::where([['id', '>', $info['id']], ['org_id', 'in', $orgids]])->column('pid,id');
  1947. foreach ($list as $key => $val) {
  1948. $groups[$val['crm_res_id']][] = $val;
  1949. }
  1950. foreach ($groups as $key => $val) {
  1951. $notemp = 0;
  1952. $ids = [];
  1953. foreach ($val as $k => $v) {
  1954. if (empty($v['employee_id'])) $notemp++;
  1955. $ids[] = $v['id'];
  1956. }
  1957. $newlist[] = ['crm_res_id' => $key, 'num' => count($val), 'notemp' => $notemp, 'ids' => $ids];
  1958. }
  1959. Db::startTrans();
  1960. try {
  1961. foreach ($newlist as $k => $v) {
  1962. $this->recovery_crms($v, $param['id'], $listids);
  1963. }
  1964. Db::commit();
  1965. } catch (\Exception $e) {
  1966. Db::rollback();
  1967. //var_dump($e->getMessage());
  1968. return json(['code' => 1, 'msg' => '回收数据失败.']);
  1969. }
  1970. if ($repeat_name) {
  1971. $name = implode(',', $repeat_name);
  1972. return json(['code' => 1, 'data' => '客户“' . $name . '”已经标记为有效无法回收', 'msg' => '客户“' . $name . '”已经标记为有效无法回收']);
  1973. } else {
  1974. return json(['code' => 0, 'data' => '回收完成', 'msg' => '回收完成']);
  1975. }
  1976. }
  1977. $list = Customer::with(['orgs' => function ($query) {
  1978. $query->field(['info', 'id', 'name'])->bind(['org_name' => 'name']);
  1979. }, 'designer' => function ($query) {
  1980. $query->field(['id', 'name'])->bind(['designer_name' => 'name']);
  1981. }, 'employee' => function ($query) {
  1982. $query->field(['id', 'name'])->bind(['sale_name' => 'name']);
  1983. }])->withCount(['outcall'])->where($where)->page($param['page'], $param['limit'])->withTrashed()->field('id,employee_id,name,community_name,org_id,designer_id,crm_res_id,state,employee_time')->order('employee_id asc,id asc')->select();
  1984. $allids = Customer::where($where)->withTrashed()->column('id');
  1985. $count = count($allids);
  1986. $allids = !empty($allids) ? implode(',', $allids) : '';
  1987. //分配时间
  1988. $times_arr = CrmImportLog::where([['id', 'in', array_column($list->toArray(), 'crm_res_id')]])->column('addtime', 'id');
  1989. foreach ($list as $key => $val) {
  1990. $list[$key]['allocate_time'] = $times_arr[$val['crm_res_id']];
  1991. }
  1992. // 状态统计获取
  1993. $customersStateList = CustomerVisitLog::where([['customer_id', 'in', array_column($list->toArray(), 'id')]])->group('state,customer_id')->field('count(state) as num, state, customer_id')->select()->toArray();
  1994. $customersState = [];
  1995. foreach ($customersStateList as $s) {
  1996. if (!isset($customersState[$s['customer_id']]))
  1997. $customersState[$s['customer_id']] = ['count' => 0, 'shop' => 0, 'measure' => 0, 'activity' => 0, 'deposit' => 0, 'signed' => 0, 'ydf' => 0, 'wdf' => 0];
  1998. $customersState[$s['customer_id']]['count'] += $s['num'];
  1999. // 到店,量房,活动,定金,签单
  2000. if ($s['state'] == '已到店') $customersState[$s['customer_id']]['shop'] += $s['num'];
  2001. elseif ($s['state'] == '已量房') $customersState[$s['customer_id']]['measure'] += $s['num'];
  2002. elseif ($s['state'] == '已到场') $customersState[$s['customer_id']]['activity'] += $s['num'];
  2003. elseif ($s['state'] == '已交定') $customersState[$s['customer_id']]['deposit'] += $s['num'];
  2004. elseif ($s['state'] == '已签单') $customersState[$s['customer_id']]['signed'] += $s['num'];
  2005. elseif ($s['state'] == '已到访') $customersState[$s['customer_id']]['ydf'] += $s['num'];
  2006. elseif ($s['state'] == '未到访') $customersState[$s['customer_id']]['wdf'] += $s['num'];
  2007. }
  2008. $list = $list->toArray();
  2009. $state1 = Customer::changeState('待确认', 'chaos');
  2010. $state2 = Customer::changeState('无效', 'chaos');
  2011. foreach ($list as $key => &$value) {
  2012. $value['stateNum'] = $customersState[$value['id']] ?? ['count' => 0, 'shop' => 0, 'measure' => 0, 'activity' => 0, 'deposit' => 0, 'signed' => 0, 'ydf' => 0, 'wdf' => 0];
  2013. //2023-02-02 修改逻辑 分配后为待确认状态,不为待确认和无效就是有效状态
  2014. $value['state'] = in_array($value['state'], $state1, true) ? '待确认' : (in_array($value['state'], $state2) ? '无效' : '有效');
  2015. }
  2016. return json(['code' => 0, 'data' => $list, 'count' => $count, 'allids' => $allids]);
  2017. }
  2018. /**
  2019. * 循环调用回收客户
  2020. */
  2021. public function recovery_crm($crm, $crm_res_id, $listids)
  2022. {
  2023. $crm_log = CrmImportLog::where('id', $crm['crm_res_id'])->find();
  2024. if ($crm_res_id != $crm_log['id']) {
  2025. $upids = $this->getInfo($crm_log['id'], $listids, $crm_res_id);
  2026. foreach ($upids as $k => $v) {
  2027. $res_data = CrmImportLog::find($v['id']);
  2028. $count = $res_data->count - 1;
  2029. $left_num = $res_data->left_num - 1;
  2030. $res_data->count = $count ? $count : 0;
  2031. if ($crm_log->id == $res_data->id && empty($crm['employee_id'])) $res_data->left_num = $left_num ? $left_num : 0;
  2032. $res_data->save();
  2033. }
  2034. }
  2035. $ben_log = CrmImportLog::where('id', $crm_res_id)->find();
  2036. $ben_left_num = $ben_log->left_num + 1;
  2037. $ben_log->left_num = $ben_left_num ?: 0;
  2038. $ben_log->save();
  2039. $is_distribution = $ben_log->pid ? 1 : 0;
  2040. Customer::where([['id', '=', $crm['id']]])->update(['crm_res_id' => $ben_log->id, 'org_id' => $ben_log->org_id, 'employee_id' => null, 'employee_time' => null, 'is_resource' => 1, 'fresh' => 1, 'is_distribution' => $is_distribution, 'state' => 0]);
  2041. }
  2042. /**
  2043. * 优化回收方法
  2044. */
  2045. public function recovery_crms($crm, $crm_res_id, $listids)
  2046. {
  2047. $crm_log = CrmImportLog::where('id', $crm['crm_res_id'])->find();
  2048. if ($crm_res_id != $crm_log['id']) {
  2049. $upids = $this->getInfo($crm_log['id'], $listids, $crm_res_id);
  2050. foreach ($upids as $k => $v) {
  2051. $res_data = CrmImportLog::find($v['id']);
  2052. $count = $res_data->count - $crm['num'];
  2053. $left_num = $res_data->left_num - $crm['notemp'];
  2054. $res_data->count = $count ? $count : 0;
  2055. if ($crm_log->id == $res_data->id && !empty($crm['notemp'])) $res_data->left_num = $left_num ? $left_num : 0;
  2056. $res_data->save();
  2057. }
  2058. }
  2059. $ben_log = CrmImportLog::where('id', $crm_res_id)->find();
  2060. $ben_left_num = $ben_log->left_num + $crm['num'];
  2061. $ben_log->left_num = $ben_left_num ?: 0;
  2062. $ben_log->save();
  2063. $is_distribution = $ben_log->pid ? 1 : 0;
  2064. Customer::where([['id', 'in', $crm['ids']]])->update(['crm_res_id' => $ben_log->id, 'org_id' => $ben_log->org_id, 'employee_id' => null, 'employee_time' => null, 'is_resource' => 1, 'fresh' => 1, 'is_distribution' => $is_distribution, 'state' => 0]);
  2065. }
  2066. /**
  2067. * 新详情页
  2068. * 详情页
  2069. */
  2070. public function read_new()
  2071. {
  2072. $request = request();
  2073. $id = input('id', 0);
  2074. $type = input('type', 0); //handdistribution
  2075. //基本信息
  2076. $data = $this->read($id);
  2077. View::assign('data', $data);
  2078. $counts = $this->get_customer_data($id);
  2079. View::assign('counts', $counts);
  2080. View::assign('id', $id);
  2081. $org = Org::where([['path', 'like', request()->empcrm->root_id . '-%']])->field('id,name')->select()->toArray();
  2082. View::assign('org', $org);
  2083. View::assign('type', $type);
  2084. $root_id = $request->empcrm->root_id;
  2085. View::assign('root_id', $root_id);
  2086. return View::fetch();
  2087. }
  2088. /**
  2089. * 详情页获取基本信息
  2090. * 详情页
  2091. */
  2092. public function read()
  2093. {
  2094. $request = request();
  2095. $root_id = $request->empcrm->root_id;
  2096. $allOrg = Org::where([['path', 'like', $root_id . '-%']])->column('id');
  2097. $param = $request->only(['id' => 0, 'empname' => null]);
  2098. $data = CrmImportLog::with(['employee', 'source' => function ($query) {
  2099. $query->field('id,source')->bind(['source_name' => 'source']);
  2100. }])->where([['org_id', 'in', $allOrg], ['id', '=', $param['id']]])->findOrEmpty();
  2101. //if($data->isEmpty()) echo json_encode(['code' => 1, 'msg' =>'数据不存在']); exit;
  2102. $fen = $this->sel_ywassign($param['id'],$allOrg,$data);
  2103. // if(empty($data->pid)) $data->y_count = (int)$data->avaliable_count - (int)$data->left_num;
  2104. // if(!empty($data->pid)){
  2105. // $data->y_count = (int)$data->count - (int)$data->left_num;
  2106. // $data->employee_name = $param['empname'];
  2107. // }
  2108. $data->new_left_num = $fen['left_num'];
  2109. if (empty($data->pid)) $data->y_count = $fen['y_count'];
  2110. if (!empty($data->pid)) {
  2111. $data->y_count = $fen['y_count'];
  2112. $data->employee_name = $param['empname'];
  2113. }
  2114. if ($data->left_num != $fen['left_num']) {
  2115. $data->left_num = $fen['left_num'];
  2116. $data->save();
  2117. }
  2118. return $data;
  2119. }
  2120. /**
  2121. * 查询已分配未分配
  2122. */
  2123. public function sel_ywassign($id, $allOrg, $data)
  2124. {
  2125. $request = request();
  2126. $root_id = $request->empcrm->root_id;
  2127. $orgids = orgSubIds($root_id);
  2128. $where[] = ['employee_id', '=', NULL];
  2129. $where[] = ['crm_res_id', '=', $id];
  2130. $ispid = !empty($data['pid']) ? 1 : 0;
  2131. $where[] = ['is_distribution', '=', $ispid];
  2132. $where[] = ['org_id', 'in', $allOrg];
  2133. $where[] = ['state', 'not in', Customer::changeState('无效', 'chaos')];
  2134. $left_num = Customer::where($where)->count();
  2135. $listid = CrmImportLog::where([['id', '>', 0], ['org_id', 'in', $orgids]])->field('id,pid')->select()->toArray();
  2136. $ids = $this->getAllLowerLevelId($listid, $id, $is_first_time = true);
  2137. if (in_array($id, array_column($listid, 'id'))) {
  2138. $ids[] = $id;
  2139. } else {
  2140. return json(['code' => 1, 'msg' => '参数错误']);
  2141. }
  2142. if ($data['pid']) {
  2143. $ids = array_diff($ids, [$id]);
  2144. //查询分配到本部门员工上的客户
  2145. $benids = Customer::where([['crm_res_id', '=', $id], ['org_id', 'in', $orgids]])
  2146. ->where(function ($query) {
  2147. $query->whereOr([['employee_id', 'NOTNULL', NULL], ['state', 'in', Customer::changeState('无效', 'chaos')]]);
  2148. })->column('id');
  2149. }
  2150. //已分配的数量包括,已经分配 和 曾经分配过当前处于无效状态的客户 和 包括分配到部门资源库的
  2151. $customer_id = Customer::where([['crm_res_id', 'in', $ids], ['org_id', 'in', $orgids], ['is_distribution', '=', 1]])->withTrashed()->column('id'); //分配到人
  2152. if (!empty($benids)) $customer_id = array_merge($customer_id, $benids);
  2153. $data = ['left_num' => $left_num, 'y_count' => count($customer_id)];
  2154. return $data;
  2155. }
  2156. /**
  2157. * 已分配页面获取客户跟进数据
  2158. * 详情页
  2159. */
  2160. public function get_customer_data()
  2161. {
  2162. $request = request();
  2163. $root_id = $request->empcrm->root_id;
  2164. $allOrg = Org::where([['path', 'like', $root_id . '-%']])->column('id');
  2165. $param = $request->only(['id' => 0]);
  2166. //分配记录
  2167. $ids = CrmImportLog::where([['pid|id', '=', $param['id']], ['org_id', 'in', $allOrg]])->column('id');
  2168. //已分配的数量包括,已经分配 和 曾经分配过当前处于无效状态的客户
  2169. $customer_id1 = Customer::where([['crm_res_id', 'in', $ids], ['employee_id', '>', 0], ['is_distribution', '=', 1]])->column('id');
  2170. $customer_id2 = Customer::where([['crm_res_id', 'in', $ids], ['employee_id', '=', null], ['is_distribution', '=', 1]])->column('id');
  2171. $customer_id3 = CustomerVisitLog::where([['customer_id', 'in', $customer_id2]])->group('customer_id')->column('customer_id');
  2172. $customer_id = array_merge($customer_id1, $customer_id3);
  2173. //有效状态 未到访,已到访,确定到场,已量房,交定,签单
  2174. // $state1 = CustomerVisitLog::changeState('待确认', 'chaos');
  2175. $state2 = CustomerVisitLog::changeState('未到访', 'chaos');
  2176. $state3 = CustomerVisitLog::changeState('已到访', 'chaos');
  2177. $state4 = CustomerVisitLog::changeState('已到场', 'chaos');
  2178. $state5 = CustomerVisitLog::changeState('已量房', 'chaos');
  2179. $state6 = CustomerVisitLog::changeState('已交定', 'chaos');
  2180. $state7 = CustomerVisitLog::changeState('已签单', 'chaos');
  2181. $state = array_merge($state2, $state3, $state4, $state5, $state6, $state7);
  2182. //有效客户 排除待回访,和无效
  2183. //2023-02-02 逻辑修改 新分配的客户为待确认状态,确认标记有效后到我的客户,状态为有效
  2184. $query1 = ['id', 'in', $customer_id];
  2185. $query2 = ['is_distribution', '=', 1];
  2186. $query3 = ['is_distribution', '=', 0];
  2187. $query4 = ['died', '<>', 2]; //排除死单
  2188. $query5 = ['customer_id', 'in', $customer_id];
  2189. $query6 = ['state', 'in', Customer::changeState('待确认', 'chaos')];
  2190. $query7 = ['state', 'not in', Customer::changeState('待确认', 'chaos')];
  2191. $query8 = ['state', 'not in', Customer::changeState('无效', 'chaos')];
  2192. $query9 = ['state', 'in', Customer::changeState('无效', 'chaos')];
  2193. //有效
  2194. $data['valid'] = Customer::where([$query1, $query2, $query7, $query8])->count();
  2195. //无效
  2196. $data['invalid'] = Customer::where([$query1, $query2, $query9])->count();
  2197. //待确认
  2198. $data['confirmed'] = Customer::where([$query1, $query2, $query6])->count();
  2199. //已到店,,曾经已到店
  2200. $data['arrived_at_the_store'] = CustomerVisitLog::where([
  2201. $query5,
  2202. ['state', 'in', CustomerVisitLog::changeState('已到店', 'chaos')]
  2203. ])->group('customer_id')->count();
  2204. //已量房
  2205. $data['measured_room'] = CustomerVisitLog::where([
  2206. $query5,
  2207. ['state', 'in', CustomerVisitLog::changeState('已量房', 'chaos')]
  2208. ])->group('customer_id')->count();
  2209. //已到场
  2210. $data['already_present'] = CustomerVisitLog::where([
  2211. $query5,
  2212. ['state', 'in', CustomerVisitLog::changeState('已到场', 'chaos')]
  2213. ])->group('customer_id')->count();
  2214. //已交定
  2215. $data['settled'] = CustomerVisitLog::where([
  2216. $query5,
  2217. ['state', 'in', CustomerVisitLog::changeState('已交定', 'chaos')]
  2218. ])->group('customer_id')->count();
  2219. //已签单
  2220. $data['sign_the_bill'] = CustomerVisitLog::where([
  2221. $query5,
  2222. ['state', 'in', CustomerVisitLog::changeState('已签单', 'chaos')]
  2223. ])->group('customer_id')->count();
  2224. //2023-02-02 已联系包括’分配资源‘中的客户已经调用外呼或者标记时remark有值的客户
  2225. $visit1 = OutCallLog::where([$query5])->group('customer_id')->column('customer_id');
  2226. $data['visit'] = Customer::whereOr([[$query1, ['remark', '<>', '']], [['id', 'in', $visit1]]])->count();
  2227. //未联系
  2228. $data['unvisit'] = count($customer_id) - $data['visit'];
  2229. //电话未联系和未接通
  2230. $call_list = OutCallLog::where([['customer_id', 'in', $customer_id]])->order('addtime desc')->field('id,status,customer_id')->select()->toArray();
  2231. $call_ids = [];
  2232. $call_status = [];
  2233. $no_connect = 0;
  2234. foreach ($call_list as $key => $val) {
  2235. if (!in_array($val['customer_id'], $call_ids)) {
  2236. $call_ids[] = $val['customer_id'];
  2237. $call_status[$val['customer_id']] = $val['status'];
  2238. }
  2239. }
  2240. foreach ($call_status as $key => $val) {
  2241. if (in_array($val, [-1, -2])) $no_connect++;
  2242. }
  2243. $yfp = Customer::where([['crm_res_id', 'in', $ids], ['is_distribution', '=', 1]])->count();
  2244. $data['no_connect'] = $no_connect;
  2245. $data['no_call'] = $yfp - count($call_ids);
  2246. return $data;
  2247. }
  2248. /**
  2249. * 未分配分配客户列表
  2250. * 分配弹框页面接口
  2251. */
  2252. public function get_uncustomers()
  2253. {
  2254. $request = request();
  2255. $root_id = $request->empcrm->root_id;
  2256. $allOrg = Org::where([['path', 'like', $root_id . '-%']])->column('id');
  2257. $param = $request->only(['page' => 1, 'limit' => 10, 'keyword' => '', 'org_id' => 0, 'id' => 0, 'pid' => 0]);
  2258. $where[] = ['employee_id', '=', NULL];
  2259. $where[] = ['crm_res_id', '=', $param['id']];
  2260. $ispid = !empty($param['pid']) ? 1 : 0;
  2261. $where[] = ['is_distribution', '=', $ispid];
  2262. $where[] = ['org_id', 'in', $allOrg];
  2263. $where[] = ['state', 'not in', Customer::changeState('无效', 'chaos')];
  2264. if ($param['keyword']) {
  2265. $ids = [];
  2266. $keyword = Customer::where($where)->field('id,community_name,phone,phone1,phone2')->select();
  2267. foreach ($keyword as $key => $val) {
  2268. $str = $val['community_name'] . $val['phone'] . $val['phone1'] . $val['phone2'];
  2269. if (strpos($str, $param['keyword']) !== false) $ids[] = $val['id'];
  2270. }
  2271. $where[] = ['id', 'in', $ids];
  2272. }
  2273. // $customer_ids = Customer::where($where)->column('id');
  2274. //排除已经分配后又置为无效的数据
  2275. // $query[] = ['customer_id', 'in', $customer_ids];
  2276. // $customer_ids1 = CustomerVisitLog::where($query)->column('customer_id');
  2277. // $where[] = ['id', 'in', array_diff($customer_ids, $customer_ids1)];
  2278. $list = Customer::where($where)->field('id,name,community_name,square,phone,phone1,phone2')->page($param['page'], $param['limit'])->select();
  2279. foreach ($list as &$item) {
  2280. $item['phone'] = substr_replace($item['phone'], '******', 3, 6);
  2281. $item['phone1'] = $item['phone1'] ? substr_replace($item['phone1'], '******', 3, 6) : '';
  2282. $item['phone2'] = $item['phone2'] ? substr_replace($item['phone2'], '******', 3, 6) : '';
  2283. }
  2284. $count = Customer::where($where)->count();
  2285. return json(['code' => 0, 'data' => $list, 'count' => $count]);
  2286. }
  2287. /**
  2288. * 电话联系次数详情
  2289. */
  2290. public function call_cuslist()
  2291. {
  2292. $request = request();
  2293. $param = $request->only(['customer_id' => 0, 'page' => 1, 'limit' => 10]);
  2294. if (!request()->isAjax()) {
  2295. View::assign('customer_id', $param['customer_id']);
  2296. return View::fetch();
  2297. }
  2298. $root_id = $request->empcrm->root_id;
  2299. $allOrg = Org::where([['path', 'like', $root_id . '-%']])->column('id');
  2300. $info = Customer::where([['id', '=', $param['customer_id']], ['org_id', 'in', $allOrg]])->find();
  2301. if (empty($info)) return json(['code' => 1, 'msg' => '客户不存在']);
  2302. $list = OutCallLog::where([['customer_id', '=', $param['customer_id']], ['root_id', '=', $root_id]])->field('id,fwd_start_time,status')->page($param['page'], $param['limit'])->select()->toArray();
  2303. foreach ($list as $key => $val) {
  2304. $list[$key]['status_name'] = '无';
  2305. if ($val['status'] == 1) $list[$key]['status_name'] = '接通';
  2306. if ($val['status'] == -1) $list[$key]['status_name'] = '未接通';
  2307. if ($val['status'] == -2) $list[$key]['status_name'] = '未接听';
  2308. }
  2309. $count = OutCallLog::where([['customer_id', '=', $param['customer_id']], ['root_id', '=', $root_id]])->count();
  2310. return json(['code' => 0, 'data' => $list, 'msg' => '获取成功', 'count' => $count]);
  2311. }
  2312. function getInfo($id, $all, $pid)
  2313. {
  2314. $result = [];
  2315. if ($id != $pid) { //将id等于0作为递归终点,如果要将无法查找到作为递归终点,也要在下面的循环遍历之后判断
  2316. foreach ($all as $item) {
  2317. if ($item['id'] == $id) {
  2318. $result[] = $item;
  2319. break;
  2320. }
  2321. }
  2322. $parents = $this->getInfo($result[0]['pid'], $all, $pid);
  2323. if (!empty($parents)) {
  2324. $result = array_merge($result, $parents);
  2325. }
  2326. }
  2327. return $result;
  2328. }
  2329. /**
  2330. * 已分配客户列表
  2331. * 分配弹框页面接口
  2332. */
  2333. public function recovery_customers()
  2334. {
  2335. $request = request();
  2336. $param = $request->only(['customer_id' => 0, 'crm_res_id']);
  2337. $root_id = $request->empcrm->root_id;
  2338. $empid = $request->empcrm->id;
  2339. $allOrg = Org::where([['path', 'like', $root_id . '-%']])->column('id');
  2340. $info = Customer::where([['id', '=', $param['customer_id']], ['org_id', 'in', $allOrg]])->findOrEmpty();
  2341. //记录操作回收信息
  2342. $msg = '操作回收客户员工id:'.$empid.'回收到资源库的id'.$param['crm_res_id'].'要回收的客户id'.$param['customer_id'];
  2343. //Log::write($msg);
  2344. if (!$info->isEmpty() && $info->crm_res_id) {
  2345. if (!in_array($info->state, [0, '待确认'], true)) {
  2346. return json(['code' => 1, 'data' => '客户“' . $info->name . '”已标记为有效', 'msg' => '客户“' . $info->name . '”已标记为有效无法回收']);
  2347. }
  2348. Db::startTrans();
  2349. try {
  2350. $crm_log = CrmImportLog::where('id', $info->crm_res_id)->find();
  2351. if ($param['crm_res_id'] != $crm_log['id']) {
  2352. $listids = CrmImportLog::where('id', '>', 0)->column('pid,id');
  2353. $upids = $this->getInfo($crm_log['id'], $listids, $param['crm_res_id']);
  2354. foreach ($upids as $k => $v) {
  2355. $res_data = CrmImportLog::find($v['id']);
  2356. $count = $res_data->count - 1;
  2357. $left_num = $res_data->left_num - 1;
  2358. $res_data->count = $count ? $count : 0;
  2359. if ($info->crm_res_id == $res_data->id && empty($info->employee_id)) $res_data->left_num = $left_num ? $left_num : 0;
  2360. $res_data->save();
  2361. }
  2362. }
  2363. $ben_log = CrmImportLog::where([['id', '=', $param['crm_res_id']], ['org_id', 'in', $allOrg]])->find();
  2364. $ben_left_num = $ben_log->left_num + 1;
  2365. $ben_log->left_num = $ben_left_num ?: 0;
  2366. $ben_log->save();
  2367. $is_distribution = $ben_log->pid ? 1 : 0;
  2368. Customer::where([['id', '=', $param['customer_id']]])->update(['crm_res_id' => $ben_log->id, 'org_id' => $ben_log->org_id, 'employee_id' => null, 'employee_time' => null, 'is_resource' => 1, 'fresh' => 1, 'is_distribution' => $is_distribution, 'state' => 0]);
  2369. Db::commit();
  2370. } catch (\Exception $e) {
  2371. Db::rollback();
  2372. var_dump($e->getMessage());
  2373. return json(['code' => 1, 'msg' => '回收失败.']);
  2374. }
  2375. return json(['code' => 0, 'data' => '回收成功', 'msg' => '回收成功']);
  2376. } else {
  2377. return json(['code' => 0, 'data' => '回收成功', 'msg' => '回收成功']);
  2378. }
  2379. }
  2380. /**
  2381. * 管理层数据统计
  2382. */
  2383. public function manageStatistics()
  2384. {
  2385. $request = request();
  2386. if (!request()->isAjax()) {
  2387. //房屋状态是否开启
  2388. $house_status_where = [
  2389. ['root_id', '=', $request->empcrm->root_id],
  2390. ['keyname', '=', 'house_status'],
  2391. ['status', '=', 0]
  2392. ];
  2393. $house_status_per = CustomerPortraitField::where($house_status_where)->findOrEmpty();
  2394. $field = [];
  2395. if (!$house_status_per->isEmpty()) {
  2396. $field = CustomerPortraitFieldSelect::where('pid', $house_status_per->id)->column('name,id');
  2397. $fields = [];
  2398. foreach ($field as $v) {
  2399. $fields[] = [
  2400. 'field' => 'house_status_' . $v['id'],
  2401. 'title' => $v['name'],
  2402. 'align' => 'center',
  2403. 'width' => 100,
  2404. 'rowspan' => 2
  2405. ];
  2406. }
  2407. $field = $fields;
  2408. }
  2409. View::assign('field', json_encode($field));
  2410. //返回组织列表
  2411. $path = Org::where('id', $request->empcrm->org_id)->value('path');
  2412. $org = Org::where([['path', 'like', $path . '%']])->select()->toArray();
  2413. View::assign('org', $org);
  2414. return View::fetch();
  2415. }
  2416. $param = $request->only(['page' => 1, 'limit' => 10, 'start_date' => '', 'end_date' => '', 'keyword' => '', 'org_id' => '']);
  2417. //日期搜索//2023-02-15页面逻辑修改 传参方式改为 start_date=2023/2/15 - 2023/2/15
  2418. if ($param['start_date']) {
  2419. $count_dates = explode(' - ', $param['start_date']);
  2420. $param['start_date'] = date('Y-m-d 00:00:00', strtotime($count_dates[0]));
  2421. $param['end_date'] = date('Y-m-d 23:59:59', strtotime($count_dates[1]));
  2422. } else {
  2423. $param['start_date'] = $param['end_date'] = '';
  2424. }
  2425. $query_date = ($param['start_date'] && $param['end_date']) ? [['addtime', 'between', [$param['start_date'], $param['end_date']]]] : [];
  2426. $root_id = request()->empcrm->root_id;
  2427. $orgids = orgSubIds($request->empcrm->org_id);
  2428. $where = [
  2429. ['root_id', '=', $root_id],
  2430. ['uid', '>', 0],
  2431. ['state', '=', '在职']
  2432. // ['is_manager', '=', 1]
  2433. ];
  2434. if ($param['start_date'] && $param['end_date']) {
  2435. $sdate = strtotime($param['start_date']);
  2436. $edate = strtotime($param['end_date']);
  2437. } else {
  2438. $edate = time();
  2439. $sdate = 972473642;
  2440. }
  2441. if ($param['keyword']) {
  2442. $where[] = ['name', 'like', '%' . $param['keyword'] . '%'];
  2443. }
  2444. if ($param['org_id']) {
  2445. $where[] = ['org_id', '=', $param['org_id']];
  2446. } else {
  2447. $where[] = ['org_id', 'in', $orgids];
  2448. }
  2449. $employee_date = [$param['start_date'], $param['end_date']];
  2450. $list = Employee::with(['customer' => function ($query) use ($employee_date) {
  2451. //手动报备查addtime,分配查询employee_time
  2452. if ($employee_date[0] && $employee_date[1]) {
  2453. $e_where1 = [
  2454. ['addtime', 'between', [$employee_date[0], $employee_date[1]]],
  2455. ['crm_res_id', 'NULL', null]
  2456. //['crm_res_id','=',0]
  2457. ];
  2458. $e_where2 = [
  2459. ['crm_res_id', '>', 0],
  2460. ['employee_time', 'between', [$employee_date[0], $employee_date[1]]]
  2461. ];
  2462. $query->whereOr([$e_where1, $e_where2])->field('id,employee_id,ext,is_resource,addtime,signed_money,house_type,square,house_status,return_visit,assigned_personnel');
  2463. } else {
  2464. $query->field('id,employee_id,ext,is_resource,addtime,signed_money,house_type,square,house_status,return_visit,assigned_personnel');
  2465. }
  2466. }])->where($where)->field('id,org_id,name')->page($param['page'], $param['limit'])->select()->toArray();
  2467. $org = Org::where([['id', 'in', array_column($list, 'org_id')]])->column('name', 'id');
  2468. // return json(['code' => 0, 'data' => $list, 'msg' => '获取成功']);
  2469. $count = Employee::where($where)->count();
  2470. //客户ID
  2471. $customer_ids = [];
  2472. foreach ($list as $key => $val) {
  2473. $cid = array_column($val['customer'], 'id');
  2474. $customer_ids = array_merge($customer_ids, $cid);
  2475. }
  2476. //最近跟进时间
  2477. $max_addtime = CustomerVisitLog::where([['is_merge', '=', 0], ['customer_id', 'in', $customer_ids]])->group('customer_id')->column('max(addtime) addtime', 'customer_id');
  2478. //查询有效数量 //有效性判断 ,, //有效状态 未到访,已到访,确定到场,已量房,交定,签单
  2479. $state1 = CustomerVisitLog::changeState('未到访', 'chaos');
  2480. $state2 = CustomerVisitLog::changeState('已到访', 'chaos');
  2481. $state3 = CustomerVisitLog::changeState('已量房', 'chaos');
  2482. $state4 = CustomerVisitLog::changeState('已到店', 'chaos');
  2483. $state5 = CustomerVisitLog::changeState('已交定', 'chaos');
  2484. $state6 = CustomerVisitLog::changeState('已签单', 'chaos');
  2485. $state7 = CustomerVisitLog::changeState('已到场', 'chaos');
  2486. $vis_where[] = ['customer_id', 'in', $customer_ids];
  2487. $vis_where[] = ['state', 'in', array_merge($state1, $state2, $state3, $state4, $state5, $state6, $state7)];
  2488. if ($query_date) $vis_where[] = $query_date[0];
  2489. $vislog_list = CustomerVisitLog::where($vis_where)->order('addtime asc')->column('customer_id,state,addtime,next_contact_date');
  2490. $valid_vislog = array_unique(array_column($vislog_list, 'customer_id'));
  2491. $rooms = $store = $dep = $sign = [];
  2492. foreach ($vislog_list as $vislog_list_item) {
  2493. if (in_array($vislog_list_item['state'], $state3)) {
  2494. $rooms[] = $vislog_list_item['customer_id'];
  2495. } elseif (in_array($vislog_list_item['state'], $state4)) {
  2496. @$store[$vislog_list_item['customer_id']][] = $vislog_list_item['addtime'];
  2497. } elseif (in_array($vislog_list_item['state'], $state5)) {
  2498. @$dep[$vislog_list_item['customer_id']][] = $vislog_list_item['addtime'];
  2499. } elseif (in_array($vislog_list_item['state'], $state6)) {
  2500. $sign[] = $vislog_list_item['customer_id'];
  2501. }
  2502. }
  2503. $rooms = array_unique($rooms); //量房客户
  2504. //到店客户
  2505. $store1 = $store2 = $store3 = [];
  2506. foreach ($store as $store_key => $store_val) {
  2507. if (count($store_val) == 1) {
  2508. $store1[] = $store_key;
  2509. } elseif (count($store_val) == 2) {
  2510. $store2[] = $store_key;
  2511. } else {
  2512. $store3[] = $store_key;
  2513. }
  2514. }
  2515. //交定客户
  2516. $dep1 = $dep2 = $dep3 = [];
  2517. foreach ($dep as $dep_key => $dep_item) {
  2518. if (count($dep_item) == 1) {
  2519. $dep1[] = $dep_key;
  2520. } elseif (count($dep_item) == 2) {
  2521. $dep2[] = $dep_key;
  2522. } else {
  2523. $dep3[] = $dep_key;
  2524. }
  2525. }
  2526. //房屋状态是否开启
  2527. $house_status_where = [
  2528. ['root_id', '=', $root_id],
  2529. ['keyname', '=', 'house_status'],
  2530. ['status', '=', 0]
  2531. ];
  2532. $house_status_per = CustomerPortraitField::where($house_status_where)->findOrEmpty();
  2533. $field = [];
  2534. if (!$house_status_per->isEmpty()) {
  2535. $field = CustomerPortraitFieldSelect::where('pid', $house_status_per->id)->column('name,id');
  2536. }
  2537. // 电话统计
  2538. $outCallLog = OutCallLog::where([['root_id', '=', $root_id]])->where($query_date)->field("count(id) as phone_count, sum(if(`status`>0,1,0)) as on_phone_count, sum(if(`status`<0,1,0)) as off_phone_count,sum(billsec) as phone_time,employee_id")->group('employee_id')->select()->toArray();
  2539. $outCallLog = array_combine(array_column($outCallLog, 'employee_id'), $outCallLog);
  2540. foreach ($list as $k => $v) {
  2541. //客户ID
  2542. $cids = array_column($v['customer'], 'id');
  2543. //客户数量
  2544. $list[$k]['customer_count'] = count($cids);
  2545. //待回访
  2546. $list[$k]['return_visit_count'] = count(array_filter(array_column($v['customer'], 'return_visit')));
  2547. //待指派
  2548. $assigned_personnel = count(array_filter(array_column($v['customer'], 'assigned_personnel')));
  2549. $list[$k]['no_assigned_personnel'] = $list[$k]['customer_count'] - $assigned_personnel;
  2550. //三天,七天,十五天,三十天,三十天以上未跟进
  2551. $list[$k]['no_visit_3'] = $list[$k]['no_visit_7'] = $list[$k]['no_visit_15'] = $list[$k]['no_visit_30'] = $list[$k]['no_visit_31'] = 0;
  2552. foreach ($v['customer'] as $customer_item) {
  2553. //最近跟进时间
  2554. $visit_time = isset($max_addtime[$customer_item['id']]) ? $max_addtime[$customer_item['id']] : $customer_item['addtime'];
  2555. $day = ceil((time() - strtotime($visit_time)) / 86400);
  2556. if ($day <= 3 && $day > 1) {
  2557. $list[$k]['no_visit_3'] += 1;
  2558. } elseif ($day <= 7 && $day > 3) {
  2559. $list[$k]['no_visit_7'] += 1;
  2560. } elseif ($day < 15 && $day > 7) {
  2561. $list[$k]['no_visit_15'] += 1;
  2562. } elseif ($day <= 30 && $day > 15) {
  2563. $list[$k]['no_visit_30'] += 1;
  2564. } elseif ($day > 30) {
  2565. $list[$k]['no_visit_31'] += 1;
  2566. }
  2567. }
  2568. //有效客户
  2569. $valid = array_intersect($cids, $valid_vislog);
  2570. //有效客户数量
  2571. $list[$k]['valid_count'] = count($valid);
  2572. //有效率
  2573. $list[$k]['valid_grawth'] = $this->grawth($list[$k]['customer_count'], $list[$k]['valid_count']);
  2574. if (isset($outCallLog[$v['id']])) {
  2575. //电话量
  2576. $list[$k]['phone_count'] = $outCallLog[$v['id']]['phone_count'];
  2577. //接通量
  2578. $list[$k]['on_phone_count'] = $outCallLog[$v['id']]['on_phone_count'];
  2579. //接通率
  2580. $list[$k]['on_phone_grawth'] = $this->grawth($list[$k]['phone_count'], $list[$k]['on_phone_count']);
  2581. //未接通
  2582. $list[$k]['off_phone_count'] = $outCallLog[$v['id']]['off_phone_count'];
  2583. //平均通话时长
  2584. $list[$k]['avg_phone_time'] = $list[$k]['on_phone_count'] == 0 ? 0 : round($outCallLog[$v['id']]['phone_time'] / $list[$k]['on_phone_count'], 2);
  2585. } else {
  2586. //电话量
  2587. $list[$k]['phone_count'] = 0;
  2588. //接通量
  2589. $list[$k]['on_phone_count'] = 0;
  2590. //接通率
  2591. $list[$k]['on_phone_grawth'] = 0;
  2592. //未接通
  2593. $list[$k]['off_phone_count'] = 0;
  2594. //平均通话时长
  2595. $list[$k]['avg_phone_time'] = 0;
  2596. }
  2597. $customer = $this->addWechatCount($v['customer'], $sdate, $edate);
  2598. //加微数量
  2599. $list[$k]['add_wechat_count'] = count($customer['wechat_count']);
  2600. //出方案客户数
  2601. $list[$k]['drawing_date'] = count($customer['plan_issuing_date']);
  2602. //加微率
  2603. $list[$k]['add_wechat_grawth'] = $this->grawth($list[$k]['valid_count'], $list[$k]['add_wechat_count']);
  2604. //量房客户数
  2605. $list[$k]['room'] = count(array_intersect($rooms, $cids));
  2606. //量房率
  2607. $list[$k]['room_grawth'] = $this->grawth($list[$k]['valid_count'], $list[$k]['room']);
  2608. //到店客户数
  2609. $store1 = array_intersect($store1, $cids);
  2610. $store2 = array_intersect($store2, $cids);
  2611. $store3 = array_intersect($store3, $cids);
  2612. $list[$k]['store1'] = count($store1);
  2613. $list[$k]['store2'] = count($store2);
  2614. $list[$k]['store3'] = count($store3);
  2615. $list[$k]['store1_grawth'] = $this->grawth($list[$k]['customer_count'], $list[$k]['store1']);
  2616. $list[$k]['store2_grawth'] = $this->grawth($list[$k]['customer_count'], $list[$k]['store2']);
  2617. $list[$k]['store3_grawth'] = $this->grawth($list[$k]['customer_count'], $list[$k]['store3']);
  2618. //交定客户数
  2619. $z_dep = array_intersect(array_keys($dep), $cids);
  2620. $dep1 = array_intersect($dep1, $cids);
  2621. $dep2 = array_intersect($dep2, $cids);
  2622. $dep3 = array_intersect($dep3, $cids);
  2623. $list[$k]['dep1'] = count($dep1);
  2624. $list[$k]['dep2'] = count($dep2);
  2625. $list[$k]['dep3'] = count($dep3);
  2626. $list[$k]['dep1_grawth'] = $this->grawth($list[$k]['customer_count'], $list[$k]['dep1']);
  2627. $list[$k]['dep2_grawth'] = $this->grawth($list[$k]['customer_count'], $list[$k]['dep2']);
  2628. $list[$k]['dep3_grawth'] = $this->grawth($list[$k]['customer_count'], $list[$k]['dep3']);
  2629. $list[$k]['dep'] = count($z_dep);
  2630. $list[$k]['dep_grawth'] = $this->grawth($list[$k]['customer_count'], $list[$k]['dep']);
  2631. //一次到店签单客户数
  2632. $list[$k]['store1_dep'] = count(array_intersect($z_dep, $store1));
  2633. $list[$k]['store1_dep_grawth'] = $this->grawth($list[$k]['customer_count'], $list[$k]['store1_dep']);
  2634. $list[$k]['store2_dep'] = count(array_intersect($z_dep, $store2));
  2635. $list[$k]['store2_dep_grawth'] = $this->grawth($list[$k]['customer_count'], $list[$k]['store2_dep']);
  2636. $list[$k]['store3_dep'] = count(array_intersect($z_dep, $store3));
  2637. $list[$k]['store3_dep_grawth'] = $this->grawth($list[$k]['customer_count'], $list[$k]['store3_dep']);
  2638. //签单
  2639. $list[$k]['sign_count'] = count(array_intersect($cids, $sign));
  2640. $list[$k]['sign_grawth'] = $this->grawth($list[$k]['customer_count'], $list[$k]['sign_count']);
  2641. //面积
  2642. $list[$k]['square_0_80'] = $customer['square_0_80']; //
  2643. $list[$k]['square_80_100'] = $customer['square_80_100']; //
  2644. $list[$k]['square_100_120'] = $customer['square_100_120']; //
  2645. $list[$k]['square_120_200'] = $customer['square_120_200']; //
  2646. $list[$k]['square_200_500'] = $customer['square_200_500']; //
  2647. $list[$k]['square_500'] = $customer['square_500']; //
  2648. //房屋类型
  2649. $list[$k]['existing_homes_count'] = $customer['existing_homes_count']; //现房数量
  2650. $list[$k]['forward_housing_count'] = $customer['forward_housing_count']; //期房数量
  2651. //房屋状态
  2652. if ($field) {
  2653. $house_status = $this->getHouseStatus($customer['house_status'], $field);
  2654. $list[$k] = array_merge($list[$k], $house_status);
  2655. }
  2656. unset($list[$k]['customer']);
  2657. }
  2658. return json(['code' => 0, 'data' => $list, 'count' => $count, 'msg' => '获取成功', 'page' => ceil($count / $param['limit'])]);
  2659. }
  2660. /**
  2661. * 率
  2662. */
  2663. private function grawth($zcount, $count)
  2664. {
  2665. $res = $zcount == 0 ? '0%' : round($count / $zcount * 100, 2) . '%';
  2666. return $res;
  2667. }
  2668. /**
  2669. * 房屋状态
  2670. */
  2671. private function getHouseStatus($house_status, $field)
  2672. {
  2673. $data = [];
  2674. $name = array_column($field, 'name');
  2675. $house = [];
  2676. foreach ($house_status as $v) {
  2677. @$house[$v] += 1;
  2678. }
  2679. foreach ($field as $k2 => $v2) {
  2680. $data['house_status_' . $v2['id']] = isset($house[$v2['name']]) ? $house[$v2['name']] : 0;
  2681. }
  2682. return $data;
  2683. }
  2684. /**
  2685. * 加微数量
  2686. */
  2687. private function addWechatCount($wechat, $sdate, $edate)
  2688. {
  2689. $data['wechat_count'] = [];
  2690. $data['plan_issuing_date'] = []; //出方案时间
  2691. $square = $house_type = [];
  2692. $data['house_status'] = [];
  2693. foreach ($wechat as $v) {
  2694. $data['house_status'][] = $v['house_status'];
  2695. $square[] = $v['square'];
  2696. $house_type[] = $v['house_type'];
  2697. //客户添加时间
  2698. $addtime = strtotime($v['addtime']);
  2699. //加微客户,有户型图客户
  2700. $v2 = $v['ext'];
  2701. $ext = json_decode($v2, true);
  2702. if (!empty($ext) && is_array($ext)) {
  2703. $ext = array_filter($ext);
  2704. foreach ($ext as $e) {
  2705. if (isset($e['keyname']) && $e['keyname'] == 'add_wechat_time' && !empty($e['value']) && strtotime($e['value']) >= $sdate && strtotime($e['value']) <= $edate) {
  2706. $data['wechat_count'][] = $v['id'];
  2707. } elseif (isset($e['keyname']) && $e['keyname'] == 'drawing_date' && !empty($e['value']) && strtotime($e['value']) >= $sdate && strtotime($e['value']) <= $edate) {
  2708. $data['drawing_date'][] = $v['id'];
  2709. }
  2710. }
  2711. }
  2712. }
  2713. //面积
  2714. //房屋面积
  2715. $data['square_0_80'] = $data['square_80_100'] = $data['square_100_120'] = $data['square_120_200'] = $data['square_200_500'] = $data['square_500'] = 0;
  2716. foreach ($square as $square_item) {
  2717. if (!$square_item) continue; //不填不计算
  2718. if ($square_item <= 80) {
  2719. $data['square_0_80'] += 1;
  2720. } elseif ($square_item <= 100) {
  2721. $data['square_80_100'] += 1;
  2722. } elseif ($square_item <= 120) {
  2723. $data['square_100_120'] += 1;
  2724. } elseif ($square_item <= 200) {
  2725. $data['square_120_200'] += 1;
  2726. } elseif ($square_item <= 500) {
  2727. $data['square_200_500'] += 1;
  2728. } else {
  2729. $data['square_500'] += 1;
  2730. }
  2731. }
  2732. //房屋类型
  2733. $data['existing_homes_count'] = 0; //现房数量
  2734. $data['forward_housing_count'] = 0; //期房数量
  2735. foreach ($house_type as $house_type_item) {
  2736. if (strpos($house_type_item, '现房') !== false) {
  2737. $data['existing_homes_count'] += 1;
  2738. } elseif (strpos($house_type_item, '期房') !== false) {
  2739. $data['forward_housing_count'] += 1;
  2740. }
  2741. }
  2742. return $data;
  2743. }
  2744. /**
  2745. * 客户统计表
  2746. */
  2747. public function customer_statistics_list()
  2748. {
  2749. $request = request();
  2750. $root_id = $request->empcrm->root_id;
  2751. $orgids = orgSubIds($request->empcrm->org_id);
  2752. if (!request()->isAjax()) {
  2753. $org = Org::where([['id', 'in', $orgids], ['org_type', '<>', 2]])->field('id,name')->select()->toArray();
  2754. View::assign('org', $org);
  2755. //渠道来源下拉
  2756. $source = CustomerSource::where('root_id', $root_id)->column('id,source');
  2757. View::assign('source', $source);
  2758. $customer_type = [['id' => 1, 'name' => '资源库'], ['id' => 2, 'name' => '活动报名'], ['id' => 3, 'name' => '装修推荐官'], ['id' => 4, 'name' => '自建'], ['id' => 5, 'name' => '公海获取']];
  2759. View::assign('customer_type', $customer_type);
  2760. return View::fetch();
  2761. }
  2762. $page = input('page', 1, 'intval');
  2763. $limit = input('limit', 20, 'intval');
  2764. $source_id = input('source_id', 0);
  2765. $customer_type = input('customer_type', '', 'intval');
  2766. switch ($customer_type) {
  2767. case 1:
  2768. $where[] = ['crm_res_id', '>', 0];
  2769. $where[] = ['remark', '<>', '公海获取'];
  2770. break;
  2771. case 2:
  2772. $where[] = ['remark', '=', '活动报名建档'];
  2773. break;
  2774. case 3:
  2775. $where[] = ['agents_id', '>', 0];
  2776. break;
  2777. case 4:
  2778. $where[] = ['crm_res_id', 'NULL', null];
  2779. $where[] = ['remark', '<>', '活动报名建档'];
  2780. $where[] = ['remark', '<>', '公海获取'];
  2781. $where[] = ['agents_id', 'NULL', null];
  2782. break;
  2783. case 5:
  2784. $where[] = ['remark', '=', '公海获取'];
  2785. break;
  2786. default:
  2787. break;
  2788. }
  2789. $employee_name = input('keyword', '', 'trim');
  2790. if ($employee_name) {
  2791. $employee_ids = Employee::where([['org_id', 'in', $orgids], ['name', 'like', '%' . $employee_name . '%'], ['root_id', '=', $root_id]])->column('id');
  2792. $where[] = ['employee_id', 'in', $employee_ids];
  2793. }
  2794. $start_date = input('start_date', '', 'trim');
  2795. $end_date = input('end_date', '', 'trim');
  2796. if ($start_date) {
  2797. $count_dates = explode(' - ', $start_date);
  2798. $start_date = $count_dates[0];
  2799. $end_date = $count_dates[1];
  2800. } else {
  2801. $start_date = $end_date = '';
  2802. }
  2803. if ($start_date && $end_date) {
  2804. $where[] = ['addtime', 'between', [$start_date . ' 00:00:00', $end_date . ' 23:59:59']];
  2805. }
  2806. $org_id = input('org_id', '', 'trim');
  2807. $org_ids = orgSubIds($root_id);
  2808. if ($org_id) {
  2809. $org_id = explode(',', $org_id);
  2810. $sel_org_ids = [];
  2811. foreach ($org_id as $k => $v) {
  2812. if (in_array($v, $org_ids)) {
  2813. $sel_org_ids[] = $v;
  2814. }
  2815. }
  2816. $where[] = ['org_id', 'in', $sel_org_ids];
  2817. } else {
  2818. $where[] = ['org_id', 'in', $orgids];
  2819. }
  2820. if ($source_id) $where[] = ['source_id', '=', $source_id];
  2821. $model = Customer::where($where)->where(function ($query) {
  2822. $state11 = Customer::changeState('待确认', 'chaos');
  2823. $state22 = Customer::changeState('无效', 'chaos');
  2824. $or1[] = ['crm_res_id', '>', 0];
  2825. $or1[] = ['state', 'not in', array_merge($state11, $state22)];
  2826. $or2[] = ['crm_res_id', 'null', null];
  2827. $or2[] = ['state', 'not in', $state22];
  2828. $query->whereOr([$or1, $or2]);
  2829. });
  2830. $count = $model->count();
  2831. $list = $model->with(['employee', 'org', 'designer', 'source'])->page($page, $limit)->order('addtime desc')->select()->each(function ($item) {
  2832. if ($item['remark'] == '公海获取') {
  2833. $customer_type = '公海获取';
  2834. } elseif ($item['agents_id']) {
  2835. $customer_type = '装修推荐官';
  2836. } elseif ($item['remark'] == '活动报名建档') {
  2837. $customer_type = '活动报名';
  2838. } elseif ($item['crm_res_id']) {
  2839. $customer_type = '资源库';
  2840. } else {
  2841. $customer_type = '自建';
  2842. }
  2843. $item['customer_type'] = $customer_type;
  2844. if (empty($item['name'])) {
  2845. $item['name'] = '未知';
  2846. }
  2847. if (empty($item['community_name'])) {
  2848. $item['community_name'] = '未知';
  2849. }
  2850. if (empty($item['house_type'])) {
  2851. $item['house_type'] = '未知';
  2852. }
  2853. if (empty($item['square'])) {
  2854. $item['square'] = '未知';
  2855. }
  2856. $item['phone'] = substr_replace($item['phone'], '******', 3, 6);
  2857. $item['signed_money_data'] = $item->getData('signed_money');
  2858. // 指派客户经理及设计师
  2859. $assigned_personal_manager_ids = [];
  2860. if ($item['assigned_personnel']) {
  2861. $assigned_personal = explode(',', $item['assigned_personnel']);
  2862. $assigned_personal_list = Employee::with('org')->where('id', 'in', $assigned_personal)->select()->toArray();
  2863. $assigned_personal_designer = [];
  2864. $assigned_personal_manager = [];
  2865. $assigned_personal_designer_org = [];
  2866. foreach ($assigned_personal_list as $k => $v) {
  2867. if ($v['org']['org_type'] == 2) {
  2868. $assigned_personal_designer[] = $v['name'];
  2869. $assigned_personal_designer_org[] = $v['org']['name'];
  2870. } else {
  2871. $assigned_personal_manager[] = $v['name'];
  2872. $assigned_personal_manager_ids[] = $v['id'];
  2873. }
  2874. }
  2875. $item['assigned_personal_manager'] = $assigned_personal_manager ? implode('、', $assigned_personal_manager) : '无';
  2876. $item['assigned_personal_designer'] = $assigned_personal_designer ? implode('、', $assigned_personal_designer) : '无';
  2877. $item['assigned_personal_designer_org'] = $assigned_personal_designer_org ? implode('、', $assigned_personal_designer_org) : '无';
  2878. } else {
  2879. $item['assigned_personal_manager'] = '无';
  2880. $item['assigned_personal_designer'] = '无';
  2881. $item['assigned_personal_designer_org'] = '无';
  2882. }
  2883. // 未跟踪天数
  2884. $last_visit_log = CustomerVisitLog::where('customer_id', '=', $item['id'])->findOrEmpty();
  2885. if (!$last_visit_log->isEmpty()) {
  2886. $time_long = time() - strtotime($last_visit_log['addtime']);
  2887. } else {
  2888. $time_long = time() - strtotime($item['addtime']);
  2889. }
  2890. $no_visit_day = ceil($time_long / (24 * 3600));
  2891. $item['no_visit_day'] = $no_visit_day;
  2892. // 是否加微
  2893. $ext = json_decode($item['ext'], true);
  2894. $item['wechat'] = '否'; // 是否加微
  2895. $item['add_wechat_type'] = '无'; // 加微类型
  2896. $item['add_wechat_time'] = '无'; // 加微时间
  2897. $item['plan_issuing_date'] = '无'; //出方案时间
  2898. $item['drawing_date'] = '无'; // 出图时间
  2899. $item['group_building_date'] = '无'; // 建群时间
  2900. if (!empty($ext)) {
  2901. foreach ($ext as $v) {
  2902. if (isset($v['keyname']) && $v['keyname'] == 'wechat' && !empty($v['value'])) {
  2903. $item['wechat'] = CustomerPortraitFieldSelect::where('id', $v['value'])->value('name');
  2904. } elseif (isset($v['keyname']) && $v['keyname'] == 'add_wechat_time' && !empty($v['value'])) {
  2905. $item['wechat'] = '是';
  2906. } elseif (isset($v['keyname']) && $v['keyname'] == 'add_wechat_type' && !empty($v['value'])) {
  2907. $item['wechat'] = '是';
  2908. }
  2909. if (isset($v['keyname']) && $v['keyname'] == 'add_wechat_time' && !empty($v['value'])) {
  2910. $item['add_wechat_time'] = $v['value'];
  2911. }
  2912. if (isset($v['keyname']) && $v['keyname'] == 'add_wechat_type' && !empty($v['value'])) {
  2913. $item['add_wechat_type'] = CustomerPortraitFieldSelect::where('id', $v['value'])->value('name');
  2914. }
  2915. if (isset($v['keyname']) && $v['keyname'] == 'plan_issuing_date' && !empty($v['value'])) {
  2916. $item['plan_issuing_date'] = $v['value'];
  2917. }
  2918. if (isset($v['keyname']) && $v['keyname'] == 'drawing_date' && !empty($v['value'])) {
  2919. $item['drawing_date'] = $v['value'];
  2920. }
  2921. if (isset($v['keyname']) && $v['keyname'] == 'group_building_date' && !empty($v['value'])) {
  2922. $item['group_building_date'] = $v['value'];
  2923. }
  2924. }
  2925. }
  2926. $lf_state = CustomerVisitLog::changeState('已量房', 'chaos');
  2927. $lf_list = CustomerVisitLog::where([['customer_id', '=', $item['id']], ['state', 'in', $lf_state]])->order('addtime asc')->select()->toArray();
  2928. if (!empty($lf_list)) {
  2929. $item['is_liangfang'] = '是';
  2930. $item['liangfang_date'] = $lf_list[0]['addtime'];
  2931. $item['once_liangfang_days'] = ceil((strtotime($lf_list[0]['addtime']) - strtotime($item['addtime'])) / (24 * 3600));
  2932. } else {
  2933. $item['is_liangfang'] = '否';
  2934. $item['liangfang_date'] = '无';
  2935. $item['once_liangfang_days'] = '无';
  2936. }
  2937. // 到店
  2938. $dd_state = CustomerVisitLog::changeState('已到店', 'chaos');
  2939. $dd_list = CustomerVisitLog::where([['customer_id', '=', $item['id']], ['state', 'in', $dd_state]])->order('addtime asc')->select()->toArray();
  2940. $item['once_daodian'] = '否';
  2941. $item['daodian_date'] = '无';
  2942. $item['once_daodian_days'] = '无';
  2943. $item['once_daodian_shop'] = '无';
  2944. $item['twice_daodian_date'] = '无'; //二次到店时间
  2945. $item['twice_daodian_days'] = '无'; // 二次到店周期 二次到店时间 - 一次到店时间
  2946. $item['twice_daodian_shop'] = '无';
  2947. if (!empty($dd_list)) {
  2948. $item['once_daodian'] = '是';
  2949. $item['daodian_date'] = $dd_list[0]['addtime'];
  2950. $item['once_daodian_days'] = ceil((strtotime($dd_list[0]['addtime']) - strtotime($item['addtime'])) / (24 * 3600));
  2951. if (!empty($dd_list[0]['shop_id'])) {
  2952. $shop_name = Shop::where('id', $dd_list[0]['shop_id'])->findOrEmpty();
  2953. if ($shop_name->isEmpty()) {
  2954. $item['once_daodian_shop'] = '未知';
  2955. } else {
  2956. $item['once_daodian_shop'] = $shop_name['name'];
  2957. }
  2958. }
  2959. // 二次到店
  2960. if (count($dd_list) > 1) {
  2961. $item['twice_daodian_date'] = $dd_list[1]['addtime'];
  2962. $item['twice_daodian_days'] = ceil((strtotime($dd_list[1]['addtime']) - strtotime($dd_list[0]['addtime'])) / (24 * 3600));
  2963. $shop_name = Shop::where('id', $dd_list[1]['shop_id'])->findOrEmpty();
  2964. if ($shop_name->isEmpty()) {
  2965. $item['twice_daodian_shop'] = '未知';
  2966. } else {
  2967. $item['twice_daodian_shop'] = $shop_name['name'];
  2968. }
  2969. }
  2970. }
  2971. // 量房 - 到店 周期
  2972. if (!empty($lf_list) && !empty($dd_list)) {
  2973. if ($lf_list[0]['addtime'] > $dd_list[0]['addtime']) {
  2974. $item['liangfang_daodian_days'] = ceil((strtotime($lf_list[0]['addtime']) - strtotime($dd_list[0]['addtime'])) / (24 * 3600));
  2975. } else {
  2976. $item['liangfang_daodian_days'] = ceil((strtotime($dd_list[0]['addtime']) - strtotime($lf_list[0]['addtime'])) / (24 * 3600));
  2977. }
  2978. } else {
  2979. $item['liangfang_daodian_days'] = '无';
  2980. }
  2981. // 交定(签单)
  2982. $jd_state = CustomerVisitLog::changeState('已交定', 'chaos');
  2983. $jd_list = CustomerVisitLog::where([['customer_id', '=', $item['id']], ['state', 'in', $jd_state]])->order('addtime asc')->select()->toArray();
  2984. if (!empty($jd_list)) {
  2985. $item['is_deposit'] = '是';
  2986. $item['deposit_date'] = $jd_list[0]['addtime'];
  2987. $item['deposit_days'] = ceil((strtotime($jd_list[0]['addtime']) - strtotime($item['addtime'])) / (24 * 3600));
  2988. } else {
  2989. $item['is_deposit'] = '否';
  2990. $item['deposit_date'] = '无';
  2991. $item['deposit_days'] = '无';
  2992. }
  2993. // 签单(转单)
  2994. $qd_state = CustomerVisitLog::changeState('已签单', 'chaos');
  2995. $qd_list = CustomerVisitLog::where([['customer_id', '=', $item['id']], ['state', 'in', $qd_state]])->order('addtime asc')->select()->toArray();
  2996. if (!empty($qd_list)) {
  2997. $item['sign_date'] = $qd_list[0]['addtime'];
  2998. $item['sign_days'] = ceil((strtotime($qd_list[0]['addtime']) - strtotime($item['addtime'])) / (24 * 3600));
  2999. } else {
  3000. $item['sign_date'] = '无';
  3001. $item['sign_days'] = '无';
  3002. }
  3003. // 交定转单周期
  3004. if (!empty($jd_list) && !empty($qd_list)) {
  3005. if ($jd_list[0]['addtime'] > $qd_list[0]['addtime']) {
  3006. $item['deposit_sign_days'] = ceil((strtotime($jd_list[0]['addtime']) - strtotime($qd_list[0]['addtime'])) / (24 * 3600));
  3007. } else {
  3008. $item['deposit_sign_days'] = ceil((strtotime($qd_list[0]['addtime']) - strtotime($jd_list[0]['addtime'])) / (24 * 3600));
  3009. }
  3010. } else {
  3011. $item['deposit_sign_days'] = '无';
  3012. }
  3013. // 一次到店未签单时间
  3014. $first_visit = CustomerVisitLog::where([['customer_id', '=', $item['id']], ['state', 'in', $dd_state]])->order('addtime asc')->findOrEmpty();
  3015. $item['first_visit_no_sign'] = '无';
  3016. if (!$first_visit->isEmpty()) {
  3017. $first_visit_no_sign = CustomerVisitLog::where([['customer_id', '=', $item['id']], ['addtime', '>', $first_visit['addtime']]])->order('addtime asc')->findOrEmpty();
  3018. if (!$first_visit_no_sign->isEmpty()) {
  3019. if (!in_array($first_visit_no_sign['state'], $qd_state)) {
  3020. $item['first_visit_no_sign'] = $first_visit['addtime'];
  3021. }
  3022. }
  3023. }
  3024. // 客户经理回访
  3025. if (!empty($assigned_personal_manager_ids)) {
  3026. $manager_next_visit = CustomerVisitLog::where([['employee_id', 'in', $assigned_personal_manager_ids], ['next_contact_date', 'not null', ''], ['customer_id', '=', $item['id']]])->field('customer_id,next_contact_date,addtime,employee_id')->select()->toArray();
  3027. $manager_visit_times = 0;
  3028. $manager_visit_days = 0;
  3029. foreach ($manager_next_visit as $k => $v) {
  3030. unset($visit_where);
  3031. $visit_where[] = ['addtime', 'between', [$v['next_contact_date'] . ' 00:00:00', $v['next_contact_date'] . ' 23:59:59']];
  3032. $visit_where[] = ['customer_id', '=', $v['customer_id']];
  3033. $visit_where[] = ['employee_id', '=', $v['employee_id']];
  3034. $visit_next_find = CustomerVisitLog::where($visit_where)->findOrEmpty();
  3035. if (!$visit_next_find->isEmpty()) {
  3036. $manager_visit_times++;
  3037. $next_days = ceil((strtotime($visit_next_find['addtime']) - strtotime($v['next_contact_date'])) / (24 * 3600));
  3038. $manager_visit_days += $next_days;
  3039. }
  3040. }
  3041. $item['manager_visit_times'] = $manager_visit_times;
  3042. $item['manager_visit_cycle'] = $manager_visit_times ? round($manager_visit_days / $manager_visit_times, 1) : '无';
  3043. } else {
  3044. $item['manager_visit_times'] = 0;
  3045. $item['manager_visit_cycle'] = '无';
  3046. }
  3047. // 经理回访
  3048. $employee_next_visit = CustomerVisitLog::where([['customer_id', '=', $item['id']], ['next_contact_date', 'not null', ''], ['employee_id', '=', $item['employee_id']]])->field('customer_id,next_contact_date,employee_id')->select()->toArray();
  3049. $employee_visit_times = 0;
  3050. $employee_visit_days = 0;
  3051. foreach ($employee_next_visit as $k => $v) {
  3052. unset($visit_where);
  3053. $visit_where[] = ['addtime', 'between', [$v['next_contact_date'] . ' 00:00:00', $v['next_contact_date'] . ' 23:59:59']];
  3054. $visit_where[] = ['customer_id', '=', $v['customer_id']];
  3055. $visit_where[] = ['employee_id', '=', $v['employee_id']];
  3056. $visit_next_find = CustomerVisitLog::where($visit_where)->findOrEmpty();
  3057. if (!$visit_next_find->isEmpty()) {
  3058. $employee_visit_times++;
  3059. $next_days = ceil((strtotime($visit_next_find['addtime']) - strtotime($v['next_contact_date'])) / (24 * 3600));
  3060. $employee_visit_days += $next_days;
  3061. }
  3062. }
  3063. $item['employee_visit_times'] = $employee_visit_times;
  3064. $item['employee_visit_cycle'] = $employee_visit_times ? round($employee_visit_days / $employee_visit_times, 1) : '无';
  3065. $wx_state = Customer::changeState('无效', 'chaos');
  3066. if (in_array($item['state'], $wx_state)) {
  3067. $item['invalid'] = '是';
  3068. } else {
  3069. $item['invalid'] = '否';
  3070. }
  3071. if ($item['died'] == 2) {
  3072. $item['died'] = '是';
  3073. } else {
  3074. $item['died'] = '否';
  3075. }
  3076. })->toArray();
  3077. $clue_where[] = ['name', '=', 'clueTag'];
  3078. $clue_where[] = ['root_id', '=', request()->empcrm->root_id];
  3079. $find = Setting::where($clue_where)->findOrEmpty();
  3080. if ($find->isEmpty()) {
  3081. $clue_tag = ['已装修', '无需求', '有需求', '超地域', '未交房', '在外地', '无购买力', '未接通电话'];
  3082. } else {
  3083. $clue_tag = array_filter(explode(',', $find['content']));
  3084. }
  3085. foreach ($list as $k => $v) {
  3086. $list[$k]['house_delivery_time'] = $v['house_delivery_time'] ? $v['house_delivery_time'] : '未知';
  3087. $list[$k]['employee_name'] = $v['employee']['name'] ?? '无';
  3088. $list[$k]['source_name'] = $v['source']['source'] ?? '未知';
  3089. if ($v['invalid'] == '否') {
  3090. $list[$k]['invalid_remark'] = '';
  3091. } else {
  3092. $wx_state = CustomerVisitLog::changeState('无效', 'chaos');
  3093. $invalid_log = CustomerVisitLog::where([['customer_id', '=', $v['id']], ['state', 'in', $wx_state]])->order('addtime desc')->findOrEmpty();
  3094. if (!$invalid_log->isEmpty() && !empty($invalid_log['remark']) && in_array($invalid_log['remark'], $clue_tag)) {
  3095. $list[$k]['invalid_remark'] = $invalid_log['remark'];
  3096. } else {
  3097. $list[$k]['invalid_remark'] = '其他';
  3098. }
  3099. }
  3100. }
  3101. return json(['code' => 0, 'data' => $list, 'count' => $count, 'page' => ceil($count / $limit)]);
  3102. }
  3103. //获取设计师列表
  3104. private function get_designer()
  3105. {
  3106. //设计师获取
  3107. $w[] = ['path', 'like', request()->empcrm->root_id . '-%'];
  3108. $w[] = ['org_type', '=', 2];
  3109. $orgs = Org::where($w)->column('id');
  3110. $list = Employee::where([['org_id', 'in', $orgs], ['state', '=', '在职'], ['show', '=', 0]])->field('id,name,initials s')->order('s asc')->select()->toArray();
  3111. return $list;
  3112. }
  3113. /**
  3114. * 共有客户
  3115. */
  3116. public function shareList()
  3117. {
  3118. $request = request();
  3119. $root_id = $request->empcrm->root_id;
  3120. $empid = $request->empcrm->id;
  3121. $orgids = orgSubIds($request->empcrm->org_id);
  3122. $is_manager = $request->empcrm->is_manager;
  3123. $path = Org::where([['pid', '=', $request->empcrm->org_id]])->count();
  3124. $param = $request->only(['page' => 1, 'limit' => 17, 'last_contact_date', 'assign_org', 'assign_list', 'community_name', 'no_visit_day', 'liangfang_time', 'jiaoding_time', 'qiandan_time', 'jiaoding_money', 'qiandan_money', 'daodian_time' => '', 'square', 'level', 'source_name', 'name' => '', 'state', 'assign_time', 'phone', 'employee_name', 'assign_type_name', 'designer_name']);
  3125. if (!$request->isAjax()) {
  3126. $employee_list = Employee::where([['org_id', 'in', $orgids], ['state', '=', '在职'], ['uid', '>', 0]])->column('id,name');
  3127. View::assign('employee_list', $employee_list);
  3128. //来源
  3129. $soudata = CustomerSource::field('id,source as name')->where('root_id', $root_id)->select()->toArray();
  3130. View::assign('soudata', $soudata);
  3131. //设计师
  3132. $list = $this->get_designer();
  3133. if (!empty($list)) {
  3134. $sort = array_column($list, 's');
  3135. sort($sort);
  3136. array_multisort($sort, SORT_ASC, $list);
  3137. $sort = array_unique($sort);
  3138. $list = ['sort' => $sort, 'arr' => $list];
  3139. } else {
  3140. $list = ['sort' => [], 'arr' => []];
  3141. }
  3142. View::assign('designers', $list);
  3143. //客户等级
  3144. $level = CustomerPortraitField::with(['select'])->where([['root_id', '=', $root_id], ['keyname', '=', 'level']])->find()->toArray();
  3145. View::assign('level', $level['select']);
  3146. //指派经理
  3147. $assignemp_list = Employee::where([['org_id', 'in', orgSubIds($root_id)], ['id', 'not in', array_column($list['arr'], 'id')], ['state', '=', '在职'], ['uid', '>', 0]])->column('id,name');
  3148. View::assign('assignemp_list', $assignemp_list);
  3149. //指派部门
  3150. $assignorg_list = Org::where([['path', 'like', $root_id . '-%']])->column('id,name');
  3151. View::assign('assignorg_list', $assignorg_list);
  3152. $assign_type = [['id' => 1, 'name' => '意向指派'], ['id' => 2, 'name' => '量房指派'], ['id' => 3, 'name' => '到店指派']];
  3153. View::assign('assign_type', $assign_type);
  3154. return View::fetch();
  3155. }
  3156. //$org_employee = [$empid];
  3157. if ($is_manager == 1) {
  3158. $team_orgs = orgSubIds($request->empcrm->org_id);
  3159. $org_employee = Employee::where([['org_id', 'in', $team_orgs], ['state', '=', '在职'], ['uid', '>', 0]])->column('id');
  3160. } else {
  3161. $org_employee = [$empid];
  3162. }
  3163. $condition[] = ['state', 'not in', Customer::changeState('无效', 'chaos')];
  3164. // $condition[] = ['employee_id|designer_id|assigned_personnel', 'find in set', $org_employee];
  3165. $condition1[] = ['assigned_personnel', 'not null', ""];
  3166. $condition1[] = ['designer_id', '>', 0];
  3167. $condition[] = ['employee_id', '>', 0];
  3168. $condition[] = ['died', '<>', 2];
  3169. if (!empty($param['assign_type_name'])) {
  3170. $all_assign_type = [1 => 'yixiang', 2 => 'liangfang', 3 => 'daodian'];
  3171. foreach (explode(',', $param['assign_type_name']) as $v) {
  3172. if (!empty($all_assign_type[$v])) $now_assign_type[] = $all_assign_type[$v];
  3173. }
  3174. //$param_assign_type = !empty($all_assign_type[$param['assign_type']]) ? $all_assign_type[$param['assign_type']] : '';
  3175. $condition[] = ['assign_type', 'in', $now_assign_type];
  3176. }
  3177. //客户姓名
  3178. if (!empty($param['name'])) $condition[] = ['name', 'like', '%' . $param['name'] . '%'];
  3179. //小区名称
  3180. if (!empty($param['community_name'])) $condition[] = ['community_name', 'like', '%' . $param['community_name'] . '%'];
  3181. //等级
  3182. if (!empty($param['level'])) $condition[] = ['level', 'in', explode(',', $param['level'])];
  3183. //来源
  3184. if (!empty($param['source_name'])) $condition[] = ['source_id', 'in', explode(',', $param['source_name'])];
  3185. //所属员工
  3186. if (!empty($param['employee_name'])) $condition[] = ['employee_id', 'in', explode(',', $param['employee_name'])];
  3187. //所属设计师
  3188. if (!empty($param['designer_name'])) $condition[] = ['designer_id', 'in', explode(',', $param['designer_name'])];
  3189. //客户的跟进时间
  3190. if (!empty($param['last_contact_date'])) {
  3191. $last_contact = explode(' - ', $param['last_contact_date']);
  3192. $start = str_replace('/', '-', $last_contact[0]);
  3193. $end = str_replace('/', '-', $last_contact[1]);
  3194. $condition[] = ['last_contact_date', '>=', $start . ' 00:00:00'];
  3195. $condition[] = ['last_contact_date', '<=', $end . ' 23:59:59'];
  3196. }
  3197. //指派时间查询
  3198. if (!empty($param['assign_time'])) {
  3199. $assign_time = explode('-', $param['assign_time']);
  3200. $start = $assign_time[0] . ' 00:00:00';
  3201. $end = $assign_time[1] . ' 23:59:59';
  3202. $condition[] = ['assign_time', '>', $start];
  3203. $condition[] = ['assign_time', '<', $end];
  3204. }
  3205. $customerIdList = Customer::where($condition)->where(function ($query) use ($org_employee) {
  3206. foreach ($org_employee as $v) {
  3207. $query->whereOr([['employee_id|designer_id|assigned_personnel', 'find in set', $v]]);
  3208. }
  3209. })->where(function ($query) use ($condition1) {
  3210. $query->whereOr($condition1);
  3211. })->column('id');
  3212. unset($condition);
  3213. $condition[] = ['id', 'in', $customerIdList];
  3214. //手机号
  3215. if (!empty($param['phone'])) {
  3216. $list = Customer::where($condition)->order('addtime desc')->field('id,name,community_name,phone')->select()->toArray();
  3217. $customerIdList = [];
  3218. foreach ($list as $v) {
  3219. if (strpos($v['phone'], trim($param['phone'])) !== false) $customerIdList[] = $v['id'];
  3220. }
  3221. unset($condition);
  3222. $condition[] = ['id', 'in', $customerIdList];
  3223. }
  3224. //客户经理
  3225. if (!empty($param['assign_list'])) {
  3226. $assign_employee = explode(',', $param['assign_list']);
  3227. $customerIdList = Customer::where($condition)->where(function ($query) use ($assign_employee) {
  3228. foreach ($assign_employee as $v) {
  3229. $query->whereOr([['assigned_personnel', 'find in set', $v]]);
  3230. }
  3231. })->column('id');
  3232. unset($condition);
  3233. $condition[] = ['id', 'in', $customerIdList];
  3234. }
  3235. //指派部门
  3236. if (!empty($param['assign_org'])) {
  3237. $assign_org = explode(',', $param['assign_org']);
  3238. $all_assigids = [];
  3239. $assigned_personnelList = Customer::where($condition)->column('assigned_personnel,id,designer_id');
  3240. foreach ($assigned_personnelList as $k => $v) {
  3241. $assigned_personal = !empty($v['assigned_personnel']) ? explode(',', $v['assigned_personnel']) : [];
  3242. if (!empty($v['designer_id'])) $assigned_personal[] = $v['designer_id'];
  3243. $assign_orgid = Employee::where([['id', 'in', $assigned_personal], ['org_id', 'in', $assign_org], ['root_id', '=', $root_id]])->column('org_id');
  3244. if (!empty($assign_orgid)) $all_assigids[] = $v['id'];
  3245. }
  3246. unset($condition);
  3247. $condition[] = ['id', 'in', $all_assigids];
  3248. }
  3249. //到店时间
  3250. if (!empty($param['daodian_time'])) {
  3251. $daodian_time = explode(' - ', $param['daodian_time']);
  3252. if (empty($daodian_time)) return json(['code' => 1, 'msg' => '时间参数错误']);
  3253. $start = str_replace('/', '-', $daodian_time[0]);
  3254. $end = str_replace('/', '-', $daodian_time[1]);
  3255. $customerIdList = Customer::where($condition)->column('id');
  3256. $logwhere[] = ['addtime', '>=', $start . ' 00:00:00'];
  3257. $logwhere[] = ['addtime', '<=', $end . ' 23:59:59'];
  3258. $logwhere[] = ['state', 'in', CustomerVisitLog::changeState('已到店', 'chaos')];
  3259. $logwhere[] = ['customer_id', 'in', $customerIdList];
  3260. $customerIdList = CustomerVisitLog::where($logwhere)->group('customer_id')->column('customer_id');
  3261. unset($condition);
  3262. $condition[] = ['id', 'in', $customerIdList];
  3263. }
  3264. //量房时间
  3265. if (!empty($param['liangfang_time'])) {
  3266. $liangfang_time = explode(' - ', $param['liangfang_time']);
  3267. if (empty($liangfang_time)) return json(['code' => 1, 'msg' => '时间参数错误']);
  3268. $start = str_replace('/', '-', $liangfang_time[0]);
  3269. $end = str_replace('/', '-', $liangfang_time[1]);
  3270. $customerIdList = Customer::where($condition)->column('id');
  3271. $logwhere[] = ['addtime', '>=', $start . ' 00:00:00'];
  3272. $logwhere[] = ['addtime', '<=', $end . ' 23:59:59'];
  3273. $logwhere[] = ['state', 'in', CustomerVisitLog::changeState('已量房', 'chaos')];
  3274. $logwhere[] = ['customer_id', 'in', $customerIdList];
  3275. $customerIdList = CustomerVisitLog::where($logwhere)->group('customer_id')->column('customer_id');
  3276. unset($condition);
  3277. $condition[] = ['id', 'in', $customerIdList];
  3278. }
  3279. //交定时间
  3280. if (!empty($param['jiaoding_time'])) {
  3281. $jiaoding_time = explode(' - ', $param['jiaoding_time']);
  3282. if (empty($jiaoding_time)) return json(['code' => 1, 'msg' => '时间参数错误']);
  3283. $start = str_replace('/', '-', $jiaoding_time[0]);
  3284. $end = str_replace('/', '-', $jiaoding_time[1]);
  3285. $customerIdList = Customer::where($condition)->column('id');
  3286. $logwhere[] = ['addtime', '>=', $start . ' 00:00:00'];
  3287. $logwhere[] = ['addtime', '<=', $end . ' 23:59:59'];
  3288. $logwhere[] = ['state', 'in', CustomerVisitLog::changeState('已交定', 'chaos')];
  3289. $logwhere[] = ['customer_id', 'in', $customerIdList];
  3290. $customerIdList = CustomerVisitLog::where($logwhere)->group('customer_id')->column('customer_id');
  3291. unset($condition);
  3292. $condition[] = ['id', 'in', $customerIdList];
  3293. }
  3294. //签单时间
  3295. if (!empty($param['qiandan_time'])) {
  3296. $qiandan_time = explode(' - ', $param['qiandan_time']);
  3297. if (empty($qiandan_time)) return json(['code' => 1, 'msg' => '时间参数错误']);
  3298. $start = str_replace('/', '-', $qiandan_time[0]);
  3299. $end = str_replace('/', '-', $qiandan_time[1]);
  3300. $customerIdList = Customer::where($condition)->column('id');
  3301. $logwhere[] = ['addtime', '>=', $start . ' 00:00:00'];
  3302. $logwhere[] = ['addtime', '<=', $end . ' 23:59:59'];
  3303. $logwhere[] = ['state', 'in', CustomerVisitLog::changeState('已签单', 'chaos')];
  3304. $logwhere[] = ['customer_id', 'in', $customerIdList];
  3305. $customerIdList = CustomerVisitLog::where($logwhere)->group('customer_id')->column('customer_id');
  3306. unset($condition);
  3307. $condition[] = ['id', 'in', $customerIdList];
  3308. }
  3309. //交定金额
  3310. if (!empty($param['jiaoding_money'])) {
  3311. $jiaoding_money = explode('-', $param['jiaoding_money']);
  3312. if (empty($jiaoding_money)) return json(['code' => 1, 'msg' => '参数错误']);
  3313. $customerIdList = Customer::where($condition)->column('id');
  3314. $logwhere[] = ['state', 'in', CustomerVisitLog::changeState('已交定', 'chaos')];
  3315. $logwhere[] = ['money', 'between', $jiaoding_money];
  3316. $logwhere[] = ['customer_id', 'in', $customerIdList];
  3317. $customerIdList = CustomerVisitLog::where($logwhere)->group('customer_id')->column('customer_id');
  3318. unset($condition);
  3319. $condition[] = ['id', 'in', $customerIdList];
  3320. }
  3321. //签单金额
  3322. if (!empty($param['qiandan_money'])) {
  3323. $sign_money = explode('-', $param['qiandan_money']);
  3324. if (empty($sign_money)) return json(['code' => 1, 'msg' => '参数错误']);
  3325. $customerIdList = Customer::where($condition)->column('id');
  3326. $logwhere[] = ['state', 'in', CustomerVisitLog::changeState('已签单', 'chaos')];
  3327. $logwhere[] = ['money', 'between', $sign_money];
  3328. $logwhere[] = ['customer_id', 'in', $customerIdList];
  3329. $customerIdList = CustomerVisitLog::where($logwhere)->group('customer_id')->column('customer_id');
  3330. unset($condition);
  3331. $condition[] = ['id', 'in', $customerIdList];
  3332. }
  3333. // 房屋面积
  3334. if (!empty($param['square'])) {
  3335. $square = explode(',', $param['square']);
  3336. $square_arr = [
  3337. 1 => '(square > 1 and square <= 80)',
  3338. 2 => '(square > 81 and square <= 100)',
  3339. 3 => '(square > 101 and square <= 120)',
  3340. 4 => '(square > 121 and square <= 200)',
  3341. 5 => '(square > 201 and square <= 500)',
  3342. 6 => '(square > 501 and square <= 10000)'
  3343. ];
  3344. $squ_whereOr = null;
  3345. foreach ($square as $k => $v) {
  3346. if (!empty($square_arr[$v])) $squ_whereOr .= $square_arr[$v] . ' OR';
  3347. }
  3348. $customersList = Customer::where($condition)->where(function ($query) use ($squ_whereOr) {
  3349. $query->whereRaw(trim($squ_whereOr, ' OR'));
  3350. })->order('addtime desc')->column('id');
  3351. unset($condition);
  3352. $condition[] = ['id', 'in', $customersList];
  3353. }
  3354. //未跟进天数
  3355. if (!empty($param['no_visit_day'])) {
  3356. $no_visit_day = explode(',', $param['no_visit_day']);
  3357. $all_no_visit = [
  3358. 1 => [3, 7],
  3359. 2 => [8, 14],
  3360. 3 => [15, 30],
  3361. 4 => [31, 10000]
  3362. ];
  3363. $customersList = Customer::where($condition)->order('addtime desc')->column('id,addtime');
  3364. $wg_where[] = ['customer_id', 'in', array_column($customersList, 'id')];
  3365. $latest_visit_log = CustomerVisitLog::where($wg_where)->group('customer_id')->column('max(addtime) as addtime', 'customer_id'); //->select()->toArray();
  3366. $no_visit_ids = [];
  3367. foreach ($customersList as $k => $v) {
  3368. if (empty($latest_visit_log[$v['id']])) {
  3369. $no_visit_long = ceil((time() - strtotime($v['addtime'])) / 86400);
  3370. } else {
  3371. $no_visit_long = ceil((time() - strtotime($latest_visit_log[$v['id']])) / 86400);
  3372. }
  3373. foreach ($no_visit_day as $m => $p) {
  3374. if (empty($all_no_visit[$p])) continue;
  3375. if ($no_visit_long >= $all_no_visit[$p][0] && $no_visit_long <= $all_no_visit[$p][1]) $no_visit_ids[] = $v['id'];
  3376. }
  3377. }
  3378. unset($condition);
  3379. $condition[] = ['id', 'in', $no_visit_ids];
  3380. }
  3381. if (!empty($param['state'])) {
  3382. $customerIdList = Customer::where($condition)->column('id');
  3383. $stateall = explode(',', $param['state']);
  3384. $allsta = [];
  3385. foreach ($stateall as $k => $v) {
  3386. if ($v == '已签单') $v = '已交定';
  3387. if ($v == '已转单') $v = '已签单';
  3388. if (in_array($v, ['待确认', '有效'])) continue;
  3389. $onestate = CustomerVisitLog::changeState($v, 'chaos');
  3390. $allsta = array_merge($onestate, $allsta);
  3391. }
  3392. $visit_where[] = ['customer_id', 'in', $customerIdList];
  3393. $visit_where[] = ['state', 'in', $allsta];
  3394. // $visit_where[] = ['addtime', '>', date('Y-m-d H:i:s', $startTime)];
  3395. // $visit_where[] = ['addtime', '<', date('Y-m-d H:i:s', $endTime)];
  3396. $logCustomersIdList = CustomerVisitLog::where($visit_where)->group('customer_id')->column('customer_id');
  3397. $c_ids = $logCustomersIdList;
  3398. foreach ($stateall as $k => $v) {
  3399. if ($v == '待确认') {
  3400. $confirmedids = Customer::where($condition)->where([['state', 'in', Customer::changeState('待确认', 'chaos')], ['crm_res_id', 'NULL', null]])->column('id');
  3401. }
  3402. if ($v == '有效') {
  3403. $validids = Customer::where($condition)->where('state', 'not in', Customer::changeState('待确认', 'chaos'))->column('id');
  3404. }
  3405. }
  3406. unset($condition);
  3407. if (!empty($confirmedids)) $c_ids = array_merge($confirmedids, $c_ids);
  3408. if (!empty($validids)) $c_ids = array_merge($validids, $c_ids);
  3409. unset($condition);
  3410. $condition[] = ['id', 'in', $c_ids];
  3411. }
  3412. $customers = Customer::with(['source' => function ($query) {
  3413. $query->field('id,source');
  3414. }, 'visitLog' => function ($query) {
  3415. $query->field('id,customer_id,state,addtime,confirm_date,money')->order('addtime asc');
  3416. }])->where($condition)->order('assign_time desc')->page($param['page'], $param['limit'])->select();
  3417. $count = Customer::where($condition)->count();
  3418. $data = $customers->toArray();
  3419. $pageIdList = array_column($data, 'id');
  3420. $employeeList = array_column($data, 'employee_id');
  3421. $designerList = array_column($data, 'designer_id');
  3422. $empIdList = array_merge($employeeList, $designerList, [$empid]);
  3423. $empList = Employee::where([['id', 'in', $empIdList]])->column('name,org_id', 'id');
  3424. $orgList = Org::where([['id', 'in', array_column($empList, 'org_id')]])->column('name', 'id');
  3425. // $customers = $customers->visible(['id', 'name', 'sex', 'level', 'community_name', 'state'])->toArray();
  3426. // 查询跟踪记录
  3427. //$depositVisitLog = CustomerVisitLog::where([CustomerVisitLog::changeState(['state', '=', '已交定']), ['customer_id', 'in', $pageIdList]])->group('customer_id')->column('count(id) as num', 'customer_id');
  3428. //$signVisitLog = CustomerVisitLog::where([CustomerVisitLog::changeState(['state', '=', '已签单']), ['customer_id', 'in', $pageIdList]])->group('customer_id')->column('count(id) as num', 'customer_id');
  3429. // 状态统计获取
  3430. $customerIdList = !empty($data) ? array_column($data, 'id') : [];
  3431. $customersStateList = CustomerVisitLog::where([['customer_id', 'in', $customerIdList]])->group('state,customer_id')->field('count(state) as num, state, customer_id')->select()->toArray();
  3432. $customersState = [];
  3433. $allstate = [];
  3434. foreach ($customersStateList as $s) {
  3435. if (!isset($customersState[$s['customer_id']]))
  3436. $customersState[$s['customer_id']] = ['count' => 0, 'shop' => 0, 'measure' => 0, 'activity' => 0, 'deposit' => 0, 'signed' => 0, 'allstate' => []];
  3437. $customersState[$s['customer_id']]['count'] += $s['num'];
  3438. // 到店,量房,活动,定金,签单
  3439. if ($s['state'] == '已到店') $customersState[$s['customer_id']]['shop'] += $s['num'];
  3440. elseif ($s['state'] == '已量房') $customersState[$s['customer_id']]['measure'] += $s['num'];
  3441. elseif ($s['state'] == '已到场') $customersState[$s['customer_id']]['activity'] += $s['num'];
  3442. elseif ($s['state'] == '已签单') {
  3443. $s['state'] = '已转单';
  3444. $customersState[$s['customer_id']]['signed'] += $s['num'];
  3445. } elseif ($s['state'] == '已交定') {
  3446. $s['state'] = '已签单';
  3447. $customersState[$s['customer_id']]['deposit'] += $s['num'];
  3448. } elseif ($s['state'] == '回访') $s['state'] = '待确认';
  3449. if (in_array($s['state'], ['回访', '待确认', '未到访', '已到店', '已量房', '已到场', '已交定', '已签单']) && !in_array($s['state'], $customersState[$s['customer_id']]['allstate'])) $customersState[$s['customer_id']]['allstate'][] = $s['state'];
  3450. }
  3451. $data = [];
  3452. // 指派类型
  3453. $assign_type_default['yixiang'] = '意向客戶指派';
  3454. $assign_type_default['liangfang'] = '量房客戶指派';
  3455. $assign_type_default['daodian'] = '到店客戶指派';
  3456. foreach ($customers->toArray() as $item) {
  3457. $daodian_time = $jiaoding_time = $jiaoding_money = $qiandan_time = $qiandan_money = $liangfang_time = $last_contact_date = '';
  3458. $state = [];
  3459. if (!empty($item['visitLog'])) {
  3460. $last_contact_date = !empty($item['visitLog'][count($item['visitLog']) - 1]['addtime']) ? $item['visitLog'][count($item['visitLog']) - 1]['addtime'] : '';
  3461. foreach ($item['visitLog'] as $k => $v) {
  3462. $state[$v['state']][] = $v;
  3463. }
  3464. foreach ($state as $k => $v) {
  3465. if ($k == '已交定') {
  3466. $jiaoding_time = date('Y-m-d', strtotime($v[0]['addtime']));
  3467. $jiaoding_money = $v[0]['money'];
  3468. }
  3469. if ($k == '已签单') {
  3470. $qiandan_time = date('Y-m-d', strtotime($v[0]['addtime']));
  3471. $qiandan_money = $v[0]['money'];
  3472. }
  3473. if ($k == '已量房') {
  3474. $liangfang_time = date('Y-m-d', strtotime($v[0]['addtime']));
  3475. }
  3476. if ($k == '已到店') $daodian_time = date('Y-m-d', strtotime($v[0]['addtime']));
  3477. }
  3478. }
  3479. $assignIdList = !empty($item['assigned_personnel']) ? explode(',', $item['assigned_personnel']) : [];
  3480. //$assignIdList[] = $item['employee_id']; // 所属销售
  3481. //$assignIdList[] = $item['designer_id']; // 指派的设计师
  3482. if (!empty($item['designer_id']) && !empty($assignIdList)) $assignIdList = array_diff($assignIdList, [$item['designer_id']]);
  3483. $assign_data = Employee::where('id', 'in', $assignIdList)->column('name,org_id');
  3484. $assign_list = !empty($assign_data) ? array_column($assign_data, 'name') : [];
  3485. $assign_org = Org::where([['id', 'in', array_column($assign_data, 'org_id')]])->group('id')->column('name');
  3486. $assign_type_name = '';
  3487. if ($item['assign_type']) {
  3488. if (isset($assign_type_default[$item['assign_type']])) {
  3489. $assign_type_name = $assign_type_default[$item['assign_type']];
  3490. }
  3491. }
  3492. $allstate = !empty($customersState[$item['id']]['allstate']) ? $customersState[$item['id']]['allstate'] : [];
  3493. if ($item['state'] != '待确认' && !empty($customersState[$item['id']]['allstate']) && count($customersState[$item['id']]['allstate']) > 1 && in_array('待确认', $customersState[$item['id']]['allstate'])) {
  3494. $allstate = array_diff($customersState[$item['id']]['allstate'], ['待确认']);
  3495. }
  3496. $no_visit_state = ['未到访', '待确认'];
  3497. $visit_state = ['已到店', '已量房', '已到场', '已签单', '已转单', '已卖卡'];
  3498. // 有'已到店', '已量房', '已到场'状态的话不显示未到访
  3499. $no_jiaoji = array_intersect($no_visit_state, $allstate);
  3500. if (count($no_jiaoji) == 2) { // 有未到访、待确认两个状态
  3501. $allstate = ['未到访'];
  3502. }
  3503. $jiaoji = array_intersect($visit_state, $allstate);
  3504. if (count($state) > 1 && count($jiaoji) > 0) {
  3505. $allstate = array_diff($allstate, $no_visit_state);
  3506. }
  3507. //if($item['state'] == '待确认') $allstate = [$item['state']];
  3508. $item['is_followup'] = 0;
  3509. if ($is_manager == 1 && empty($path)) {
  3510. $item['is_followup'] = 1;
  3511. }
  3512. if ($empid == $item['employee_id']) {
  3513. $item['is_followup'] = 1;
  3514. }
  3515. $data[] = [
  3516. 'id' => $item['id'],
  3517. 'name' => $item['name'],
  3518. 'sex' => $item['sex'],
  3519. 'source_name' => !empty($item['source']) ? $item['source']['source'] : '',
  3520. 'no_visit_day' => ceil((strtotime(date('Y-m-d')) - strtotime($last_contact_date)) / 86400) > 0 ? ceil((strtotime(date('Y-m-d')) - strtotime($last_contact_date)) / 86400) : 0,
  3521. 'org_id' => $item['org_id'],
  3522. 'level' => $item['level'],
  3523. 'phone' => substr_replace($item['phone'], '******', 3, 6),
  3524. 'community_name' => $item['community_name'],
  3525. 'state' => !empty($allstate) ? implode(',', $allstate) : '',
  3526. 'employee_name' => !empty($empList[$item['employee_id']]['name']) ? $empList[$item['employee_id']]['name'] : '',
  3527. 'employeeOrg' => [
  3528. 'name' => $orgList[$empList[$item['employee_id']]['org_id']]
  3529. ],
  3530. 'designer_name' => !empty($empList[$item['designer_id']]['name']) ? $empList[$item['designer_id']]['name'] : '',
  3531. 'designerOrg' => empty($item['designer_id']) ? null : [
  3532. 'name' => $orgList[$empList[$item['designer_id']]['org_id']]
  3533. ],
  3534. 'btn_type' => !empty($arr[$item['id']]) ? $arr[$item['id']] : 0, ////1到店,3量房
  3535. 'square' => !empty($item['square']) ? $item['square'] : '', //房屋面积
  3536. 'agents' => !empty($item['agents_id']) ? $item['agents_id'] : '', //是否是经纪人推荐的
  3537. 'stateNum' => !empty($customersState[$item['id']]) ? $customersState[$item['id']] : ['count' => 0, 'shop' => 0, 'measure' => 0, 'activity' => 0, 'deposit' => 0, 'signed' => 0],
  3538. 'assign_time' => !empty($item['assign_time']) ? $item['assign_time'] : '',
  3539. 'assign_list' => !empty($assign_list) ? implode(',', $assign_list) : '',
  3540. 'assign_org' => !empty($assign_org) ? implode(',', $assign_org) : '',
  3541. 'assign_type' => $item['assign_type'],
  3542. 'assigned_personnel' => $item['assigned_personnel'],
  3543. 'assign_type_name' => $assign_type_name,
  3544. 'allstate' => !empty($allstate) ? implode(',', $allstate) : '',
  3545. 'jiaoding_time' => !empty($jiaoding_time) ? $jiaoding_time : '',
  3546. 'jiaoding_money' => !empty($jiaoding_money) ? $jiaoding_money : '',
  3547. 'qiandan_time' => !empty($qiandan_time) ? $qiandan_time : '',
  3548. 'qiandan_money' => !empty($qiandan_money) ? $qiandan_money : '',
  3549. 'liangfang_time' => !empty($liangfang_time) ? $liangfang_time : '',
  3550. 'last_contact_date' => $last_contact_date,
  3551. 'is_followup' => $item['is_followup'],
  3552. 'daodian_time' => !empty($daodian_time) ? $daodian_time : '',
  3553. 'jiange_day' => ceil((strtotime(date('Y-m-d')) - strtotime($last_contact_date)) / 86400)
  3554. ];
  3555. }
  3556. return json(['code' => 0, 'data' => $data, 'count' => $count]);
  3557. }
  3558. }