CrmCustomer.php 298 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309
  1. <?php
  2. namespace app\api\controller;
  3. use app\logics\CustomerLogic;
  4. use app\logics\OrgLogic;
  5. use app\model\Community;
  6. use app\model\CrmImportLog;
  7. use app\model\Customer;
  8. use app\model\Company;
  9. use app\model\CustomerClue;
  10. use app\model\CustomerDropPool;
  11. use app\model\CustomerDropRecord;
  12. use app\model\CustomerRecycle;
  13. use app\model\CustomerSource;
  14. use app\model\CustomerVisitLog;
  15. use app\model\Decostyle;
  16. use app\model\Employee;
  17. use app\model\Org;
  18. use app\model\Product;
  19. use app\model\CustomerTop;
  20. use app\logics\EmployeeLogic;
  21. use app\model\Setting;
  22. use app\model\Shop;
  23. use app\model\WeworksingleCompanySetting;
  24. use app\model\WeworksingleCustomer;
  25. use think\facade\Db;
  26. use app\model\Activity;
  27. use app\model\User;
  28. use app\model\CustomerPortrait;
  29. use app\model\CreditsSetting;
  30. use app\model\AgentIntegral;
  31. use app\model\AgentUser;
  32. use app\model\AgentCustomerLog;
  33. use app\model\CustomerSmsLog;
  34. use app\model\CustomersSubscribe;
  35. use think\facade\Console;
  36. use app\model\PreformanceTasksOrg;
  37. use app\model\PreformanceTasks as PreformanceTasksModel;
  38. use app\model\ShortUrl;
  39. use Exception;
  40. use sms\ChuanglanSmsApi;
  41. use app\event\Msg;
  42. use app\model\CustomerNotVisit;
  43. use app\model\CustomerPackage;
  44. use app\model\EmployeeMsg;
  45. use app\model\Miniprogram;
  46. use app\model\CustomerPortraitField;
  47. use app\model\CustomerPortraitFieldSelect;
  48. use app\model\CustomerSharing;
  49. use app\model\Building;
  50. use think\facade\Cache;
  51. use think\facade\Log;
  52. use toolkits\Aec;
  53. use app\model\OutCallLog;
  54. use think\facade\Request;
  55. use app\model\CustomerWisdomImg;
  56. use app\model\OutCallSetting;
  57. use app\model\CustomerInvalidLog;
  58. use app\model\AgentType;
  59. use app\model\CustomerStateCheck;
  60. use wx\offiaccount\client\TmpMsg;
  61. use app\model\WechatActivityIntegral;
  62. class CrmCustomer extends Base
  63. {
  64. /**
  65. * 添加客户检测手机号的重复
  66. * 1.客户录入不和资源库和回收站排重 (创艺)
  67. * 2.客户录入需查询是否和公海重复,如重复,提示可以获取该客户 (创艺) 工单id6077
  68. */
  69. public function checkPepeat($pharr, $org_id, $employee_id, $id = null)
  70. {
  71. // 同部门能否重复录入开关设置
  72. $root_id = request()->token['root_org'];
  73. $empcrm_repeat[] = ['root_id', '=', $root_id];
  74. $empcrm_repeat[] = ['name', '=', 'empcrm_customer_repeat'];
  75. $repeat_setting = Setting::where($empcrm_repeat)->findOrEmpty();
  76. $emp_org = request()->token['org_id'];
  77. if ($id) {
  78. $this_customer = Customer::find($id);
  79. } else {
  80. $this_customer = null;
  81. }
  82. foreach ($pharr as $val) {
  83. if (empty($val)) continue;
  84. // 先判断公海 只有添加时候判断
  85. if (empty($id)) {
  86. $poolExist = Customer::where([
  87. ['phone|phone1|phone2', '=', cypherphone(trim($val))],
  88. ['org_id', '=', $emp_org],
  89. ['employee_id', 'null', null],
  90. ['is_resource', '=', 0]
  91. ])->column('id');
  92. if (!empty($poolExist)) {
  93. $poolCrmIdStr = implode(',', $poolExist);
  94. return json(['code' => 3, 'data' => $poolCrmIdStr, 'msg' => '录入失败:客户信息已在公海中。']);
  95. }
  96. }
  97. // 新建档,检测手机号是否重复
  98. $customerExist = Customer::where([
  99. ['phone|phone1|phone2', '=', cypherphone(trim($val))],
  100. ['org_id', 'in', $org_id],
  101. ['employee_id', '>', 0] // 员工客户
  102. ])->where(
  103. function ($query) {
  104. $not_sure = Customer::changeState('待确认', 'chaos');
  105. $or1[] = ['crm_res_id', 'null', null];
  106. $or2[] = ['crm_res_id', '>', 0];
  107. $or2[] = ['state', 'not in', $not_sure];
  108. $query->whereOr([$or1, $or2]);
  109. }
  110. )->field('id,employee_id,is_resource,org_id,source_id')->select()->toArray();
  111. $id_arr = array_column($customerExist, 'id');
  112. $employee_id_arr = array_column($customerExist, 'employee_id');
  113. if (empty($id)) {
  114. // 对非当前业务员名下重复客户不在判断
  115. if (in_array($employee_id, $employee_id_arr)) {
  116. // 是否已存在为自己的客户
  117. return json(['code' => 2, 'msg' => '录入失败。' . $val . '已经是您的客户。']);
  118. }
  119. } else {
  120. if (!in_array($id, $id_arr) && in_array($employee_id, $employee_id_arr)) {
  121. // 是否已存在为自己的客户
  122. return json(['code' => 2, 'msg' => '录入失败。' . $val . '已经是您的客户。']);
  123. }
  124. }
  125. //判断同部门
  126. if (empty($id)) { // 添加时候按员工所属部门判断
  127. if (!$repeat_setting->isEmpty()) {
  128. $repeat_org = explode(',', $repeat_setting['content']);
  129. if (!in_array($emp_org, $repeat_org)) { // 不属于判重部门
  130. $repeat_org = [$emp_org]; // 判断自身部门
  131. }
  132. } else {
  133. $repeat_org = [$emp_org]; // 判断自身部门
  134. }
  135. } else { // 编辑时候按客户所属部门判断
  136. if (!$repeat_setting->isEmpty()) {
  137. $repeat_org = explode(',', $repeat_setting['content']);
  138. if (!in_array($this_customer['org_id'], $repeat_org)) {
  139. $repeat_org = [$this_customer['org_id']];
  140. }
  141. } else {
  142. $repeat_org = [$this_customer['org_id']];
  143. }
  144. }
  145. // 需要验证
  146. if (!empty($customerExist)) {
  147. foreach ($customerExist as $ex) {
  148. if (in_array($ex['org_id'], $repeat_org) && $ex['employee_id'] != $employee_id) {
  149. //查询撞单客户渠道
  150. $source_name = '';
  151. if ($ex['source_id']) {
  152. $source = CustomerSource::where(['id' => $ex['source_id']])->value('source');
  153. $source_name = $source . '渠道客户';
  154. }
  155. // 为了避免开启撞单之前都已经重复的情况,所以要查一下这个id的现数据
  156. if ($id) {
  157. if ($this_customer) {
  158. $this_customer_phone = array_filter([$this_customer['phone'], $this_customer['phone1'], $this_customer['phone2']]);
  159. if (!in_array($val, $this_customer_phone)) { // 不是原来的客户手机号,编辑时候判断撞单
  160. $have_emp = Employee::where('id', '=', $ex['employee_id'])->value('name');
  161. return json(['code' => 2, 'msg' => '该客户与员工' . $have_emp . $source_name . '撞单,无法录入']);
  162. }
  163. }
  164. } else {
  165. $have_emp = Employee::where('id', '=', $ex['employee_id'])->value('name');
  166. return json(['code' => 2, 'msg' => '该客户与员工' . $have_emp . $source_name . '撞单,无法录入']);
  167. }
  168. }
  169. }
  170. }
  171. }
  172. }
  173. /**
  174. * 客户建档
  175. */
  176. public function add()
  177. {
  178. $token = $this->request->token;
  179. $data = $this->request->only(['ext', 'name', 'phone', 'sex', 'level', 'state', 'last_contact_date' => date('Y-m-d'), 'product', 'source_id', 'deposit_money' => null, 'signed_money' => null, 'external_userid', 'phone1', 'phone2', 'agents_id']);
  180. // $data['employee_id'] = $token['employee_id'];
  181. // $data['org_id'] = $token['org_id'];
  182. $id = $this->request->param('id');
  183. $aid = $this->request->param('aid') ?: 0; //状态为预约活动时预约的活动id
  184. $activity_id = $this->request->param('activity_id') ?: 0; //从活动邀约列表进入客户详情 活动id
  185. //在活动列表中编辑客户信息
  186. if ($id && $activity_id) {
  187. $aw[] = ['customer_id', '=', $id];
  188. $aw[] = ['aid', '>', 0];
  189. $aw[] = CustomerVisitLog::changeState(['state', '=', '交定']);
  190. $info = CustomerVisitLog::with(['activity' => function ($query) {
  191. $query->visible(['title']);
  192. }])->where($aw)->find();
  193. if ($info && isset($info['activity']['title']) && $info['activity']['title'] && $activity_id != $info['aid']) {
  194. return json(['code' => 1, 'msg' => '客户已经在《' . $info['activity']['title'] . '》活动中交定,请在此活动中修改状态']);
  195. }
  196. }
  197. $clueId = $this->request->param('clue_id');
  198. $customer = new Customer();
  199. // 添加客户需要查询所有部门id;
  200. // 设计师能否报备、获取客户
  201. if (empty($id)) {
  202. $de_where[] = ['root_id', '=', $token['root_org']];
  203. $de_where[] = ['name', '=', 'designer_get_customer'];
  204. $info_de_where = Setting::where($de_where)->findOrEmpty();
  205. if (!$info_de_where->isEmpty() && $token['org_type'] == 2) {
  206. if ((int)$info_de_where['content'] != 1) {
  207. return json(['code' => 1, 'msg' => '您的身份为设计师,无法报备客户']);
  208. }
  209. }
  210. }
  211. if (!empty($data['phone']) && !empty($data['phone1']) && $data['phone'] == $data['phone1']) {
  212. return json(['code' => 1, 'msg' => '手机号不能重复']);
  213. }
  214. if (!empty($data['phone1']) && !empty($data['phone2']) && $data['phone1'] == $data['phone2']) {
  215. return json(['code' => 1, 'msg' => '手机号不能重复']);
  216. }
  217. if (!empty($data['phone']) && !empty($data['phone2']) && $data['phone'] == $data['phone2']) {
  218. return json(['code' => 1, 'msg' => '手机号不能重复']);
  219. }
  220. $orgids = orgSubIds($token['root_org']);
  221. $pharr = [
  222. $data['phone'],
  223. !empty($data['phone1']) ? $data['phone1'] : '',
  224. !empty($data['phone2']) ? $data['phone2'] : ''
  225. ];
  226. //判断手机号是否在公海,资源库,已建档,回收站
  227. if (!$id) {
  228. $tips = $this->checkPepeat($pharr, $orgids, $token['employee_id']);
  229. if (!empty($tips)) return $tips;
  230. } else {
  231. $tips = $this->checkPepeat($pharr, $orgids, $token['employee_id'], $id);
  232. if (!empty($tips)) return $tips;
  233. }
  234. if ($id) {
  235. $sub_org = orgSubIds($token['org_id']);
  236. $sub_employee = Employee::where([['org_id', 'in', $sub_org], ['state', '=', '在职'], ['uid', '>', 0]])->column('id');
  237. $where_c1[] = ['id', '=', $id];
  238. $orgids = orgSubIds($token['root_org']);
  239. $where_c1[] = ['org_id', 'in', $orgids];
  240. //$where_c1[] = ['employee_id|designer_id', 'in', $sub_employee];
  241. $customer = Customer::where($where_c1)->where(function ($query) use ($sub_employee) {
  242. foreach ($sub_employee as $v) {
  243. $query->whereOr([['employee_id|designer_id|assigned_personnel', 'find in set', $v]]);
  244. }
  245. })->find();
  246. if (empty($customer)) return json(['code' => 1, 'msg' => '数据不存在']);
  247. //记录修改客户基本信息
  248. $this->cusbasic_field_savelog($data, $customer);
  249. if (!empty($data['state'])) {
  250. $state = Customer::changeState($data['state']);
  251. if (empty($state)) unset($data['state']);
  252. else $data['state'] = $state;
  253. }
  254. } elseif ($clueId) { // 如果是线索跳转建档
  255. $clue = CustomerClue::where([['id', '=', $clueId], ['employee_id', '=', $token['employee_id']]])->find();
  256. if (empty($clue)) return json(['code' => 1, 'msg' => '线索不存在']);
  257. if ($clue->state == 1) return json(['code' => 1, 'msg' => '线索已建档']);
  258. // 检测线索是否已经被其他同事建档过
  259. /* $exist = CustomerClue::where([
  260. ['org_id', 'in', $orgids],
  261. ['uid', '=', $clue->uid],
  262. ['state', '=', 1],
  263. ['id', '<>', $clueId]
  264. ])->find();
  265. if ($exist)
  266. return json(['code' => 1, 'msg' => '建档失败,线索已被其他员工先行建档']); */
  267. // 添加数据
  268. $data['clue_id'] = $clue->id;
  269. $data['uid'] = $clue->uid;
  270. $data['employee_id'] = $token['employee_id'];
  271. $data['org_id'] = $token['org_id'];
  272. $data['agents_id'] = $clue->agent_id ?? NULL; //如果线索是经纪人端获取的记录
  273. $state = Customer::changeState('待确认');
  274. $data['state'] = $state;
  275. $clue->state = 1;
  276. } else {
  277. $data['employee_id'] = $token['employee_id'];
  278. $data['org_id'] = $token['org_id'];
  279. $state = Customer::changeState('待确认');
  280. $data['state'] = $state;
  281. }
  282. Db::startTrans();
  283. try {
  284. if (isset($clue)) $clue->save();
  285. $old_data = $data;
  286. $data = array_filter($data);
  287. if (isset($old_data['phone1'])) $data['phone1'] = $old_data['phone1'];
  288. if (isset($old_data['phone2'])) $data['phone2'] = $old_data['phone2'];
  289. if ($aid) $data['aid'] = $aid;
  290. $customer->save($data);
  291. // 更新客户保护期
  292. if (!$id) {
  293. $customer->save(['employee_time' => date('Y-m-d H:i:s')]); //保存员工获取客户时间
  294. Customer::changeProtectedTo($customer->id, $token['root_org']);
  295. }
  296. // -------------------- 企业微信逻辑相关 start -----------------
  297. // 如果有外部联系人id,说明是企业微信端添加的客户
  298. if (!empty($data['external_userid'])) {
  299. $external_where['external_userid'] = $data['external_userid'];
  300. $external_where['employee_id'] = $this->request->token['employee_id'];
  301. $external_find = WeworksingleCustomer::where($external_where)->find();
  302. if (empty($external_find)) {
  303. Db::rollback();
  304. return json(['code' => 1, 'msg' => '外部联系人不存在']);
  305. } else {
  306. if (!empty($external_find['customer_id']) && $external_find['customer_id'] != 0) {
  307. Db::rollback();
  308. return json(['code' => 1, 'msg' => '该外部联系人已绑定客户']);
  309. }
  310. }
  311. WeworksingleCustomer::where($external_where)->save(['customer_id' => $customer->id]);
  312. }
  313. // -------------------- 企业微信逻辑相关 end -----------------
  314. //建档后添加一条跟进记录
  315. if (empty($id)) $this->addFirstCustoemrVisitLog($customer->id, $clueId);
  316. Db::commit();
  317. } catch (\Exception $e) {
  318. Db::rollback();
  319. return json(['code' => 1, 'msg' => $e->getMessage()]);
  320. }
  321. // 发送管理层模板消息
  322. $data['name'] = !empty($data['name']) ? $data['name'] : '';
  323. $data['phone'] = substr_replace($data['phone'], '******', 3, 6);
  324. $msg = ['first' => '行为通知', 'keyword1' => '客户信息编辑', 'keyword2' => "员工" . $token['name'] . "对客户" . $data['name'] . "(" . $data['phone'] . ")信息编辑", 'keyword3' => date('Y/m/d'), 'remark' => '请悉知'];
  325. TmpMsg::sendMsgToLeader($msg, $token['org_id']);
  326. return json(['code' => 0, 'data' => $customer->id, 'msg' => '添加成功']);
  327. }
  328. /**
  329. * 编辑部分字段
  330. */
  331. public function edit()
  332. {
  333. $id = input('id', '', 'intval');
  334. $param = request()->post();
  335. $token = request()->token;
  336. $customer = Customer::find($id);
  337. if (empty($customer)) {
  338. return json(['code' => 1, 'msg' => '数据不存在']);
  339. }
  340. $sub_org = orgSubIds(request()->token['root_org']);
  341. if (!in_array($customer['org_id'], $sub_org)) {
  342. return json(['code' => 1, 'msg' => '数据不存在']);
  343. }
  344. //记录修改客户基本信息
  345. $this->cusbasic_field_savelog($param, $customer);
  346. $orgids = orgSubIds($token['root_org']);
  347. $pharr = [
  348. !empty($param['phone']) ? $param['phone'] : '',
  349. !empty($param['phone1']) ? $param['phone1'] : '',
  350. !empty($param['phone2']) ? $param['phone2'] : ''
  351. ];
  352. $pharr = array_filter($pharr);
  353. if (!empty($pharr)) {
  354. $repeat = [];
  355. foreach ($pharr as $key => $val) {
  356. if (empty($val)) continue;
  357. if (!in_array($val, $repeat)) {
  358. $repeat[] = $val;
  359. } else {
  360. return json(['code' => 1, 'msg' => '手机号不能重复']);
  361. }
  362. }
  363. //判断手机号是否在公海,资源库,已建档,回收站
  364. $tips = $this->checkPepeat($pharr, $orgids, $token['employee_id'], $id);
  365. if (!empty($tips)) return $tips;
  366. }
  367. $result = $customer->save($param);
  368. if ($result) {
  369. // 发送管理层模板消息
  370. $customer['name'] = !empty($customer['name']) ? $customer['name'] : '';
  371. $customer['phone'] = substr_replace($customer['phone'], '******', 3, 6);
  372. $msg = ['first' => '行为通知', 'keyword1' => '客户信息编辑', 'keyword2' => "员工" . $token['name'] . "对客户" . $customer['name'] . "(" . $customer['phone'] . ")信息编辑", 'keyword3' => date('Y/m/d'), 'remark' => '请悉知'];
  373. TmpMsg::sendMsgToLeader($msg, $token['org_id']);
  374. return json(['code' => 0, 'msg' => '操作成功']);
  375. } else {
  376. return json(['code' => 1, 'msg' => '操作失败']);
  377. }
  378. }
  379. /**
  380. * 记录客户基本信息的修改
  381. */
  382. public function cusbasic_field_savelog($param, $customer)
  383. {
  384. $token = request()->token;
  385. $baskey = ['name', 'phone', 'level', 'sex'];
  386. $basdata = CustomerPortraitField::with(['select'])->where([['root_id', '=', request()->token['root_org']], ['keyname', 'in', $baskey]])->select()->toArray();
  387. $yes_save = [];
  388. foreach ($param as $key => $val) {
  389. if (in_array($key, $baskey) && $val != $customer[$key]) {
  390. if ($key == 'sex') {
  391. $val = $val == 1 ? '男' : '女';
  392. }
  393. $yes_save[] = ['keyname' => $key, 'value' => $val];
  394. }
  395. }
  396. if (!empty($yes_save)) {
  397. foreach ($yes_save as $key => $val) {
  398. foreach ($basdata as $k => $v) {
  399. if ($v['keyname'] == $val['keyname']) {
  400. $yes_save[$key]['id'] = $v['id'];
  401. $yes_save[$key]['name'] = $v['name'];
  402. $yes_save[$key]['type'] = $v['type'];
  403. $yes_save[$key]['valname'] = $val['value'];
  404. }
  405. }
  406. }
  407. // 添加追踪记录
  408. $visitLog = [
  409. 'customer_id' => $customer->id,
  410. 'type' => 1,
  411. 'next_contact_date' => null,
  412. 'employee_id' => $token['employee_id'],
  413. 'user_id' => $token['uid'],
  414. 'remark' => '修改客户基本信息',
  415. 'state' => 1,
  416. 'org_id' => $token['org_id'],
  417. 'customer_employee_id' => $customer->employee_id,
  418. 'customer_org_id' => Employee::where('id', $customer->employee_id)->value('org_id'),
  419. 'save_portrait_field' => json_encode($yes_save),
  420. 'down_portrait_field_status' => 0
  421. ];
  422. // var_dump($visitLog);
  423. // exit;
  424. CustomerVisitLog::create($visitLog);
  425. }
  426. }
  427. /**
  428. * 新建客户时添加一条跟进记录
  429. * $id 客户id
  430. */
  431. public function addFirstCustoemrVisitLog($id, $source = '')
  432. {
  433. $token = $this->request->token;
  434. $name = Employee::where('id', $token['employee_id'])->value('name');
  435. $cname = Customer::where('id', $id)->value('name');
  436. // $type = $source ? '建档' : '报备';
  437. $type = '报备';
  438. $remark = '业务员' . $name . '对客户' . $cname . '进行' . $type;
  439. $save = [
  440. 'customer_id' => $id,
  441. 'type' => '',
  442. 'next_contact_date' => date('Y-m-d'),
  443. 'remark' => $remark,
  444. 'addtime' => date('Y-m-d H:i:s'),
  445. 'employee_id' => $token['employee_id'],
  446. 'user_id' => $token['uid'],
  447. 'state' => 1,
  448. 'org_id' => $token['org_id'],
  449. 'customer_employee_id' => $token['employee_id'],
  450. 'customer_org_id' => $token['org_id']
  451. ];
  452. CustomerVisitLog::insertGetId($save);
  453. return true;
  454. }
  455. /**
  456. * 经纪人送积分功能
  457. */
  458. public function agents_integral($agentid, $state, $customer_id, $state_type, $money, $state_type_num)
  459. {
  460. $token = $this->request->token;
  461. $agent_data = AgentUser::where([['id', '=', $agentid], ['root_id', '=', $token['root_org']]])->field('agent_name,type')->find();
  462. if ($state == '已到店') {
  463. $code = 'daodian_integral';
  464. $sta_type = 1;
  465. }
  466. if ($state == '已交定') {
  467. $code = 'jiaoding_integral';
  468. $sta_type = 2;
  469. }
  470. if ($state == '已签单') {
  471. $code = 'qiandan_integral';
  472. $sta_type = 3;
  473. }
  474. if ($state == '已量房') {
  475. $code = 'measuring_integral';
  476. $sta_type = 4;
  477. }
  478. if ($state_type . $state == '套房已量房') {
  479. $code = 'measuring_suite_integral';
  480. $sta_type = 4;
  481. }
  482. if ($state_type . $state == '别墅已量房') {
  483. $code = 'measuring_villa_integral';
  484. $sta_type = 4;
  485. }
  486. //添加与经纪人相关记录
  487. $you = AgentCustomerLog::where([['agent_id', '=', $agentid], ['type', '=', $sta_type], ['customer_id', '=', $customer_id]])->count();
  488. if (empty($you)) {
  489. $add = array(
  490. 'agent_id' => $agentid,
  491. 'type' => $sta_type,
  492. 'typename' => $state,
  493. 'addtime' => time(),
  494. 'customer_id' => $customer_id,
  495. 'agent_type' => $agent_data['type'],
  496. 'status' => 1
  497. );
  498. AgentCustomerLog::insert($add);
  499. }
  500. $rule = AgentType::where([['root_id', '=', $token['root_org']], ['id', '=', $agent_data['type']]])->find();
  501. $rule_list = !empty($rule['count']) ? json_decode($rule['count'], true) : '';
  502. $jifen = !empty($rule_list) ? (isset($rule_list[$code]) ? $rule_list[$code] : 0) : 0;
  503. if ($jifen == 0 && $state == '已签单' && $money > 0 && !empty($rule_list)) {
  504. if (isset($rule_list['qiandan_money_integral']) && $rule_list['qiandan_money_integral'] > 0 && isset($rule_list['qiandan_scale_integral']) && $rule_list['qiandan_scale_integral'] > 0) {
  505. $jifen = intval($money / $rule_list['qiandan_money_integral']) * $rule_list['qiandan_scale_integral'];
  506. }
  507. }
  508. //$jifen = CreditsSetting::where(['code' => $code, 'root_id' => $token['root_org']])->value('value');
  509. $ye = AgentIntegral::where(['customer_id' => $customer_id, 'agent_id' => $agentid])->column('state');
  510. //if (!in_array($state, $ye) && $agent_data['type'] == 1) {
  511. if (!in_array($state, $ye)) {
  512. $add = array(
  513. 'agent_id' => $agentid,
  514. 'type' => $sta_type,
  515. 'integral' => $jifen,
  516. 'addtime' => time(),
  517. 'state' => $state,
  518. 'customer_id' => $customer_id
  519. );
  520. AgentIntegral::insert($add);
  521. }
  522. if ($state == '已交定' && !in_array('已到店', $ye)) {
  523. $jifen = !empty($rule_list) ? $rule_list['daodian_integral'] : 0;
  524. //$jifen = CreditsSetting::where(['code' => 'daodian_integral', 'root_id' => $token['root_org']])->value('value');
  525. $add = array(
  526. 'agent_id' => $agentid,
  527. 'type' => 1,
  528. 'integral' => $jifen,
  529. 'addtime' => time(),
  530. 'state' => '已到店',
  531. 'customer_id' => $customer_id
  532. );
  533. AgentIntegral::insert($add);
  534. }
  535. if ($state == '已签单' && !in_array('已到店', $ye)) {
  536. $jifen = !empty($rule_list) ? $rule_list['daodian_integral'] : 0;
  537. //$jifen = CreditsSetting::where(['code' => 'daodian_integral', 'root_id' => $token['root_org']])->value('value');
  538. $add = array(
  539. 'agent_id' => $agentid,
  540. 'type' => 1,
  541. 'integral' => $jifen,
  542. 'addtime' => time(),
  543. 'state' => '已到店',
  544. 'customer_id' => $customer_id
  545. );
  546. AgentIntegral::insert($add);
  547. }
  548. if ($state == '已签单' && !in_array('已交定', $ye)) {
  549. $jifen = !empty($rule_list) ? $rule_list['jiaoding_integral'] : 0;
  550. //$jifen = CreditsSetting::where(['code' => 'jiaoding_integral', 'root_id' => $token['root_org']])->value('value');
  551. $add = array(
  552. 'agent_id' => $agentid,
  553. 'type' => 2,
  554. 'integral' => $jifen,
  555. 'addtime' => time(),
  556. 'state' => '已交定',
  557. 'customer_id' => $customer_id
  558. );
  559. AgentIntegral::insert($add);
  560. }
  561. }
  562. /**
  563. * 客户扩展字段添加
  564. */
  565. public function customerExt($id, array $ext)
  566. {
  567. Db::startTrans();
  568. try {
  569. $customer = Customer::where(['id' => $id, 'employee_id' => $this->request->token['employee_id']])->lock(true)->find();
  570. if (empty($customer)) return json(['code' => 1, 'msg' => '客户不存在']);
  571. // $customer->ext = NULL;
  572. // $customer->save();
  573. $customer->ext = $ext;
  574. $customer->save();
  575. Db::commit();
  576. } catch (\Exception $e) {
  577. Db::rollback();
  578. return json(['code' => 1, 'msg' => $e->getMessage()]);
  579. }
  580. return json(['code' => 0, 'msg' => '保存成功']);
  581. }
  582. /**
  583. * 设计师指定
  584. * 2022-11-08 业务修改, 指派设计师改为指派人员 并且可以指派多人
  585. * $id 客户id
  586. * $designerId 指派的人员 1,2,3,4 //为空取消指派人员
  587. */
  588. public function reserveDesigner($id, $designerId)
  589. {
  590. if (isset($this->request->token['isManager']) && $this->request->token['isManager']) {
  591. //修改指派逻辑,只要是管理层能看到的客户都可以指派
  592. $orgids = orgSubIds($this->request->token['root_org']);
  593. $condition[] = ['org_id', 'in', $orgids];
  594. $condition[] = ['id', '=', $id];
  595. $customer = Customer::where($condition)->find();
  596. // if ($this->request->token['org_type'] == 2) {
  597. // $sub_org = orgSubIds($this->request->token['org_id']);
  598. // $sub_employee = Employee::where([['org_id', 'in', $sub_org], ['state', '=', '在职'], ['uid', '<>', 0]])->column('id');
  599. // $customer = Customer::where([['id', '=', $id], ['designer_id', 'in', $sub_employee]])->find();
  600. // } else {
  601. // $customer = Customer::where([['id', '=', $id], ['org_id', 'in', orgSubIds($this->request->token['org_id'])]])->find();
  602. // }
  603. } else {
  604. $customer = Customer::where(['id' => $id, 'employee_id' => $this->request->token['employee_id']])->find();
  605. }
  606. if (empty($customer)) return json(['code' => 1, 'msg' => '您无权限指派此客户']);
  607. $old_customer = $customer->toArray();
  608. $is_designer_manager = input('designer_manager', 0, 'intval');
  609. if (empty($designerId)) {
  610. if ($is_designer_manager) {
  611. $customer->designer_id = NULL;
  612. } else {
  613. $customer->designer_id = NULL;
  614. $customer->assigned_personnel = NULL;
  615. }
  616. $customer->save();
  617. return json(['code' => 0, 'msg' => '取消指派成功!']);
  618. }
  619. $designerId = explode(',', $designerId);
  620. if (in_array($old_customer['employee_id'], $designerId)) {
  621. return json(['code' => 1, 'msg' => '该员工名下已有该客户', 'data' => []]);
  622. }
  623. $designer = Employee::where([
  624. ['id', 'in', $designerId], ['root_id', '=', $this->request->token['root_org']], ['state', '=', '在职']
  625. ])->column('org_id', 'id');
  626. if (empty($designer)) return json(['code' => 1, 'msg' => '指派人员不存在']);
  627. $orgs = Org::where([['id', 'in', array_values($designer)]])->column('org_type', 'id');
  628. //第一个选择的设计师
  629. $selectDesigner = [];
  630. foreach ($designerId as $k => $v) {
  631. if (empty($designer[$v]) || $orgs[$designer[$v]] !== 2) continue;
  632. $selectDesigner[] = $v;
  633. }
  634. if (count($selectDesigner) > 1) {
  635. return json(['code' => self::error_msg, 'msg' => '最多只能指派一名设计师']);
  636. }
  637. $designer_id = isset($selectDesigner[0]) ? $selectDesigner[0] : null;
  638. // 检测是否有设计师已指派满了
  639. $limitNum = Setting::where(['root_id' => $this->request->token['root_org'], 'name' => 'designerNum'])->value('content');
  640. if ($limitNum != 0) {
  641. //获取当月时间跨度
  642. $start_time = date('Y-m') . '-01 00:00:00';
  643. $end_time = date('Y-m-d', strtotime("$start_time +1 month -1 day")) . ' 23:59:59';
  644. $where[] = ['addtime', 'between', [strtotime($start_time), strtotime($end_time)]];
  645. $where[] = ['employee_id', 'in', $selectDesigner];
  646. $had = CustomerSharing::field('employee_id,count(customer_id) as num')->group('employee_id')->where($where)->having("num >= $limitNum")->select();
  647. // var_dump($had->toArray());
  648. // exit;
  649. if (!$had->isEmpty()) return json(['code' => 1, 'msg' => '指派的设计师已无指派名额,请刷新后再试']);
  650. }
  651. // 检测部门是否是设计师
  652. // $orgType = Org::where(['id' => $designer->org_id])->value('org_type');
  653. // if ($orgType != 2) return json(['code' => 1, 'msg' => '设计师不存在']);
  654. $customer->designer_id = $designer_id;
  655. if (!$is_designer_manager) {
  656. $customer->assigned_personnel = implode(',', array_keys($designer));
  657. }
  658. $customer->assign_time = date('Y-m-d H:i:s'); //增加记录指派时间
  659. // 指派类型
  660. $assign_type = input('assign_type', '', 'trim');
  661. if ($assign_type && empty($old_customer['assign_type'])) {
  662. $customer->assign_type = $assign_type;
  663. }
  664. $customer->save();
  665. $assign_type_default['yixiang'] = '[意向客户指派]';
  666. $assign_type_default['liangfang'] = '[量房客户指派]';
  667. $assign_type_default['daodian'] = '[到店客户指派]';
  668. $assign_type_string = $assign_type_default[$customer['assign_type']] ?? '';
  669. $remark_employee_name = Employee::where('id', 'in', array_keys($designer))->column('name');
  670. $remark = $assign_type_string . '指派至员工' . implode(',', $remark_employee_name);
  671. $visit_Log = [
  672. 'customer_id' => $id,
  673. 'type' => '',
  674. 'remark' => $remark,
  675. 'employee_id' => $this->request->token['employee_id'],
  676. 'user_id' => $this->request->token['uid'],
  677. 'state' => 1,
  678. ];
  679. CustomerVisitLog::create($visit_Log);
  680. // 发提醒
  681. $old_assign = $old_customer['assigned_personnel'];
  682. if (empty($old_assign)) { // 之前未指派,新指派人员
  683. $msg_employee = array_keys($designer);
  684. } else {
  685. $msg_employee = array_diff(array_keys($designer), explode(',', $old_assign));
  686. }
  687. $employee_name = Employee::where('id', '=', request()->token['employee_id'])->value('name');
  688. foreach ($msg_employee as $k => $v) {
  689. $msg = '员工' . $employee_name . '指派给你一个客户:' . ($old_customer['name'] ? $old_customer['name'] : '未知');
  690. event(new Msg($v, $msg, 'customerAssign', $id));
  691. }
  692. // 更新预约未确定的客户所属设计师id
  693. CustomersSubscribe::where(['customer_id' => $customer->id, 'state' => 0])->update(['designer_id' => $designer_id]);
  694. return json(['code' => 0, 'msg' => '指派成功!']);
  695. }
  696. /**
  697. * 产品(关注点)
  698. */
  699. public function product()
  700. {
  701. $data = Product::field('id,product')->where('root_id', request()->token['root_org'])->column('product');
  702. return json(['code' => 0, 'data' => $data]);
  703. }
  704. /**
  705. * 来源
  706. */
  707. public function source()
  708. {
  709. $data = CustomerSource::field('id,source')->where('root_id', request()->token['root_org'])->select();
  710. return json(['code' => 0, 'data' => $data]);
  711. }
  712. public function count()
  713. {
  714. $token = request()->token;
  715. $param = request()->only([
  716. 'type' => '',
  717. 'start_date' => '',
  718. 'end_date' => '',
  719. 'date' => ''
  720. ]);
  721. if ($param['date']) {
  722. $date_arr = $this->getDate($param['date']);
  723. if (!$date_arr) {
  724. $date_s = '2018-01-01 00:00:00';
  725. $date_e = date('Y-m-d H:i:s');
  726. $date_arr = [$date_s, $date_e];
  727. }
  728. } elseif ($param['start_date'] && $param['start_date']) {
  729. $startTime = strtotime($param['start_date']);
  730. $endTime = strtotime($param['end_date']);
  731. $start_date = date('Y-m-d 00:00:00', $startTime);
  732. $end_date = date('Y-m-d 23:59:59', $endTime);
  733. $date_arr = [$start_date, $end_date];
  734. } else {
  735. $date_s = '2018-01-01 00:00:00';
  736. $date_e = date('Y-m-d H:i:s');
  737. $date_arr = [$date_s, $date_e];
  738. }
  739. $c_where[] = ['sign_time', 'between', $date_arr]; //客户的条件
  740. $c_where[] = ['employee_id', '=', $token['employee_id']];
  741. $c_where[] = ['state', 'not in', Customer::changeState('无效', 'chaos')];
  742. $c_where[] = ['died', '<>', 2];
  743. $countor1[] = ['crm_res_id', 'NULL', null];
  744. $countor2[] = ['crm_res_id', 'NOTNULL', null];
  745. $countor2[] = ['state', 'not in', Customer::changeState('待确认', 'chaos')];
  746. $countor3[] = ['crm_res_id', 'NOTNULL', null];
  747. $countor3[] = ['state', 'in', Customer::changeState('待确认', 'chaos')];
  748. $countor3[] = ['valid_time', 'NOTNULL', null];
  749. $customer_count = Customer::where($c_where)->where(function ($query) use ($countor1, $countor2, $countor3) {
  750. $query->whereOr([$countor1, $countor2, $countor3]);
  751. })->count();
  752. $jv_where[] = ['add_wechat_time', 'between', $date_arr]; // 加微的条件
  753. $jv_where[] = ['employee_id', '=', $token['employee_id']];
  754. $jv_where[] = ['state', 'not in', Customer::changeState('无效', 'chaos')];
  755. $jv_where[] = ['died', '<>', 2];
  756. $jiav_count = Customer::where($jv_where)->where(function ($query) use ($countor1, $countor2) {
  757. $query->whereOr([$countor1, $countor2]);
  758. })->count();
  759. $s_where[] = ['CustomersSubscribe.addtime', 'between', $date_arr]; //预约的条件
  760. $s_where[] = ['CustomersSubscribe.state', '=', 0];
  761. $s_where[] = ['Customer.employee_id', '=', $token['employee_id']];
  762. $s_where[] = ['Customer.state', 'not in', Customer::changeState('无效', 'chaos')];
  763. $s_where[] = ['Customer.died', '<>', 2];
  764. $customer_subscribe = Db::view('Customer', 'id')
  765. ->view('CustomersSubscribe', 'id sid,state,type', 'Customer.id=CustomersSubscribe.customer_id')
  766. ->where($s_where)
  767. ->where(function ($query) {
  768. $countor1[] = ['Customer.crm_res_id', 'NULL', null];
  769. $countor2[] = ['Customer.crm_res_id', 'NOTNULL', null];
  770. $countor2[] = ['Customer.state', 'not in', Customer::changeState('待确认', 'chaos')];
  771. $query->whereOr([$countor1, $countor2]);
  772. })
  773. ->select()
  774. ->toArray();
  775. $subscribe_lf = [];
  776. $subscribe_dd = [];
  777. foreach ($customer_subscribe as $k => $v) {
  778. if ((int)$v['state'] == 3 && !in_array($v['id'], $subscribe_lf)) {
  779. $subscribe_lf[] = $v['id'];
  780. }
  781. if ((int)$v['state'] == 1 && !in_array($v['id'], $subscribe_dd)) {
  782. $subscribe_dd[] = $v['id'];
  783. }
  784. }
  785. //确认数量
  786. $state1 = CustomerVisitLog::changeState('交定', 'chaos');
  787. $state2 = CustomerVisitLog::changeState('签单', 'chaos');
  788. $state3 = CustomerVisitLog::changeState('已量房', 'chaos');
  789. $state4 = CustomerVisitLog::changeState('已到店', 'chaos');
  790. $log_state = array_merge($state1, $state2, $state3, $state4);
  791. $v_where[] = ['confirm_date', 'between', $date_arr]; // 日志的条件
  792. $v_where[] = ['customer_employee_id', '=', $token['employee_id']];
  793. $v_where[] = ['state', 'in', $log_state];
  794. $visitlog = CustomerVisitLog::where($v_where)->column('state,customer_id');
  795. $ding = $sign = $ok_house = $ok_store = [];
  796. foreach ($visitlog as $k => $v) {
  797. if (in_array($v['state'], $state1)) {
  798. $ding[] = $v['customer_id'];
  799. } elseif (in_array($v['state'], $state2)) {
  800. $sign[] = $v['customer_id'];
  801. } elseif (in_array($v['state'], $state3)) {
  802. $ok_house[] = $v['customer_id'];
  803. } elseif (in_array($v['state'], $state4)) {
  804. $ok_store[] = $v['customer_id'];
  805. }
  806. }
  807. // 查询有效数量
  808. $validNum = CustomerStateCheck::where([
  809. ['employee_id', '=', $token['employee_id']]
  810. ])->count();
  811. return json([
  812. 'code' => 0,
  813. 'data' => [
  814. 'total' => $customer_count,
  815. 'ding' => count(array_unique($ding)),
  816. 'sign' => count(array_unique($sign)),
  817. 'make_house' => count(array_unique($subscribe_lf)),
  818. 'ok_house' => count(array_unique($ok_house)),
  819. 'make_store' => count(array_unique($subscribe_dd)),
  820. 'ok_store' => count(array_unique($ok_store)),
  821. 'wechat_count' => $jiav_count,
  822. 'valid_num' => $validNum,
  823. ]
  824. ]);
  825. }
  826. /**
  827. * 获取查询的时间范围
  828. */
  829. private function getDate($dateType)
  830. {
  831. switch ($dateType) {
  832. case 'today':
  833. return [date('Y-m-d 00:00:00'), date('Y-m-d 23:59:59')];
  834. case 'yesterday':
  835. return [date('Y-m-d 00:00:00', strtotime('yesterday')), date('Y-m-d 23:59:59', strtotime('yesterday'))];
  836. case 'serven':
  837. return [date('Y-m-d 00:00:00', strtotime('6 days ago')), date('Y-m-d 23:59:59')];
  838. case 'month':
  839. return [date('Y-m-d 00:00:00', strtotime('previous month')), date('Y-m-d 23:59:59')];
  840. }
  841. return null;
  842. }
  843. /**
  844. * 客户列表
  845. * @param state integer 1全部, 2待确认, 3未到访 4已到访,5定金,6签单,7无效
  846. */
  847. public function lists()
  848. {
  849. $token = $this->request->token;
  850. $param = $this->request->only([
  851. 'state' => '',
  852. 'page' => 1,
  853. 'limit' => 20,
  854. 'keyword' => '',
  855. 'source' => '',
  856. 'date' => '',
  857. 'visit' => '',
  858. 'addtime' => '',
  859. 'following' => '',
  860. 'protected' => '',
  861. 'level' => '',
  862. 'repay' => '',
  863. 'type' => '',
  864. 'start_date' => date('Y-m-d', 0),
  865. 'end_date' => date('Y-m-d')
  866. ]);
  867. // 格式化时间格式
  868. if (!empty($param['date'])) $param['date'] = date('Y-m-d', strtotime($param['date']));
  869. $condition = [];
  870. if ($param['type']) {
  871. if (empty($param['start_date'])) {
  872. $param['start_date'] = date('Y-m-d', 0);
  873. }
  874. if (empty($param['end_date'])) {
  875. $param['end_date'] = date('Y-m-d');
  876. }
  877. $startTime = strtotime($param['start_date']) - 1;
  878. $endTime = strtotime($param['end_date']) + 86400;
  879. // 查询条件
  880. $condition[] = ['Customer.employee_id', '=', $token['employee_id']];
  881. $condition[] = ['Customer.state', 'not in', Customer::changeState('无效', 'chaos')];
  882. // 有效
  883. $state3 = CustomerVisitLog::changeState('已量房', 'chaos');
  884. $state4 = CustomerVisitLog::changeState('已到店', 'chaos');
  885. $state5 = CustomerVisitLog::changeState('交定', 'chaos');
  886. $state6 = CustomerVisitLog::changeState('签单', 'chaos');
  887. $state7 = CustomerVisitLog::changeState('已到场', 'chaos');
  888. // 查询条件
  889. switch ($param['type']) {
  890. case 'jiav':
  891. $condition[] = ['Customer.add_wechat_time', '>', date('Y-m-d H:i:s', $startTime)];
  892. $condition[] = ['Customer.add_wechat_time', '<', date('Y-m-d H:i:s', $endTime)];
  893. break;
  894. case 'jiaofang':
  895. $condition[] = ['Customer.house_delivery_time', '>', date('Y/m/d H:i:s', $startTime)];
  896. $condition[] = ['Customer.house_delivery_time', '<', date('Y/m/d H:i:s', $endTime)];
  897. break;
  898. case 'yjlf': // 预计量房
  899. $s_where[] = ['employee_id', '=', $token['employee_id']];
  900. $s_where[] = ['state', '=', 0];
  901. $s_where[] = ['type', '=', 3];
  902. $s_where[] = ['addtime', '>', date('Y-m-d H:i:s', $startTime)];
  903. $s_where[] = ['addtime', '<', date('Y-m-d H:i:s', $endTime)];
  904. $customer_ids = CustomersSubscribe::where($s_where)->group('customer_id')->column('customer_id');
  905. $condition[] = ['Customer.id', 'in', $customer_ids];
  906. break;
  907. case 'liangfang':
  908. $condition[] = ['CustomerVisitLog.state', 'in', $state3];
  909. $condition[] = ['CustomerVisitLog.addtime', '>', date('Y-m-d H:i:s', $startTime)];
  910. $condition[] = ['CustomerVisitLog.addtime', '>', date('Y-m-d H:i:s', $startTime)];
  911. break;
  912. case 'yjdd': // 预计到店
  913. $s_where[] = ['employee_id', '=', $token['employee_id']];
  914. $s_where[] = ['state', '=', 0];
  915. $s_where[] = ['type', '=', 1];
  916. $s_where[] = ['addtime', '>', date('Y-m-d H:i:s', $startTime)];
  917. $s_where[] = ['addtime', '<', date('Y-m-d H:i:s', $endTime)];
  918. $customer_ids = CustomersSubscribe::where($s_where)->group('customer_id')->column('customer_id');
  919. $condition[] = ['Customer.id', 'in', $customer_ids];
  920. break;
  921. case 'daodian':
  922. $condition[] = ['CustomerVisitLog.state', 'in', $state4];
  923. $condition[] = ['CustomerVisitLog.addtime', '>', date('Y-m-d H:i:s', $startTime)];
  924. $condition[] = ['CustomerVisitLog.addtime', '>', date('Y-m-d H:i:s', $startTime)];
  925. break;
  926. case 'jiaoding':
  927. $condition[] = ['CustomerVisitLog.state', 'in', $state5];
  928. $condition[] = ['CustomerVisitLog.addtime', '>', date('Y-m-d H:i:s', $startTime)];
  929. $condition[] = ['CustomerVisitLog.addtime', '>', date('Y-m-d H:i:s', $startTime)];
  930. break;
  931. case 'qiandan':
  932. $condition[] = ['CustomerVisitLog.state', 'in', $state6];
  933. $condition[] = ['CustomerVisitLog.addtime', '>', date('Y-m-d H:i:s', $startTime)];
  934. $condition[] = ['CustomerVisitLog.addtime', '>', date('Y-m-d H:i:s', $startTime)];
  935. break;
  936. case 'jianqun':
  937. $condition[] = ['Customer.group_building_date', '>', date('Y-m-d H:i:s', $startTime)];
  938. $condition[] = ['Customer.group_building_date', '<', date('Y-m-d H:i:s', $endTime)];
  939. break;
  940. case 'zhibo':
  941. $condition[] = ['Customer.live_broadcast_date', '>', date('Y-m-d H:i:s', $startTime)];
  942. $condition[] = ['Customer.live_broadcast_date', '<', date('Y-m-d H:i:s', $endTime)];
  943. break;
  944. case 'yydc':
  945. $s_where[] = ['employee_id', '=', $token['employee_id']];
  946. $s_where[] = ['state', '=', 0];
  947. $s_where[] = ['type', '=', 2];
  948. $s_where[] = ['addtime', '>', date('Y-m-d H:i:s', $startTime)];
  949. $s_where[] = ['addtime', '<', date('Y-m-d H:i:s', $endTime)];
  950. $customer_ids = CustomersSubscribe::where($s_where)->group('customer_id')->column('customer_id');
  951. $condition[] = ['Customer.id', 'in', $customer_ids];
  952. break;
  953. case 'daochang':
  954. $condition[] = ['CustomerVisitLog.state', 'in', $state7];
  955. $condition[] = ['CustomerVisitLog.addtime', '>', date('Y-m-d H:i:s', $startTime)];
  956. $condition[] = ['CustomerVisitLog.addtime', '>', date('Y-m-d H:i:s', $startTime)];
  957. break;
  958. case 'yygswjm':
  959. $condition[] = ['Customer.subscribe_meet_outside', '>', date('Y-m-d H:i:s', $startTime)];
  960. $condition[] = ['Customer.subscribe_meet_outside', '<', date('Y-m-d H:i:s', $endTime)];
  961. break;
  962. case 'gswjm':
  963. $condition[] = ['Customer.meet_outside', '>', date('Y-m-d H:i:s', $startTime)];
  964. $condition[] = ['Customer.meet_outside', '<', date('Y-m-d H:i:s', $endTime)];
  965. break;
  966. default:
  967. //$condition[] = ['Customer.addtime', '>', date('Y-m-d H:i:s', $startTime)];
  968. //$condition[] = ['Customer.addtime', '<', date('Y-m-d H:i:s', $endTime)];
  969. break;
  970. }
  971. // 客户总数
  972. $customer_ids = Db::view('Customer')
  973. ->view('Org', '', 'Org.id=Customer.org_id')
  974. ->view('CustomerVisitLog', '', 'Customer.id=CustomerVisitLog.customer_id')
  975. ->where($condition)
  976. ->group('Customer.id')
  977. ->column('Customer.id');
  978. unset($condition);
  979. $condition[] = ['id', 'in', $customer_ids];
  980. }
  981. $condition[] = ['died', '<>', 2]; // 死单客户过滤
  982. // 1)查询条件
  983. if (empty($param['protected'])) {
  984. $condition[] = ['employee_id', '=', $token['employee_id']];
  985. $condition[] = ['state', 'not in', Customer::changeState('无效', 'chaos')];
  986. }
  987. // 可回收列表
  988. if (!empty($param['protected'])) {
  989. $orgids = orgSubIds($this->request->token['org_id']);
  990. $org_employee = Employee::where('org_id', 'in', $orgids)->column('id');
  991. $condition[] = ['employee_id', 'in', $org_employee];
  992. }
  993. setCondition($param, 'level', '=', $condition);
  994. // 2)状态筛选
  995. // empty($param['state']) ? $logCondition[] = ['state', 'not in', CustomerVisitLog::changeState('无效', 'chaos')] : $condition[] = ['state', 'in', CustomerVisitLog::changeState($param['state'], 'chaos')];
  996. // 3)来源筛选
  997. $source = [
  998. 'ownadd' => [
  999. ['crm_res_id', 'NULL', null],
  1000. ['is_resource', '=', 0],
  1001. ['remark', '=', '']
  1002. ],
  1003. 'crmres' => [
  1004. ['crm_res_id', 'NOTNULL', null],
  1005. ['is_resource', '=', 0]
  1006. ],
  1007. 'public' => [
  1008. ['remark', '=', '公海获取']
  1009. ],
  1010. 'agent' => [
  1011. ['agents_id', '<>', ''],
  1012. ['agent_source_type', 'in', [1, 2]], //1表示手动报备2表示活动报名录入
  1013. ],
  1014. 'agent_crm_add' => [
  1015. ['agents_id', '<>', ''],
  1016. ['agent_source_type', '=', 3], //经纪人分享内容报名的客户
  1017. ]
  1018. ];
  1019. // 来源
  1020. (empty($param['source']) || !isset($source[$param['source']])) ?: $condition = array_merge_recursive($condition, $source[$param['source']]);
  1021. // 5)待回访
  1022. empty($param['visit']) ?: $condition[] = empty($param['date']) ? ['revisit_time', '=', date('Y-m-d') . ' 00:00:00'] : ['revisit_time', '=', $param['date'] . ' 00:00:00'];
  1023. // 6)录入时间筛选
  1024. empty($param['addtime']) ?: $condition[] = ['addtime', 'like', date('Y-m-d', strtotime($param['addtime'])) . '%'];
  1025. //增加按跟进时间排序
  1026. $order = 'addtime desc';
  1027. empty($param['following']) ?: $order = 'last_contact_date ' . $param['following'] . ',' . $order;
  1028. //增加回访时间排序
  1029. empty($param['repay']) ?: $order = 'revisit_time ' . $param['repay'] . ',' . $order;
  1030. //关键词搜索
  1031. if (!empty($param['keyword'])) {
  1032. if (empty($param['protected'])) {
  1033. $list = Customer::where($condition)->order($order)->field('id,name,community_name,phone')->select()->toArray();
  1034. $customersIdList = [];
  1035. foreach ($list as $k => $v) {
  1036. $str = $v['name'] . $v['community_name'] . $v['phone'];
  1037. if (strpos($str, trim($param['keyword'])) !== false) $customersIdList[] = $v['id'];
  1038. }
  1039. } else {
  1040. $search_employee = Employee::where([['id', 'in', $org_employee], ['name', 'like', '%' . $param['keyword'] . '%']])->column('id');
  1041. $search_designer = Employee::where([['root_id', '=', $this->request->token['root_org']], ['name', 'like', '%' . $param['keyword'] . '%']])->column('id');
  1042. $list = Customer::where($condition)->order($order)->field('id,name,community_name,phone,employee_id,designer_id')->select()->toArray();
  1043. $employee_customer = [];
  1044. $customersIdList = [];
  1045. foreach ($list as $k => $v) {
  1046. $str = $v['name'] . $v['community_name'];
  1047. if (strpos($str, trim($param['keyword'])) !== false) $customersIdList[] = $v['id'];
  1048. if (in_array($v['employee_id'], $search_employee)) {
  1049. $employee_customer[] = $v['id'];
  1050. }
  1051. if (in_array($v['designer_id'], $search_designer)) {
  1052. $employee_customer[] = $v['id'];
  1053. }
  1054. $employee_customer = array_values(array_filter(array_unique($employee_customer)));
  1055. }
  1056. $customersIdList = array_values(array_filter(array_unique(array_merge($customersIdList, $employee_customer))));
  1057. }
  1058. } else {
  1059. // 不查询待确认的客户, 或待确认的客户不是资源库中的
  1060. $orCondition1 = $orCondition = $condition;
  1061. $condition[] = ['state', 'not in', Customer::changeState('待确认', 'chaos')];
  1062. $orCondition[] = ['state', 'in', Customer::changeState('待确认', 'chaos')];
  1063. $orCondition[] = ['crm_res_id', 'NULL', null];
  1064. //从公海获取的客户是资源库的,当前状态是待确认的
  1065. $orCondition1[] = ['state', 'in', Customer::changeState('待确认', 'chaos')];
  1066. $orCondition1[] = ['crm_res_id', 'NOTNULL', null];
  1067. $orCondition1[] = ['valid_time', 'NOTNULL', null];
  1068. $customersIdList = Customer::whereOr([$condition, $orCondition, $orCondition1])->order($order)->column('id');
  1069. }
  1070. // 剔除掉未经历该状态的客户id
  1071. // 全部客户搜索当前状态 共有客户搜历史 2023-03-01 小胖
  1072. if (!empty($param['state'])) {
  1073. if ($param['state'] == '待确认') {
  1074. //2022-10-30 小程序客户列表的待确认状态是根据客户表的当前状态来展示的,所以查询待确认状态时 查询客户当前状态
  1075. //增加查询从公海获取的客户是资源库的,当前状态是待确认的
  1076. $daior[] = [['id', 'in', $customersIdList], ['state', 'in', Customer::changeState($param['state'], 'chaos')], ['crm_res_id', 'NULL', NULL]];
  1077. $daior[] = [['id', 'in', $customersIdList], ['state', 'in', Customer::changeState($param['state'], 'chaos')], ['crm_res_id', 'NOTNULL', NULL], ['valid_time', 'NOTNULL', NULL]];
  1078. //$customersIdList = Customer::where([['id', 'in', $customersIdList], ['state', 'in', Customer::changeState($param['state'], 'chaos')], ['crm_res_id', 'NULL', null]])->column('id');
  1079. $customersIdList = Customer::whereOr($daior)->column('id');
  1080. } elseif (CustomerVisitLog::changeState($param['state']) == '回访' || $param['state'] == '有效') {
  1081. //有效状态 未到访,已到访,确定到场,已量房,交定,签单
  1082. // $visit_status = ['未到访', '已到访', '已量房', '已到场', '已到店', '交定', '签单'];
  1083. // $now_status = [];
  1084. // foreach ($visit_status as $v) {
  1085. // $now_status = array_merge(CustomerVisitLog::changeState($v, 'chaos'), $now_status);
  1086. // }
  1087. // $customersIdList = CustomerVisitLog::where([['customer_id', 'in', $customersIdList], ['state', 'in', $now_status], ['employee_id|customer_employee_id', '=', $token['employee_id']]])->group('customer_id')->column('customer_id');
  1088. //客户表里排除了待确认的跟死单跟无效的客户就是有效的
  1089. $customersIdList = Customer::where([['id', 'in', $customersIdList], ['state', 'not in', array_merge(Customer::changeState('待确认', 'chaos'), Customer::changeState('无效', 'chaos'))], ['died', '<>', 2]])->column('id');
  1090. // 查询经历过回访以外所有状态的客户id(有效)
  1091. // $expectCustomersIdList = CustomerVisitLog::where([['customer_id', 'in', $customersIdList], ['state', 'not in', CustomerVisitLog::changeState('回访', 'chaos')], ['state', 'not in', CustomerVisitLog::changeState('无效', 'chaos')], ['employee_id', '=', $token['employee_id']]])->group('customer_id')->column('customer_id');
  1092. // if ($param['state'] == '有效') {
  1093. // $customersIdList = $expectCustomersIdList;
  1094. // } else {
  1095. // $customersIdList = array_diff($customersIdList, $expectCustomersIdList);
  1096. // }
  1097. } else {
  1098. $customersIdList = CustomerVisitLog::where([['customer_id', 'in', $customersIdList], ['state', 'in', CustomerVisitLog::changeState($param['state'], 'chaos')]])->group('customer_id')->column('customer_id');
  1099. }
  1100. }
  1101. // 过保护期查询
  1102. $setting = Setting::where([['name', '=', 'pubpool'], ['root_id', '=', $token['root_org']]])->findOrEmpty();
  1103. if (!empty($param['protected'])) {
  1104. if (!$setting->isEmpty()) {
  1105. $content = !empty($setting['content']) ? json_decode($setting['content'], true) : [];
  1106. if (empty($content)) {
  1107. return json(['code' => 0, 'data' => ['list' => [], 'count' => 0, 'ids' => []], 'page' => 1]);
  1108. }
  1109. $empty = false; //判断是否是正常数据,因为之前可能有垃圾数据
  1110. foreach ($content as $k => $v) {
  1111. if (!isset($v['day']) || !isset($v['state'])) {
  1112. $empty = true;
  1113. }
  1114. }
  1115. if ($empty) {
  1116. return json(['code' => 0, 'data' => ['list' => [], 'count' => 0, 'ids' => []], 'page' => 1]);
  1117. }
  1118. $whereOr = [];
  1119. foreach ($content as $k => $v) {
  1120. if ($v['state'] == 1 && $v['day'] > 0) {
  1121. $whereOr[] = [
  1122. ['state', 'in', Customer::changeState($k, 'chaos')],
  1123. ['protected_to', '<', date('Y-m-d H:i:s')],
  1124. ['protected_to', '<>', ' null']
  1125. ];
  1126. }
  1127. }
  1128. if (!empty($whereOr)) {
  1129. $customersIdList = Customer::where([['id', 'in', $customersIdList]])->where(function ($query) use ($whereOr) {
  1130. $query->whereOr($whereOr);
  1131. })->column('id');
  1132. } else {
  1133. return json(['code' => 0, 'data' => ['list' => [], 'count' => 0, 'ids' => []], 'page' => 1]);
  1134. }
  1135. } else {
  1136. return json(['code' => 0, 'data' => ['list' => [], 'count' => 0, 'ids' => []], 'page' => 1]);
  1137. }
  1138. }
  1139. if (empty($param['protected'])) {
  1140. // 置顶数据获取
  1141. $top = CustomerTop::where([['root_id', '=', $token['root_org']], ['employee_id', '=', $token['employee_id']]])->where([['customer_id', 'in', $customersIdList]])->order('addtoptime asc')->column('customer_id');
  1142. // 新数据获取
  1143. $new = Customer::where([['id', 'in', $customersIdList], ['fresh', '=', 1]])->order($order)->column('id');
  1144. // 剔除不应该出现的客户
  1145. $top = array_diff($top, array_diff($top, $customersIdList));
  1146. // // 剔除不应该出现的新客户
  1147. $new = array_diff($new, array_diff($new, $customersIdList));
  1148. // 剔除置顶的客户
  1149. $notTop = array_diff($customersIdList, $top);
  1150. // 剔除新客户
  1151. $notNew = array_diff($notTop, $new);
  1152. // 将置顶客户放置到前面
  1153. $customersIdList = array_unique(array_merge($top, $new, $notNew));
  1154. } else {
  1155. $top = [];
  1156. }
  1157. //返回到特定位置
  1158. $id = input('id', 0);
  1159. if ($id) {
  1160. $ids = array_chunk($customersIdList, $param['limit']);
  1161. foreach ($ids as $k => $v) {
  1162. $a = false;
  1163. foreach ($v as $k2 => $v2) {
  1164. if ($id == $v2) {
  1165. $a = true;
  1166. $param['page'] = $k + 1;
  1167. break;
  1168. }
  1169. }
  1170. if ($a) break;
  1171. }
  1172. }
  1173. // 分页
  1174. $pageIdList = array_slice($customersIdList, ($param['page'] - 1) * $param['limit'], $param['limit']);
  1175. $id_where[] = ['id', 'in', $pageIdList];
  1176. $customers = Customer::with(['designer', 'designerOrg', 'employee', 'agent'])->where($id_where)->select();
  1177. // 总数获取
  1178. $count = count($customersIdList);
  1179. $customers = $customers->visible(['id', 'employee_id', 'designer_id', 'name', 'sex', 'level', 'community_name', 'state', 'addtime', 'revisit_time', 'designer.name', 'designerOrg.name', 'fresh', 'square', 'last_contact_date', 'updatetime', 'employee.name', 'agent.agent_name', 'assign_type'])->toArray();
  1180. if (!empty($param['protected'])) {
  1181. if (!$setting->isEmpty()) {
  1182. $setting_content = !empty($setting['content']) ? json_decode($setting['content'], true) : [];
  1183. } else {
  1184. $setting_content = [];
  1185. }
  1186. foreach ($customers as $k => $v) {
  1187. $customers[$k]['un_protected'] = 0;
  1188. $customers[$k]['protected_tips'] = '';
  1189. if (!empty($v['protected_to']) && time() > strtotime($v['protected_to'])) {
  1190. $state_n = Customer::changeState($v['state'], 'n');
  1191. if (!empty($setting_content[$state_n]['state']) && $setting_content[$state_n]['state'] == 1) {
  1192. $customers[$k]['un_protected'] = 1;
  1193. $customers[$k]['protected_tips'] = '已过期';
  1194. }
  1195. }
  1196. if (!empty($v['protected_to']) && time() < strtotime($v['protected_to'])) {
  1197. $day = floor((strtotime($v['protected_to']) - time()) / (24 * 3600));
  1198. $customers[$k]['protected_tips'] = $day ? '保护期' . $day . '天' : '即将过期';
  1199. }
  1200. }
  1201. } else {
  1202. foreach ($customers as $k => $v) {
  1203. $customers[$k]['un_protected'] = 0;
  1204. $customers[$k]['protected_tips'] = '';
  1205. }
  1206. }
  1207. $customers = array_combine(array_column($customers, 'id'), $customers);
  1208. // 状态统计获取
  1209. $customersStateList = CustomerVisitLog::where([['customer_id', 'in', $pageIdList]])->group('state,customer_id')->field('count(state) as num, state, customer_id')->select()->toArray();
  1210. $customersState = [];
  1211. foreach ($customersStateList as $s) {
  1212. if (!isset($customersState[$s['customer_id']]))
  1213. $customersState[$s['customer_id']] = ['count' => 0, 'shop' => 0, 'measure' => 0, 'activity' => 0, 'deposit' => 0, 'signed' => 0];
  1214. $customersState[$s['customer_id']]['count'] += $s['num'];
  1215. // 到店,量房,活动,定金,签单
  1216. if ($s['state'] == '已到店') $customersState[$s['customer_id']]['shop'] += $s['num'];
  1217. elseif ($s['state'] == '已量房') $customersState[$s['customer_id']]['measure'] += $s['num'];
  1218. elseif ($s['state'] == '已到场') $customersState[$s['customer_id']]['activity'] += $s['num'];
  1219. elseif ($s['state'] == '已交定') $customersState[$s['customer_id']]['deposit'] += $s['num'];
  1220. elseif ($s['state'] == '已签单') $customersState[$s['customer_id']]['signed'] += $s['num'];
  1221. }
  1222. // 最后跟进时间获取
  1223. $lastTime = CustomerVisitLog::where([['customer_id', 'in', $pageIdList]])->group('customer_id')->column('max(addtime)', 'customer_id');
  1224. // 交定时间获取
  1225. $dingTime = CustomerVisitLog::where([['customer_id', 'in', $pageIdList], ['state', 'in', CustomerVisitLog::changeState('已交定', 'chaos')]])->group('customer_id')->column("max(confirm_date)", "customer_id");
  1226. trace(json_encode($dingTime));
  1227. // 排序(按每页id顺序取值)
  1228. $listData = [];
  1229. foreach ($pageIdList as $customerId) {
  1230. $customers[$customerId]['top'] = 0;
  1231. $customers[$customerId]['is_new'] = $customers[$customerId]['fresh'] == 1 ? 1 : 0;
  1232. $customers[$customerId]['addtoptime'] = null;
  1233. if (in_array($customerId, $top)) $customers[$customerId]['addtoptime'] = 1;
  1234. if (isset($customersState[$customerId]) && !in_array($customers[$customerId]['state'], Customer::changeState('待确认', 'chaos'), true)) {
  1235. $customers[$customerId]['stateNum'] = $customersState[$customerId];
  1236. } else {
  1237. $customers[$customerId]['stateNum'] = ['count' => 0, 'shop' => 0, 'measure' => 0, 'activity' => 0, 'deposit' => 0, 'signed' => 0];
  1238. }
  1239. $customers[$customerId]['last_visit_day'] = isset($lastTime[$customerId]) ? get_date_diff(time(), $lastTime[$customerId])->days : -1;
  1240. $customers[$customerId]['last_ding_day'] = isset($dingTime[$customerId]) ? get_date_diff(time(), $dingTime[$customerId])->days : 0;
  1241. $listData[] = $customers[$customerId];
  1242. }
  1243. //重复录入功能,添加手机号 ,自动回收库里分配去重用
  1244. if ($listData) {
  1245. $keys = array_column($listData, 'id');
  1246. $customer = Customer::where([['id', 'in', $keys]])->field('id,phone,phone1,phone2')->select();
  1247. $phones = [];
  1248. foreach ($customer as $v) {
  1249. $phones[$v->id] = $v->toArray();
  1250. }
  1251. foreach ($listData as $k2 => $v2) {
  1252. $listData[$k2] = array_merge($v2, $phones[$v2['id']]);
  1253. }
  1254. //小程序排序待回收和 后台待回收排序保持一致
  1255. if (!empty($param['protected'])) array_multisort(array_column($listData, 'id'), SORT_DESC, $listData);
  1256. }
  1257. $data = [
  1258. 'list' => $listData,
  1259. 'count' => $count,
  1260. 'ids' => Customer::where([['id', 'in', $customersIdList]])->field('id,phone,phone1,phone2')->select()
  1261. ];
  1262. return json(['code' => 0, 'data' => $data, 'page' => $param['page']]);
  1263. }
  1264. /**
  1265. * 设计师待跟进接口
  1266. */
  1267. public function confirmList()
  1268. {
  1269. $param = $this->request->only(['state' => '', 'page' => 1, 'limit' => 20, 'date' => date('Y-m-d')]);
  1270. $type = [
  1271. '到店' => 1,
  1272. '活动' => 2,
  1273. '量房' => 3
  1274. ];
  1275. if (!isset($type[$param['state']])) {
  1276. $search = ['type', 'in', [1, 2, 3]];
  1277. } else {
  1278. $search = ['type', '=', $type[$param['state']]];
  1279. }
  1280. $condition = ['designer_id|employee_id', '=', $this->request->token['employee_id']];
  1281. $date = ['subscribe_date', '=', $param['date']];
  1282. // 排除掉无效的客户
  1283. $customerIdList = CustomersSubscribe::where([$condition, $date, $search, ['state', '=', 0]])->column('customer_id');
  1284. $customerIdList = Customer::where([['id', 'in', $customerIdList], ['state', 'not in', Customer::changeState('无效', 'chaos')]])->column('id');
  1285. $subscribe = CustomersSubscribe::with(['customer', 'employee', 'designer', 'activity', 'org'])->where([$condition, $date, $search, ['state', '=', 0], ['customer_id', 'in', $customerIdList]])->order('subscribe_date asc, hour asc')->page($param['page'], $param['limit'])->select();
  1286. $data = $subscribe->visible(['id', 'customer_id', 'employee_id', 'customer.name', 'customer.sex', 'customer.level', 'customer.community_name', 'customer.state', 'employee.name', 'org.name', 'activity.title', 'aid', 'subscribe_date', 'type'])->toArray();
  1287. // 保持原接口数据一致
  1288. $customers = [];
  1289. foreach ($data as $c) {
  1290. $customers[] = [
  1291. 'id' => $c['customer_id'],
  1292. 'customer_id' => $c['customer_id'],
  1293. 'employee_id' => $c['employee_id'],
  1294. 'name' => $c['customer']['name'],
  1295. 'sex' => $c['customer']['sex'],
  1296. 'level' => $c['customer']['level'],
  1297. 'community_name' => $c['customer']['community_name'],
  1298. 'state' => $c['customer']['state'],
  1299. 'subscribe_state' => $c['type'],
  1300. 'employee' => ['name' => $c['employee']['name']],
  1301. 'employeeOrg' => ['name' => $c['org']['name']],
  1302. 'activity' => [
  1303. 'title' => empty($c['activity']) ? '' : $c['activity']['title'],
  1304. 'id' => $c['aid']
  1305. ],
  1306. 'last_contact_date' => $c['subscribe_date']
  1307. ];
  1308. }
  1309. // 状态统计获取
  1310. $customersStateList = CustomerVisitLog::where([['customer_id', 'in', array_column($customers, 'customer_id')]])->group('state,customer_id')->field('count(state) as num, state, customer_id')->select()->toArray();
  1311. $customersState = [];
  1312. foreach ($customersStateList as $s) {
  1313. if (!isset($customersState[$s['customer_id']])) $customersState[$s['customer_id']] = ['count' => 0, 'shop' => 0, 'measure' => 0, 'activity' => 0, 'deposit' => 0, 'signed' => 0];
  1314. $customersState[$s['customer_id']]['count'] += $s['num'];
  1315. // 到店,量房,活动,定金,签单
  1316. if ($s['state'] == '已到店') $customersState[$s['customer_id']]['shop'] += $s['num'];
  1317. elseif ($s['state'] == '已量房') $customersState[$s['customer_id']]['measure'] += $s['num'];
  1318. elseif ($s['state'] == '已到场') $customersState[$s['customer_id']]['activity'] += $s['num'];
  1319. elseif ($s['state'] == '已交定') $customersState[$s['customer_id']]['deposit'] += $s['num'];
  1320. elseif ($s['state'] == '已签单') $customersState[$s['customer_id']]['signed'] += $s['num'];
  1321. }
  1322. foreach ($customers as &$item) {
  1323. $item['stateNum'] = $customersState[$item['customer_id']] ?? ['count' => 0, 'shop' => 0, 'measure' => 0, 'activity' => 0, 'deposit' => 0, 'signed' => 0];
  1324. }
  1325. $data = [
  1326. 'list' => $customers,
  1327. 'count' => CustomersSubscribe::where([$condition, $date, $search, ['state', '=', 0], ['customer_id', 'in', $customerIdList]])->count(),
  1328. 'allCount' => CustomersSubscribe::where([$condition, $date, ['state', '=', 0], ['customer_id', 'in', $customerIdList]])->count(),
  1329. 'visitCount' => CustomersSubscribe::where([$condition, $date, ['state', '=', 0], ['type', '=', $type['到店']], ['customer_id', 'in', $customerIdList]])->count(),
  1330. 'measureCount' => CustomersSubscribe::where([$condition, $date, ['state', '=', 0], ['type', '=', $type['量房']], ['customer_id', 'in', $customerIdList]])->count(),
  1331. 'activityCount' => CustomersSubscribe::where([$condition, $date, ['state', '=', 0], ['type', '=', $type['活动']], ['customer_id', 'in', $customerIdList]])->count()
  1332. ];
  1333. return json(['code' => 0, 'data' => $data]);
  1334. }
  1335. /*
  1336. * 客户列表点击电话图标获取电话
  1337. */
  1338. public function getCrmPhone()
  1339. {
  1340. $id = $this->request->param('id');
  1341. $token = $this->request->token;
  1342. $where = [
  1343. ['id', '=', $id],
  1344. ['state', '<>', '无效'],
  1345. ['employee_id', '=', $token['employee_id']]
  1346. ];
  1347. //指派的客户
  1348. $where_or = [['assigned_personnel', 'find in set', $token['employee_id']], ['id', '=', $id]];
  1349. $where_or1 = [['designer_id', '=', $token['employee_id']], ['id', '=', $id]];
  1350. $had = Customer::whereOr([$where, $where_or, $where_or1])->find();
  1351. // 不是共有客户,检测是否是领导领导调用
  1352. if ($had == null) {
  1353. $had = Customer::find($id);
  1354. // 检测数据是否存在
  1355. if (!$had)
  1356. return json(['code' => 1, 'msg' => '数据不存在']);
  1357. // 登陆人部门及子部门获取
  1358. $my = Org::find($token['org_id']);
  1359. $orgIdList = Org::where([['path', 'like', $my->path . '%']])->column('id');
  1360. // 不是可见部门的 返回空
  1361. // if (!in_array($had->org_id, $orgIdList)) {
  1362. // return json(['code' => 1, 'msg' => '数据不存在']);
  1363. // }
  1364. if ($token['isManager']) {
  1365. // 是管理员
  1366. if (!empty($had->employee_id)) {
  1367. $employeeIdListStr = $had->employee_id . ',' . $had->assigned_personnel . ',' . $had->designer_id;
  1368. $employeeIdListArr = explode(',', $employeeIdListStr);
  1369. $employeeIdListArr = array_filter($employeeIdListArr);
  1370. // 查找分享人是否在部门下
  1371. $exit = Employee::where([['org_id', 'in', $orgIdList], ['id', 'in', $employeeIdListArr]])->count();
  1372. if ($exit == 0)
  1373. return json(['code' => 1, 'msg' => '数据不存在']);
  1374. }
  1375. } else {
  1376. // 不是领导判断 客户是否属于自己 公海库不判断
  1377. if ($had->employee_id && ($had->employee_id != $token['employee_id'])) {
  1378. return json(['code' => 1, 'msg' => '数据不存在']);
  1379. }
  1380. }
  1381. }
  1382. if (!$had)
  1383. return json(['code' => 1, 'msg' => '数据不存在']);
  1384. //客户电话
  1385. $phone = [
  1386. 'phone' => $had->phone,
  1387. 'phone1' => $had->phone1,
  1388. 'phone2' => $had->phone2,
  1389. ];
  1390. //员工电话
  1391. $info = Employee::where('id', $token['employee_id'])->field('out_call_phone,phone')->find();
  1392. // 开启外呼的店面判断
  1393. $set = OutCallSetting::where('root_id', '=', request()->token['root_org'])->findOrEmpty();
  1394. $out_call_check = 0;
  1395. if (!$set->isEmpty()) {
  1396. $out_call_check = 1;
  1397. }
  1398. return json(['code' => 0, 'phone' => $phone, 'out_call_phone' => $info->out_call_phone ? array_merge([$info->phone], explode(',', $info->out_call_phone)) : [$info->phone], 'out_call_check' => $out_call_check]);
  1399. }
  1400. /*
  1401. * 星标置顶和取消
  1402. */
  1403. public function customer_top()
  1404. {
  1405. $id = $this->request->param('id');
  1406. $CustomerTop = CustomerTop::where(['customer_id' => $id, 'employee_id' => $this->request->token['employee_id'], 'root_id' => request()->token['root_org']])->find();
  1407. if (empty($CustomerTop)) {
  1408. CustomerTop::create(['customer_id' => $id, 'employee_id' => $this->request->token['employee_id'], 'root_id' => request()->token['root_org']]);
  1409. } else {
  1410. CustomerTop::where('id', $CustomerTop['id'])->delete();
  1411. }
  1412. return json(['code' => 0, 'msg' => '操作成功']);
  1413. }
  1414. /*
  1415. * 个人在系统内客户最早的待回访时间和录入时间,最晚待回访时间和录入时间,按以上时间之内可选
  1416. */
  1417. public function time_limit()
  1418. {
  1419. $data = Customer::where([['state', '<>', '无效'], ['employee_id', '=', $this->request->token['employee_id']]])->field('max(revisit_time) as max_revisit_time,min(revisit_time) as min_revisit_time,max(addtime) as max_addtime,min(addtime) as min_addtime')->find();
  1420. $data['max_revisit_time'] = !empty($data['max_revisit_time']) ? date('Y-m-d', strtotime($data['max_revisit_time'])) : null;
  1421. $data['min_revisit_time'] = !empty($data['min_revisit_time']) ? date('Y-m-d', strtotime($data['min_revisit_time'])) : null;
  1422. $data['max_addtime'] = !empty($data['max_addtime']) ? date('Y-m-d', strtotime($data['max_addtime'])) : null;
  1423. $data['min_addtime'] = !empty($data['min_addtime']) ? date('Y-m-d', strtotime($data['min_addtime'])) : null;
  1424. return json(['code' => 0, 'data' => $data, 'msg' => '获取成功']);
  1425. }
  1426. /**
  1427. * 待回访每日具体个数
  1428. */
  1429. public function visit_schedule()
  1430. {
  1431. $date = $this->request->get('date', date('Y-m'));
  1432. $condition = [
  1433. ['state', '<>', '无效'],
  1434. ['employee_id', '=', $this->request->token['employee_id']],
  1435. ['revisit_time', '<>', 'null'],
  1436. ['revisit_time', 'like', $date . '%']
  1437. ];
  1438. $futuredates = Customer::where(function ($query) {
  1439. $query->whereOr([[['state', 'in', Customer::changeState('待确认', 'chaos')], ['crm_res_id', 'NULL', null]], [['state', 'not in', Customer::changeState('待确认', 'chaos')]]]);
  1440. })->where($condition)->field("count(id) as num,date_format(revisit_time, '%Y-%m-%d') as days")->group('days')->select();
  1441. $schedule = [];
  1442. foreach ($futuredates as $r) {
  1443. $schedule[$r['days']] = $r['num'];
  1444. }
  1445. return json(['code' => 0, 'data' => $schedule]);
  1446. }
  1447. /**
  1448. * 工作台待跟进每日具体个数
  1449. */
  1450. public function followup_schedule()
  1451. {
  1452. $date = $this->request->get('date', date('Y-m'));
  1453. // $role = $this->request->token['org_type'] == 2 ? 'designer_id' : 'employee_id';
  1454. $condition = [
  1455. ['state', '=', '0'],
  1456. ['designer_id|employee_id', '=', $this->request->token['employee_id']],
  1457. ['subscribe_date', 'like', $date . '-%']
  1458. ];
  1459. // 排除掉无效的客户
  1460. $customerIdList = CustomersSubscribe::where($condition)->column('customer_id');
  1461. $customerIdList = Customer::where([['id', 'in', $customerIdList], ['state', 'not in', Customer::changeState('无效', 'chaos')]])->column('id');
  1462. $condition[] = ['customer_id', 'in', $customerIdList];
  1463. $futuredates = CustomersSubscribe::where($condition)->field("count(id) as num,subscribe_date as days")->group('days')->select();
  1464. $schedule = [];
  1465. foreach ($futuredates as $r) {
  1466. $schedule[$r['days']] = $r['num'];
  1467. }
  1468. return json(['code' => 0, 'data' => $schedule]);
  1469. }
  1470. /**
  1471. * 待回访数据统计
  1472. */
  1473. public function visitCount()
  1474. {
  1475. $condition = [
  1476. ['employee_id', '=', $this->request->token['employee_id']]
  1477. ];
  1478. // 总数统计
  1479. $total = Customer::where($condition)->count();
  1480. setCondition(date('Y-m-d H:i:s'), 'revisit_time', '<', $condition);
  1481. $visit = Customer::where($condition)->count();
  1482. return json(['code' => 0, 'data' => ['total' => $total, 'visit' => $visit]]);
  1483. }
  1484. /**
  1485. * 公共库
  1486. */
  1487. public function common()
  1488. {
  1489. $param = $this->request->param();
  1490. $page = $param['page'];
  1491. $limit = $param['limit'];
  1492. $condition[] = ['state', 'in', Customer::changeState('无效', 'chaos')];
  1493. $condition[] = ['employee_id', '=', $this->request->token['employee_id']];
  1494. // setCondition($param, ['keyword', 'community_name'], ['like', '%VALUE%'], $condition);
  1495. if (isset($param['keyword']) && $param['keyword']) {
  1496. $condition[] = ['name|community_name', 'like', '%' . trim($param['keyword']) . '%'];
  1497. }
  1498. $customers = Customer::where($condition)->page($page, $limit)->order('addtime desc')->select();
  1499. return json(['code' => 0, 'data' => $customers]);
  1500. }
  1501. /**
  1502. * 客户追踪记录
  1503. */
  1504. public function visitlog()
  1505. {
  1506. $param = request()->param(['id']);
  1507. $token = $this->request->token;
  1508. // 判断是否是当前请求的用户
  1509. if ($this->request->token['isManager']) {
  1510. $team_orgs = orgSubIds($this->request->token['org_id']);
  1511. $empIdList = Employee::where([['org_id', 'in', $team_orgs]])->column('id');
  1512. $this_customer = Customer::find($param['id']);
  1513. if ($this_customer->isEmpty()) {
  1514. return json(['code' => 0, 'data' => [], 'count' => 0]);
  1515. }
  1516. $isMy = 0;
  1517. if (in_array($this_customer['employee_id'], $empIdList)) {
  1518. $isMy = 1;
  1519. }
  1520. if (in_array($this_customer['designer_id'], $empIdList)) {
  1521. $isMy = 1;
  1522. }
  1523. $assigned_personnel = explode(',', $this_customer['assigned_personnel']);
  1524. $assigned_personnel_arr = array_intersect($assigned_personnel, $empIdList);
  1525. if (!empty($assigned_personnel_arr)) {
  1526. $isMy = 1;
  1527. }
  1528. } else {
  1529. $isMy = Customer::where([['id', '=', $param['id']], ['employee_id|designer_id', '=', $this->request->token['employee_id']]])->count();
  1530. }
  1531. //指派人员
  1532. if ($isMy == 0) $isMy = Customer::where([['id', '=', $param['id']], ['assigned_personnel', 'find in set', $token['employee_id']]])->count();
  1533. if ($isMy == 0) return json(['code' => 0, 'data' => [], 'count' => 0]);
  1534. //查询是否设置只显示员工跟进记录不展示修改客户扩展字段
  1535. $showEmpVistlog = Setting::where([['root_id', '=', $token['root_org']], ['name', '=', 'showEmpVistlog']])->findOrEmpty();
  1536. $visit = !$showEmpVistlog->isEmpty() ? (int)$showEmpVistlog->content : 0;
  1537. $vlg_where[] = $visit ? ['save_portrait_field', 'NULL', null] : ['id', '>', 0];
  1538. $vlg_where[] = ['customer_id', '=', $param['id']];
  1539. $data = CustomerVisitLog::with(['employee' => function ($query) {
  1540. $query->field('id,name,org_id');
  1541. }, 'user' => function ($query) {
  1542. $query->field('id,headimgurl');
  1543. }])->where($vlg_where)->order('id desc')->select()->toArray();
  1544. //查询组织所属角色:销售、设计师
  1545. $column_employee_id = array_column($data, 'employee_id');
  1546. $employee = Employee::with(['org' => function ($query) {
  1547. $query->field('id,org_type');
  1548. }])->field('id,org_id')->where('id', 'in', $column_employee_id)->select()->toArray();
  1549. $column_org_type = array_column($employee, null, 'id');
  1550. //预约活动
  1551. $aids = array_column($data, 'aid');
  1552. $activity = array_filter($aids) ? Activity::where([['id', 'in', $aids]])->column('title', 'id') : [];
  1553. $state1 = CustomerVisitLog::changeState('已到店', 'chaos');
  1554. $state2 = CustomerVisitLog::changeState('已到场', 'chaos');
  1555. foreach ($data as &$v) {
  1556. $v['role'] = isset($column_org_type[$v['employee_id']]['org']['org_type']) ? $column_org_type[$v['employee_id']]['org']['org_type'] : null;
  1557. $v['is_track'] = $v['remark'] == '公海获取' ? 1 : 0;
  1558. $v['is_track'] = in_array($v['remark'], ['客户回收', '客户还原', '客户再分配', '资源库分配', '客户转移', '客戶指派', '取消客户下次回访时间']) ? 2 : $v['is_track']; //后台操作
  1559. if ($v['remark']) {
  1560. if (strpos($v['remark'], '[意向客户指派]') !== false || strpos($v['remark'], '[量房客户指派]') !== false || strpos($v['remark'], '[到店客户指派]') !== false) {
  1561. $v['is_track'] = 2;
  1562. }
  1563. }
  1564. //确认到店 的选择的内场活动
  1565. if ($v['aid'] && in_array($v['state'], $state1) && $activity && isset($activity[$v['aid']])) {
  1566. $v['remark'] = $v['remark'] . '预约活动:《' . $activity[$v['aid']] . '》;';
  1567. }
  1568. if (!empty($v['actmeet_type']) && in_array($v['state'], array_merge(CustomerVisitLog::changeState('已到场', 'chaos'), CustomerVisitLog::changeState('预约活动', 'chaos')), true)) {
  1569. if ($v['actmeet_type'] == 1) {
  1570. $v['remark'] .= ',见面方式为外场活动';
  1571. } elseif ($v['actmeet_type'] == 2) {
  1572. $v['remark'] .= ',见面方式为茶楼见面';
  1573. } elseif ($v['actmeet_type'] == 3) {
  1574. $v['remark'] .= ',见面方式为网谈登记';
  1575. }
  1576. }
  1577. if ($v['number_of_visitors'] > 0 && in_array($v['state'], $state1)) {
  1578. $v['remark'] = $v['remark'] . '到店人数:' . $v['number_of_visitors'] . '人;';
  1579. }
  1580. if ($v['talking_order_time'] && in_array($v['state'], $state1)) {
  1581. $v['remark'] = $v['remark'] . '谈单时长:' . $v['talking_order_time'] . '分钟;';
  1582. }
  1583. if ($v['number_of_visitors'] > 0 && in_array($v['state'], $state2)) {
  1584. $v['remark'] = $v['remark'] . '到场人数:' . $v['number_of_visitors'] . '人;';
  1585. }
  1586. if ($v['stay_length'] && in_array($v['state'], $state2)) {
  1587. $v['remark'] = $v['remark'] . '停留时间:' . $v['stay_length'] . '分钟;';
  1588. }
  1589. //zhihuiping
  1590. $v['wisdom_url'] = '';
  1591. $v['is_wisdom'] = 0;
  1592. if ($v['remark'] && strpos($v['remark'], '讲解智慧屏##') !== false) {
  1593. //remark = 接待了客户:张三,讲解时长21分钟@讲解智慧屏## url;
  1594. $v['is_wisdom'] = 1;
  1595. $arr = explode('##', $v['remark']);
  1596. if (count($arr) == 2) {
  1597. $ali_oss_bindurl = config('app.ali_oss_bindurl');
  1598. $v['wisdom_url'] = 'https://' . $ali_oss_bindurl . '/' . $arr[1];
  1599. $title = explode('@', $arr[0]);
  1600. $v['remark'] = $title[0];
  1601. }
  1602. }
  1603. if ($token['client_type'] != 'vL0CQQ') {
  1604. $v['remark'] = str_replace('签单', '转单', $v['remark']);
  1605. $v['remark'] = str_replace('交定', '签单', $v['remark']);
  1606. }
  1607. // 检测是否有录音
  1608. if ($v['data_type'] == 'out_call') {
  1609. $v['is_wisdom'] = 2;
  1610. $v['wisdom_url'] = OutCallLog::where(['id' => $v['data_id']])->value('url');
  1611. } elseif ($v['data_type'] == 'mobile_call' && strpos($v['remark'], '#') !== false) {
  1612. $ali_oss_bindurl = config('app.ali_oss_bindurl');
  1613. $arr = explode('#', $v['remark']);
  1614. $v['wisdom_url'] = 'https://' . $ali_oss_bindurl . '/' . $arr[1];
  1615. $v['remark'] = $arr[0];
  1616. }
  1617. //智慧屏跟进记录
  1618. if ($v['remark'] && strpos($v['remark'], '智慧屏客户图片##') !== false) {
  1619. //remark = 智慧屏客户图片## ## url
  1620. $arr = explode('##', $v['remark']);
  1621. if (count($arr) == 3) {
  1622. $ali_oss_bindurl = config('app.ali_oss_bindurl');
  1623. $imgs = explode(',', $arr[2]);
  1624. $img = [];
  1625. // $count = count($imgs)-1;
  1626. // for ($i=$count; $i >= 0; $i--) {
  1627. // $img[] = 'https://' . $ali_oss_bindurl . '/' . $imgs[$i];
  1628. // }
  1629. foreach ($imgs as $item) {
  1630. $img[] = 'https://' . $ali_oss_bindurl . '/' . $item;
  1631. }
  1632. $v['img'] = $img;
  1633. $v['remark'] = $arr[1];
  1634. }
  1635. }
  1636. //增加取消下次回访时间员工姓名
  1637. if ($v['remark'] == '取消客户下次回访时间') {
  1638. $empname = !empty($v['employee']['name']) ? $v['employee']['name'] : '';
  1639. $v['remark'] = $empname . $v['remark'];
  1640. }
  1641. //检测是否有下载文件
  1642. if (!empty($v['document_field']) && !empty($v['document_name'])) {
  1643. $str = $token['root_org'] . '#' . $token['employee_id'] . '#' . $v['id'];
  1644. $aec = new Aec(config('app.aec_key'), config('app.aec_iv'));
  1645. $value = $aec->encrypt($str);
  1646. $v['document_field'] = $this->request->domain() . '/downdocument/index.html?token=' . $value;
  1647. }
  1648. }
  1649. $count = CustomerVisitLog::where($vlg_where)->count();
  1650. return json(['code' => 0, 'data' => $data, 'count' => $count]);
  1651. }
  1652. /*
  1653. * 客户详情弹出框列表
  1654. * 确认量房、确认到店
  1655. */
  1656. public function visitlogDetails()
  1657. {
  1658. $param = request()->param(['id', 'state']);
  1659. $w[] = ['customer_id', '=', $param['id']];
  1660. if ($param['state'] == '已交定') {
  1661. $w[] = ['state', 'in', CustomerVisitLog::changeState('已交定', 'chaos')];
  1662. } else {
  1663. $w[] = CustomerVisitLog::changeState(['state', '=', '确认' . $param['state']]);
  1664. }
  1665. $root_id = request()->token['root_org'];
  1666. $subOrg = orgSubIds($root_id);
  1667. $w[] = ['org_id', 'in', $subOrg];
  1668. $data = CustomerVisitLog::with(['employee' => function ($query) {
  1669. $query->visible(['name', 'org_id', 'id']);
  1670. }])->where($w)->field('id,remark,addtime,money,img,img1,employee_id,number_of_visitors,talking_order_time,state,aid,shop_id,actmeet_type,stay_length')->order('addtime desc')->select();
  1671. $state1 = CustomerVisitLog::changeState('已到店', 'chaos');
  1672. $state2 = CustomerVisitLog::changeState('已到场', 'chaos');
  1673. //预约活动
  1674. $aids = array_column($data->toArray(), 'aid');
  1675. $activity = array_filter($aids) ? Activity::where([['id', 'in', $aids]])->column('title', 'id') : [];
  1676. //店铺
  1677. // $shop_id = array_column($data->toArray(),'shop_id');
  1678. // $shop = array_filter($shop_id) ? Shop::where([['id','in',$shop_id]])->column('name','id') : [];
  1679. foreach ($data as $k => &$v) {
  1680. if ($v->employee) {
  1681. $v->name = $v->employee->name;
  1682. $v->identity = isset($v->employee->org->org_type) && $v->employee->org->org_type == 2 ? '设计师' : '业务员';
  1683. } else {
  1684. $v->name = '';
  1685. $v->identity = '业务员';
  1686. }
  1687. if ($v->number_of_visitors > 0 && in_array($v['state'], $state1)) {
  1688. $v->remark = $v->remark . '到店人数:' . $v->number_of_visitors . '人;';
  1689. }
  1690. if ($v->number_of_visitors > 0 && in_array($v['state'], $state2)) {
  1691. $v->remark = $v->remark . '到场人数:' . $v->number_of_visitors . '人;';
  1692. }
  1693. if ($v->talking_order_time) {
  1694. $v->remark = $v->remark . '谈单时长:' . $v->talking_order_time . '分钟;';
  1695. }
  1696. if ($v->stay_length) {
  1697. $v->remark = $v->remark . '停留时间:' . $v->stay_length . '分钟;';
  1698. }
  1699. //确认到店 的选择的内场活动
  1700. if ($v['aid'] && in_array($v['state'], $state1) && $activity && isset($activity[$v['aid']])) {
  1701. $v->remark = $v->remark . '预约活动:《' . $activity[$v['aid']] . '》;';
  1702. }
  1703. //增加馨居尚活动见面方式
  1704. if (!empty($v['actmeet_type']) && in_array($v['state'], CustomerVisitLog::changeState('已到场', 'chaos'))) {
  1705. if ($v['actmeet_type'] == 1) {
  1706. $actmeet_type = ',见面方式为外场活动';
  1707. } elseif ($v['actmeet_type'] == 2) {
  1708. $actmeet_type = ',见面方式为茶楼见面';
  1709. } elseif ($v['actmeet_type'] == 3) {
  1710. $actmeet_type = ',见面方式为网谈登记';
  1711. }
  1712. $v->remark = !empty($actmeet_type) ? $v->remark . $actmeet_type : $v->remark;
  1713. }
  1714. //到达店面
  1715. // if ($v['shop_id'] && $shop && isset($shop[$v['shop_id']])) {
  1716. // $v->remark = $v->remark . '到达店面:《' . $shop[$v['shop_id']] . '》;';
  1717. // }
  1718. }
  1719. return json(['code' => 0, 'data' => $data]);
  1720. }
  1721. /**
  1722. * 2022-10-27 逻辑修改,跟进保护优化 如果后台设置了重复客户跟进保护规则 跟进到保护状态后其他客户的此重复客户就不能在跟进了,但是可以置为无效
  1723. */
  1724. private function forbiddenState($id, $status)
  1725. {
  1726. if ($status == '无效') return false;
  1727. $token = $this->request->token;
  1728. //保护规则
  1729. $provite = Setting::where([['name', '=', 'forbiddenState'], ['root_id', '=', $token['root_org']]])->value('content');
  1730. if (!$provite) return false;
  1731. $info = Customer::where('id', $id)->column('phone,phone1,phone2');
  1732. //查询是否是重复客户
  1733. $orgs = Org::where([['path', 'like', $token['root_org'] . '-%']])->column('id');
  1734. $query[] = ['employee_id', '>', 0];
  1735. $query[] = ['org_id', 'in', $orgs];
  1736. $query[] = ['phone|phone1|phone2', 'in', array_filter($info[0])];
  1737. // $query[] = ['employee_id','<>',$token['employee_id']];
  1738. $check = Customer::where($query)->column('id,employee_id');
  1739. if (count($check) <= 1) return false;
  1740. $provite = explode(',', $provite);
  1741. $state = [];
  1742. foreach ($provite as $v) {
  1743. $state = array_merge($state, CustomerVisitLog::changeState($v, 'chaos'));
  1744. }
  1745. //查询该客户是否存在受保护的状态 只有第一个跟进的业务员可以继续跟进
  1746. $where[] = ['state', 'in', $state];
  1747. $where[] = ['customer_id', 'in', array_column($check, 'id')];
  1748. $where[] = ['employee_id|customer_employee_id', 'in', array_column($check, 'employee_id')];
  1749. $repeat = CustomerVisitLog::where($where)->order('id asc')->field('customer_id,state')->findOrEmpty();
  1750. if ($repeat->isEmpty() || (int)$repeat->customer_id == (int)$id) return false;
  1751. //该客户已被其他员工 确认到店/确认量房/确认到场/交定/签单 无法更近
  1752. $state = str_replace('已', '', $repeat->state);
  1753. $state = in_array(trim($state), ['交定', '签单']) ? trim($state) : '确认' . trim($state);
  1754. return '该客户已被其他员工“' . $state . '”无法跟进';
  1755. }
  1756. /**
  1757. * 2022-11-11 业务修改 签单之后可以编辑签单金额,跟进记录增加 业务员修改签单金额为3000元
  1758. */
  1759. private function updateMoney($param)
  1760. {
  1761. $token = $this->request->token;
  1762. $money = $param['money'] ?: 0;
  1763. $where[] = ['id', '=', $param['customer_id']];
  1764. Customer::where($where)->update(['signed_money' => $money]);
  1765. if (isset($param['vlogid']) && $param['vlogid']) CustomerVisitLog::where('id', $param['vlogid'])->update(['money' => $money]);
  1766. $token['name'] = Employee::where([['id', '=', $token['employee_id']]])->value('name');
  1767. $time = date('Y-m-d H:i:s');
  1768. //增加跟进记录
  1769. $save = [
  1770. 'customer_id' => $param['customer_id'],
  1771. 'type' => '',
  1772. 'next_contact_date' => date('Y-m-d'),
  1773. 'remark' => '业务员' . $token['name'] . '修改已签单金额为' . $money . '元',
  1774. 'addtime' => $time,
  1775. 'employee_id' => $token['employee_id'],
  1776. 'user_id' => $token['uid'],
  1777. 'state' => 1,
  1778. 'org_id' => $token['org_id'],
  1779. 'customer_employee_id' => $token['employee_id'],
  1780. 'customer_org_id' => $token['org_id'],
  1781. 'money' => $money
  1782. ];
  1783. //2022-10-28 增加交定和签单凭证 凭证为图片
  1784. $deliverySignVoucher = request()->only(['sign_media_id' => '', 'sign_weixin_media' => '', 'sign_img' => '']);
  1785. $save = $save + $deliverySignVoucher;
  1786. CustomerVisitLog::insertGetId($save);
  1787. if ($deliverySignVoucher['sign_media_id']) Console::call('download', ['sign']);
  1788. $msg = '转单金额修改成功.'; //判断文字显示
  1789. return json(['code' => 0, 'msg' => $msg, 'data' => $msg]);
  1790. }
  1791. /**
  1792. * 取消客户的下次回访时间
  1793. */
  1794. public function cancelNextContactDate()
  1795. {
  1796. $token = $this->request->token;
  1797. $param = request()->only(['id']);
  1798. $cusdata = Customer::where([['state', 'not in', Customer::changeState('无效', 'chaos')], ['id', '=', $param['id']], ['org_id', 'in', orgSubIds($token['root_org'])]])->find();
  1799. if (empty($cusdata)) return json(['code' => 1, 'msg' => '客户数据不存在']);
  1800. $cusdata->revisit_time = null;
  1801. $cusdata->save();
  1802. $add = [
  1803. 'customer_id' => $cusdata->id,
  1804. 'type' => '',
  1805. 'employee_id' => $token['employee_id'],
  1806. 'user_id' => $token['uid'],
  1807. 'remark' => '取消客户下次回访时间',
  1808. 'state' => 10,
  1809. 'confirm_date' => date('Y-m-d'),
  1810. 'org_id' => $token['org_id'],
  1811. 'customer_employee_id' => $cusdata['employee_id'],
  1812. 'customer_org_id' => $cusdata['org_id']
  1813. ];
  1814. $ms = CustomerVisitLog::create($add);
  1815. if ($ms) {
  1816. return json(['code' => 0, 'msg' => '修改成功']);
  1817. } else {
  1818. return json(['code' => 1, 'msg' => '修改失败']);
  1819. }
  1820. }
  1821. /**
  1822. * 添加客户追踪记录
  1823. * 签单、收定时记录金额,更新客户状态,记录回访时间
  1824. * number_of_visitors 到店人数
  1825. * measure_room_img_type 量房图片类型
  1826. *
  1827. * 2022-10-03 逻辑修改,预约到店和确认到店时必须要有内场活动
  1828. *
  1829. */
  1830. public function addVisitlog()
  1831. {
  1832. $token = $this->request->token;
  1833. // 防止后台切换部门
  1834. $token['org_id'] = Employee::where('id', $token['employee_id'])->value('org_id');
  1835. $param = request()->only(['customer_id', 'type', 'next_contact_date', 'remark', 'img' => '', 'state', 'state_type' => '', 'money' => 0, 'aid' => 0, 'addtime' => date('Y-m-d H:i:s'), 'confirm_date' => '', 'weixin_media' => '', 'media_id' => '', 'starts' => 0, 'weixin_media1' => '', 'media_id1' => '', 'img1' => '', 'number_of_visitors' => 0, 'measure_room_img_type' => '', 'package' => '', 'deposit_mode' => 0, 'stay_length' => '', 'down_payment' => '', 'shop_id' => 0, 'actmeet_type' => 0, 'vlogid' => 0, 'document_field' => '', 'document_name' => '', 'estimated_sign_money' => 0]);
  1836. $param['confirm_date'] = $param['confirm_date'] ? $param['confirm_date'] . ' ' . date('H:i:s') : date('Y-m-d H:i:s');
  1837. $employeeTypeName = $token['org_type'] == 2 ? '设计师' : '销售';
  1838. $employeeType = $token['org_type'] == 2 ? 'designer_id' : 'employee_id';
  1839. //2022-10-04 逻辑修改,无效时无效原因必传remark
  1840. // if ($param['state'] == '无效' && empty($param['remark'])) return json(['code' => 1, 'msg' => '请填写无效原因']);
  1841. // 在跟进之前,增加了设计师必填判断,得先查一下设置
  1842. $state = Customer::changeState($param['state']);
  1843. $stateCheck = ['已到店' => 'daodian', '已到场' => 'daochang', '已量房' => 'liangfang', '已交定' => 'qiandan', '已签单' => 'zhuandan'];
  1844. if (in_array($state, ['已到店', '已到场', '已量房', '已交定', '已签单'])) {
  1845. $need_designer[] = ['root_id', '=', $token['root_org']];
  1846. $need_designer[] = ['name', '=', 'add_visit_log_need_designer'];
  1847. $need_designer_setting = Setting::where($need_designer)->findOrEmpty();
  1848. if (!$need_designer_setting->isEmpty()) {
  1849. $need_state = explode(',', $need_designer_setting['content']);
  1850. $input_state = $stateCheck[$state] ?? '';
  1851. if (!empty($input_state) && in_array($input_state, $need_state)) {
  1852. // 需要验证
  1853. $customer_find = Customer::find($param['customer_id']);
  1854. if (!empty($customer_find)) {
  1855. if (empty($customer_find['assigned_personnel'])) {
  1856. return json(['code' => 1, 'msg' => '请先指派设计师']);
  1857. }
  1858. $assigned_personnel = explode(',', $customer_find['assigned_personnel']);
  1859. $assigned_personnel_employee_org = Employee::where('id', 'in', $assigned_personnel)->column('org_id');
  1860. $assigned_personnel_org_type = Org::where('id', 'in', $assigned_personnel_employee_org)->column('org_type');
  1861. if (!in_array(2, $assigned_personnel_org_type)) {
  1862. return json(['code' => 1, 'msg' => '请先指派设计师']);
  1863. }
  1864. }
  1865. }
  1866. }
  1867. }
  1868. //2022-10-27 逻辑修改,跟进保护优化 如果后台设置了重复客户跟进保护规则 跟进到保护状态后其他业务员的此重复客户就不能在跟进了,但是可以置为无效
  1869. $forbiddenState = $this->forbiddenState($param['customer_id'], $param['state']);
  1870. if ($forbiddenState != false) return json(['code' => 1, 'msg' => $forbiddenState]);
  1871. //23-03-10 共有客户列表管理层查看下级部门所有员工指派的跟被指派的客户,同时还可以跟进修改查询客户的逻辑
  1872. if (isset($token['isManager']) && $token['isManager']) {
  1873. $team_orgs = orgSubIds($token['org_id']);
  1874. $org_employee = Employee::where([['org_id', 'in', $team_orgs], ['state', '=', '在职'], ['uid', '>', 0]])->column('id');
  1875. } else {
  1876. $org_employee = [$token['employee_id']];
  1877. }
  1878. $where = [
  1879. ['id', '=', $param['customer_id']],
  1880. ['state', '<>', '无效']
  1881. ];
  1882. $had = Customer::where($where)->where(function ($query) use ($org_employee) {
  1883. foreach ($org_employee as $k => $v) {
  1884. $query->whereOr([['employee_id|designer_id|assigned_personnel', 'find in set', $v]]);
  1885. }
  1886. })->find();
  1887. // $where = [
  1888. // ['id', '=', $param['customer_id']],
  1889. // ['state', '<>', '无效'],
  1890. // ['employee_id', '=', $token['employee_id']]
  1891. // ];
  1892. // //指派的客户
  1893. // $where_or = [['assigned_personnel', 'find in set', $token['employee_id']], ['id', '=', $param['customer_id']]];
  1894. // $where_or1 = [['designer_id', '=', $token['employee_id']], ['id', '=', $param['customer_id']]];
  1895. // $had = Customer::whereOr($where, $where_or, $where_or1)->find();
  1896. if (!$had) return json(['code' => 1, 'msg' => '添加失败,数据不存在']);
  1897. if ($had['died'] == 2) {
  1898. return json(['code' => 1, 'msg' => '客户死单,暂无法跟踪']);
  1899. }
  1900. //签单之后不能置为无效
  1901. if ($param['state'] == '无效') {
  1902. $is_orders = CustomerVisitLog::where([['state', 'in', CustomerVisitLog::changeState('已签单', 'chaos')], ['customer_id', '=', $had->id]])->count();
  1903. if ($is_orders) return json(['code' => 1, 'msg' => '该客户已签单,不能置为无效']);
  1904. }
  1905. //改为有效之后不能再改为待确认
  1906. if ($param['state'] == '待确认') {
  1907. if ($had->state != '待确认') return json(['code' => 1, 'msg' => '该客户已标记为有效,不能修改为待确认']);
  1908. }
  1909. // 撞单机制 从待确认变为有效
  1910. if (in_array($state, ['未到访', '已到店', '已到场', '已量房', '已交定', '已签单', '已卖卡']) && $had->state == '待确认') {
  1911. // 同部门能否重复录入开关设置
  1912. $empcrm_repeat[] = ['root_id', '=', $token['root_org']];
  1913. $empcrm_repeat[] = ['name', '=', 'empcrm_customer_repeat'];
  1914. $repeat_setting = Setting::where($empcrm_repeat)->findOrEmpty();
  1915. //判断同部门
  1916. if (!$repeat_setting->isEmpty()) {
  1917. $repeat_org = explode(',', $repeat_setting['content']);
  1918. if (!in_array($had['org_id'], $repeat_org)) {
  1919. $repeat_org = [$had['org_id']];
  1920. }
  1921. } else {
  1922. $repeat_org = [$had['org_id']];
  1923. }
  1924. // 需要验证
  1925. $not_sure = Customer::changeState('待确认', 'chaos');
  1926. $wuxiao = Customer::changeState('无效', 'chaos');
  1927. $phones_arr = array_filter([$had['phone'], $had['phone1'], $had['phone2']]);
  1928. $repeat_where[] = ['phone|phone1|phone2', 'in', $phones_arr];
  1929. $repeat_where[] = ['org_id', 'in', $repeat_org];
  1930. $repeat_where[] = ['state', 'not in', array_merge($not_sure, $wuxiao)];
  1931. $repeat_where[] = ['id', '<>', $param['customer_id']];
  1932. $customerExist = Customer::where($repeat_where)->field('id,employee_id,source_id');
  1933. if (!empty($customerExist)) {
  1934. foreach ($customerExist as $ex) {
  1935. if ($ex['employee_id'] != $had['employee_id']) {
  1936. //查询撞单客户渠道
  1937. $source_name = '';
  1938. if ($ex['source_id']) {
  1939. $source = CustomerSource::where(['id' => $ex['source_id']])->value('source');
  1940. $source_name = $source . '渠道客户';
  1941. }
  1942. $have_emp = Employee::where('id', '=', $ex['employee_id'])->value('name');
  1943. return json(['code' => 2, 'msg' => '该客户与员工' . $have_emp . $source_name . '撞单,无法标记有效']);
  1944. }
  1945. }
  1946. }
  1947. }
  1948. if (in_array($state, ['未到访', '已到店', '已到场', '已量房', '已交定', '已签单', '已卖卡']) && $had->state == '待确认') {
  1949. $valid_time = date('Y-m-d H:i:s');
  1950. if (!empty($param['confirm_date'])) {
  1951. $valid_time = $param['confirm_date'];
  1952. }
  1953. $had->valid_time = $valid_time;
  1954. }
  1955. // 如果是预约添加预约记录
  1956. $stateType = [
  1957. 1 => '到店',
  1958. 2 => '到场',
  1959. 3 => '量房'
  1960. ];
  1961. $yylf_state = CustomerVisitLog::changeState('预约量房', 'chaos');
  1962. $lf_state = CustomerVisitLog::changeState('已量房', 'chaos');
  1963. $yydc_state = CustomerVisitLog::changeState('预约活动', 'chaos');
  1964. $dc_state = CustomerVisitLog::changeState('已到场', 'chaos');
  1965. $yydd_state = CustomerVisitLog::changeState('预约到店', 'chaos');
  1966. $dd_state = CustomerVisitLog::changeState('已到店', 'chaos');
  1967. $check_state = array_merge($yylf_state, $lf_state, $yydc_state, $dc_state, $yydd_state, $dd_state);
  1968. if (in_array($param['state'], $check_state)) {
  1969. // 保护设置
  1970. $sub_setting = Setting::where([['root_id', '=', $token['root_org']], ['name', '=', 'subscribe_protected']])->findOrEmpty();
  1971. if (!$sub_setting->isEmpty()) { // 有设置
  1972. $setting_content = json_decode($sub_setting['content'], true);
  1973. $org_ids = orgSubIds($token['root_org']);
  1974. foreach ($setting_content as $k_s => $v_s) {
  1975. if (!empty($v_s['state']) && !empty($v_s['day']) && $v_s['state'] == 1) {
  1976. $continue = false;
  1977. $sub_state = 0;
  1978. $errmsg = '该客户在保护期内,无法提交';
  1979. $check_log = false;
  1980. $check_where = [];
  1981. switch ($k_s) {
  1982. case 'liangfang':
  1983. $sub_state = 3;
  1984. $visit_state = 1;
  1985. $check_log = true;
  1986. $check_where[] = ['org_id', 'in', $org_ids];
  1987. $check_where[] = ['addtime', '>', date('Y-m-d H:i:s', time() - 24 * 3600 * $v_s['day'])];
  1988. $check_where[] = ['employee_id', '<>', $token['employee_id']];
  1989. $check_where[] = ['state', 'in', $lf_state];
  1990. break;
  1991. case 'yliangfang': //预约量房
  1992. $sub_state = 3;
  1993. $visit_state = 0;
  1994. break;
  1995. case 'daodian':
  1996. $sub_state = 1;
  1997. $visit_state = 1;
  1998. $check_log = true;
  1999. $check_where[] = ['org_id', 'in', $org_ids];
  2000. $check_where[] = ['addtime', '>', date('Y-m-d H:i:s', time() - 24 * 3600 * $v_s['day'])];
  2001. $check_where[] = ['employee_id', '<>', $token['employee_id']];
  2002. $check_where[] = ['state', 'in', $dd_state];
  2003. break;
  2004. case 'ydaodian':
  2005. $sub_state = 1;
  2006. $visit_state = 0;
  2007. break;
  2008. case 'daochang':
  2009. $sub_state = 2;
  2010. $visit_state = 1;
  2011. $check_log = true;
  2012. $check_where[] = ['org_id', 'in', $org_ids];
  2013. $check_where[] = ['addtime', '>', date('Y-m-d H:i:s', time() - 24 * 3600 * $v_s['day'])];
  2014. $check_where[] = ['employee_id', '<>', $token['employee_id']];
  2015. $check_where[] = ['state', 'in', $dc_state];
  2016. break;
  2017. case 'ydaochang':
  2018. $sub_state = 2;
  2019. $visit_state = 0;
  2020. break;
  2021. default:
  2022. $continue = true;
  2023. break;
  2024. }
  2025. if ($continue) continue;
  2026. // “确认” 不受预约的限制
  2027. if (in_array($k_s, ['yliangfang', 'ydaodian', 'ydaochang']) && in_array($param['state'], array_merge($lf_state, $dd_state, $dc_state))) {
  2028. continue;
  2029. }
  2030. if (in_array($param['state'], array_merge($lf_state, $dd_state, $dc_state))) {
  2031. $errmsg = '该客户在保护期内,无法提交确认';
  2032. } elseif (in_array($param['state'], array_merge($yylf_state, $yydd_state, $yydc_state))) {
  2033. $errmsg = '该客户在保护期内,无法预约';
  2034. }
  2035. // 查询保护时间段内添加的预约量房记录
  2036. unset($v_where);
  2037. $v_where[] = ['org_id', 'in', $org_ids];
  2038. $v_where[] = ['addtime', '>', date('Y-m-d H:i:s', time() - 24 * 3600 * $v_s['day'])];
  2039. $v_where[] = ['employee_id', '<>', $token['employee_id']];
  2040. $v_where[] = ['type', '=', $sub_state];
  2041. $v_where[] = ['state', '=', $visit_state];
  2042. $sub_list = CustomersSubscribe::where($v_where)->select()->toArray();
  2043. if (!empty($sub_list)) {
  2044. $sub_list_ids = array_column($sub_list, 'customer_id');
  2045. $sub_employee_ids = array_column($sub_list, 'employee_id');
  2046. $sub_customers = Customer::where([['id', 'in', $sub_list_ids], ['employee_id', 'in', $sub_employee_ids]])->select()->toArray();
  2047. foreach ($sub_customers as $v) {
  2048. if (in_array($had->phone, [$v['phone'], $v['phone1'], $v['phone2']]) && $v['id'] != $had['id']) {
  2049. return json(['code' => 1, 'msg' => $errmsg]);
  2050. }
  2051. if (!empty($had->phone1) && in_array($had->phone1, [$v['phone'], $v['phone1'], $v['phone2']]) && $v['id'] != $had['id']) {
  2052. return json(['code' => 1, 'msg' => $errmsg]);
  2053. }
  2054. if (!empty($had->phone2) && in_array($had->phone2, [$v['phone'], $v['phone1'], $v['phone2']]) && $v['id'] != $had['id']) {
  2055. return json(['code' => 1, 'msg' => $errmsg]);
  2056. }
  2057. }
  2058. }
  2059. if ($check_log) {
  2060. $log_list = CustomerVisitLog::where($check_where)->select()->toArray();
  2061. $log_list_ids = array_column($log_list, 'customer_id');
  2062. $log_employee_ids = array_column($log_list, 'employee_id');
  2063. $log_customers = Customer::where([['id', 'in', $log_list_ids], ['employee_id', 'in', $log_employee_ids]])->select()->toArray();
  2064. foreach ($log_customers as $v) {
  2065. if (in_array($had->phone, [$v['phone'], $v['phone1'], $v['phone2']]) && $v['id'] != $had['id']) {
  2066. return json(['code' => 1, 'msg' => $errmsg]);
  2067. }
  2068. if (!empty($had->phone1) && in_array($had->phone1, [$v['phone'], $v['phone1'], $v['phone2']]) && $v['id'] != $had['id']) {
  2069. return json(['code' => 1, 'msg' => $errmsg]);
  2070. }
  2071. if (!empty($had->phone2) && in_array($had->phone2, [$v['phone'], $v['phone1'], $v['phone2']]) && $v['id'] != $had['id']) {
  2072. return json(['code' => 1, 'msg' => $errmsg]);
  2073. }
  2074. }
  2075. }
  2076. }
  2077. }
  2078. }
  2079. }
  2080. // 更改客户信息
  2081. $state = Customer::changeState($param['state']);
  2082. $orders = false;
  2083. //签单之后不能签单交定,可以跟进
  2084. if ($state == '已签单') {
  2085. $is = CustomerVisitLog::where([['state', 'in', CustomerVisitLog::changeState('已签单', 'chaos')], ['customer_id', '=', $had->id]])->count();
  2086. if ($is) {
  2087. //2022-11-11 业务修改 签单之后可以编辑签单金额,跟进记录增加 业务员修改签单金额为3000元
  2088. return $this->updateMoney($param);
  2089. // return json(['code' => 1, 'msg' => '该客户' . $state]);
  2090. }
  2091. $orders = true;
  2092. } elseif ($state == '已交定') {
  2093. $is = CustomerVisitLog::where([['state', 'in', CustomerVisitLog::changeState('已签单', 'chaos')], ['customer_id', '=', $had->id]])->count();
  2094. if ($is) {
  2095. return json(['code' => 1, 'msg' => '该客户已签单']);
  2096. }
  2097. $orders = true;
  2098. }
  2099. // 检测确认 到店/量房/交定/签单
  2100. $stateCheck = ['已到店' => 'visitShopConfirm', '已到场' => 'visitSiteConfirm', '已量房' => 'measureConfirm', '已交定' => 'depositConfirm', '已签单' => 'signConfirm'];
  2101. if ($token['org_type'] == 1 || ($token['org_type'] == 2 && $token['employee_id'] != $had['employee_id'])) {
  2102. foreach ($stateCheck as $ss => $set) {
  2103. if ($ss != $state) continue;
  2104. $setContent = Setting::where(['name' => $set, 'root_id' => $this->request->token['root_org'], 'state' => 1])->value('content');
  2105. // 没有找到则不限制
  2106. if ($setContent == null) continue;
  2107. $setContent = json_decode($setContent, true);
  2108. if (count($setContent) == 0) continue;
  2109. if (in_array($had->designer_id, $org_employee) && in_array('designer', $setContent))
  2110. continue;
  2111. if (in_array($had->employee_id, $org_employee) && in_array('salesperson', $setContent))
  2112. continue;
  2113. // 共有客户 销售人员
  2114. $assigned_personnel = explode(',', $had['assigned_personnel']);
  2115. $designer_arr = !empty($had['designer_id']) ? [$had['designer_id']] : [];
  2116. $salesperson = array_diff($assigned_personnel, $designer_arr);
  2117. if ($token['org_type'] == 1 && array_intersect($salesperson, $org_employee) && in_array('salesperson', $setContent))
  2118. continue;
  2119. // 多设计师指派时候,多的设计师会存在$salesperson 中
  2120. if ($token['org_type'] == 2 && array_intersect($salesperson, $org_employee) && in_array('designer', $setContent)) {
  2121. continue;
  2122. }
  2123. return json(['code' => 1, 'msg' => '操作失败,无确认权限']);
  2124. }
  2125. }
  2126. Db::startTrans();
  2127. if (!empty($state)) {
  2128. $had->state = $state;
  2129. }
  2130. $had->revisit_time = $param['next_contact_date'] . ' 00:00:00';
  2131. $had->last_contact_date = date('Y-m-d', time());
  2132. $had->updatetime = date('Y-m-d H:i:s', time());
  2133. if ($param['aid'] && $param['state'] == '预约活动') $had->aid = $param['aid'];
  2134. $had->fresh = 0;
  2135. // 交定产品
  2136. $dingMsg = '';
  2137. if ($had->state == '已交定') {
  2138. empty($param['money']) ?: $had->deposit_money = $param['money'];
  2139. empty($param['estimated_sign_money']) ?: $had->estimated_sign_money = $param['estimated_sign_money'];
  2140. if (!empty($param['package'])) {
  2141. $package = CustomerPackage::where([['root_id', '=', $this->request->token['root_org']], ['id', 'in', $param['package']]])->column('name', 'id');
  2142. if (!$package) return json(['code' => 1, 'msg' => '客户产品不存在']);
  2143. $had->package_id = implode(',', array_keys($package));
  2144. $dingMsg = ',交定金额:' . $param['money'] . '元,选择产品:' . implode(',', $package);
  2145. }
  2146. }
  2147. if ($had->state == '已签单' && !empty($param['money'])) $had->signed_money = $param['money'];
  2148. $had->save();
  2149. // 更新客户保护期
  2150. if ($param['state'] !== '无效' && !empty($state)) {
  2151. $log_state = CustomerVisitLog::changeState($state, 'chaos');
  2152. $vis_where[] = ['employee_id', '=', $this->request->token['employee_id']];
  2153. $vis_where[] = ['state', 'in', $log_state];
  2154. $vis_where[] = ['customer_id', '=', $param['customer_id']];
  2155. if (!empty($had['employee_time'])) {
  2156. $vis_where[] = ['addtime', '>', $had['employee_time']];
  2157. }
  2158. $v_count = CustomerVisitLog::where($vis_where)->count();
  2159. //查看此状态的跟踪记录,如果有数据,说明此客户在此员工这里已经经历过此状态,不再更新保护期
  2160. if (!$v_count) {
  2161. Customer::changeProtectedTo($had->id, $this->request->token['root_org']);
  2162. }
  2163. }
  2164. // 添加确定消息内容
  2165. $confirmMsg = '';
  2166. if (!empty($param['confirm_date'])) {
  2167. $confirmMsg = ', 时间:' . date('Y-m-d', strtotime($param['confirm_date']));
  2168. }
  2169. // 到店消息
  2170. $state_msg = '';
  2171. if ($param['state'] == '已到店') {
  2172. if ($param['shop_id']) {
  2173. $shop_name = Shop::where('id', $param['shop_id'])->value('name');
  2174. $state_msg = ',所到店面为:' . $shop_name;
  2175. }
  2176. }
  2177. // 备注
  2178. $employeeName = Employee::where(['id' => $this->request->token['employee_id']])->value('name');
  2179. $remark = $param['remark'];
  2180. if (empty($remark)) {
  2181. if (empty($state))
  2182. $remark = $employeeTypeName . $employeeName . '对客户进行了回访';
  2183. else
  2184. $remark = $employeeTypeName . $employeeName . '更新客户状态为' . $state . $state_msg . $confirmMsg . $dingMsg;
  2185. }
  2186. //2022-10-04 逻辑修改,无效时增加无效原因
  2187. if ($param['state'] == '无效' && !empty($param['remark'])) {
  2188. // $remark = $employeeTypeName . $employeeName . '更新客户状态为' . $state . $confirmMsg . ',原因是:' . $param['remark'] . $dingMsg;
  2189. }
  2190. // 添加追踪记录
  2191. $visitLog = [
  2192. 'customer_id' => $had->id,
  2193. 'type' => $param['type'],
  2194. 'next_contact_date' => !empty($param['next_contact_date']) ? $param['next_contact_date'] : null,
  2195. 'employee_id' => $this->request->token['employee_id'],
  2196. 'user_id' => $this->request->token['uid'],
  2197. 'remark' => $remark,
  2198. 'state' => $param['state'],
  2199. 'weixin_media' => $param['weixin_media'],
  2200. 'media_id' => $param['media_id'],
  2201. 'starts' => $param['starts'],
  2202. 'money' => $param['money'],
  2203. 'confirm_date' => $param['confirm_date'],
  2204. 'org_id' => $token['org_id'],
  2205. 'aid' => $param['aid'] ?: $had->aid,
  2206. 'weixin_media1' => $param['weixin_media1'],
  2207. 'media_id1' => $param['media_id1'],
  2208. 'customer_employee_id' => $had->employee_id,
  2209. 'customer_org_id' => Employee::where('id', $had->employee_id)->value('org_id'),
  2210. 'img' => $param['img'],
  2211. 'img1' => $param['img1'],
  2212. 'number_of_visitors' => $param['number_of_visitors'],
  2213. 'measure_room_img_type' => $param['measure_room_img_type'],
  2214. 'deposit_mode' => $param['deposit_mode'],
  2215. 'stay_length' => $param['stay_length'],
  2216. 'down_payment' => $param['down_payment'],
  2217. 'shop_id' => $param['shop_id'],
  2218. 'actmeet_type' => !empty($param['actmeet_type']) && $token['client_type'] == 'vL0CQQ' ? $param['actmeet_type'] : 0, //馨居尚才可记录见面方式
  2219. 'document_field' => $param['document_field'],
  2220. 'document_name' => $param['document_name']
  2221. ];
  2222. $returnvisit = ['customer_org_id' => $visitLog['customer_org_id']];
  2223. //2022-10-28 增加交定和签单凭证 凭证为图片 谈单时长talking_order_time
  2224. $deliverySignVoucher = request()->only(['delivery_media_id' => '', 'delivery_weixin_media' => '', 'sign_media_id' => '', 'sign_weixin_media' => '', 'delivery_img' => '', 'sign_img' => '', 'talking_order_time' => '']);
  2225. $visitLog = $visitLog + $deliverySignVoucher;
  2226. empty($param['img']) ?: $visitLog['img'] = $param['img'];
  2227. if (!empty($param['aid'])) {
  2228. // 检测活动是否存在
  2229. $existActivity = Activity::where([['id', '=', $param['aid']], ['root_id', '=', $this->request->token['root_org']]])->count();
  2230. if ($existActivity == 0) {
  2231. Db::rollback();
  2232. return json(['code' => 1, 'msg' => '活动不存在']);
  2233. }
  2234. $visitLog['aid'] = $param['aid'];
  2235. }
  2236. $visitLog = CustomerVisitLog::create($visitLog);
  2237. if ($orders) $this->preformance_tasks($state, $param['customer_id'], $param['money'], $visitLog->id); //计算业绩
  2238. // 如果是预约添加预约记录
  2239. if (strpos($visitLog->state, '预约') !== false) {
  2240. //2022-11-09 增加指派客户逻辑 同一个客户可以指派多人, 但是该客户在同一天内只能有一个预约,预约之后其他人就不能预约了,,,不同日期可以继续预约
  2241. $state = str_replace('预约', '', $visitLog->state);
  2242. // 查找是否已经预约
  2243. $hadSubscribe = CustomersSubscribe::where([
  2244. ['customer_id', '=', $had['id']],
  2245. // ['employee_id|designer_id', '=', $this->request->token['employee_id']],
  2246. ['subscribe_date', '=', date('Y-m-d', strtotime($param['confirm_date']))],
  2247. ['state', '=', 0]
  2248. ])->count();
  2249. $typeSubscribe = CustomersSubscribe::where([
  2250. ['customer_id', '=', $had['id']],
  2251. // ['employee_id|designer_id', '=', $this->request->token['employee_id']],
  2252. ['type', '=', array_search($state, $stateType)],
  2253. ['state', '=', 0]
  2254. ])->find();
  2255. $typeSubscribe = false; // 不是同一天的预约,同类型还可以预约
  2256. if ($hadSubscribe) {
  2257. Db::rollback();
  2258. return json(['code' => 1, 'msg' => '该客户在当前日期已有预约']);
  2259. } elseif ($typeSubscribe) {
  2260. Db::rollback();
  2261. return json(['code' => 1, 'msg' => '该客户已有' . $state . '预约, 预约日期' . $typeSubscribe->subscribe_date]);
  2262. } else {
  2263. $subscribe = [
  2264. 'customer_id' => $had['id'],
  2265. 'subscribe_date' => $param['confirm_date'],
  2266. 'employee_id' => $had->employee_id,
  2267. 'designer_id' => $had->designer_id,
  2268. 'type' => $state,
  2269. 'aid' => $param['aid'] ?: $had->aid,
  2270. 'org_id' => $had->org_id,
  2271. 'actmeet_type' => !empty($param['actmeet_type']) && $token['client_type'] == 'vL0CQQ' ? $param['actmeet_type'] : 0 //馨居尚才可记录见面方式
  2272. ];
  2273. CustomersSubscribe::create($subscribe);
  2274. }
  2275. }
  2276. //当设为无效时,记录当前操作人跟进的最后一次状态,此处在公海列表处展示
  2277. if ($param['state'] == '无效') {
  2278. $last_cvl = CustomerVisitLog::where('customer_id', $param['customer_id'])->with('employee')->order('addtime desc')->find();
  2279. //获取"无效"并进入公海之前的那次跟进记录的信息
  2280. if ($last_cvl) {
  2281. $before_pool = [
  2282. 'name' => $last_cvl->employee->name,
  2283. 'state' => $last_cvl->state,
  2284. 'addtime' => $last_cvl->addtime
  2285. ];
  2286. } else {
  2287. $before_pool = [
  2288. 'name' => Employee::find($this->request->token['employee_id'])->value('name'),
  2289. 'state' => '待确认',
  2290. 'addtime' => $had->addtime
  2291. ];
  2292. }
  2293. // 该客户预约中的状态置为无效
  2294. CustomersSubscribe::where([['customer_id', '=', $param['customer_id']], ['state', '=', 0]])->save(['state' => -1]);
  2295. //公海内是否存在该客户信息,存在则合并客户信息(phone、phone1、phone2)
  2296. $orgids = orgSubIds($token['root_org']);
  2297. $phone_arr = [];
  2298. !empty(trim($had['phone'])) ? $phone_arr[] = cypherphone(trim($had['phone'])) : '';
  2299. !empty(trim($had['phone1'])) ? $phone_arr[] = cypherphone(trim($had['phone1'])) : '';
  2300. !empty(trim($had['phone2'])) ? $phone_arr[] = cypherphone(trim($had['phone2'])) : '';
  2301. $phone_arr = array_filter($phone_arr);
  2302. $pool_condition = [
  2303. ['employee_id', '=', NULL],
  2304. ['is_resource', '=', 0],
  2305. ['org_id', 'in', $orgids],
  2306. ['phone|phone1|phone2', 'in', $phone_arr]
  2307. ];
  2308. $pool_crm = Customer::where($pool_condition)->column('id');
  2309. if (!empty($pool_crm)) {
  2310. //公海存在则删除
  2311. Customer::where([['id', 'in', $pool_crm]])->update(['delete_time' => time()]);
  2312. //关联回访记录修改
  2313. CustomerVisitLog::where([['customer_id', 'in', $pool_crm]])->update(['is_merge' => 1, 'customer_id' => $had['id']]);
  2314. CustomersSubscribe::where([['customer_id', 'in', $pool_crm]])->update(['is_merge' => 1, 'customer_id' => $had['id']]);
  2315. }
  2316. //增加无效记录
  2317. $vlglist = CustomerVisitLog::where([['customer_id', '=', $param['customer_id']], ['customer_employee_id', '=', $had->employee_id], ['state', 'not in', array_merge(CustomerVisitLog::changeState('待确认', 'chaos'), CustomerVisitLog::changeState('无效', 'chaos'))], ['save_portrait_field', 'NULL', null]])->count();
  2318. $invalidlog = [
  2319. 'customer_id' => $param['customer_id'],
  2320. 'employee_id' => $had->employee_id,
  2321. 'designer_id' => $had->designer_id ? $had->designer_id : 0,
  2322. 'org_id' => $had->org_id,
  2323. 'root_id' => $this->request->token['root_org'],
  2324. 'cus_addtime' => $had->sign_time,
  2325. 'visitlog_id' => $visitLog->id,
  2326. 'assigned_personnel' => $had->assigned_personnel ? $had->assigned_personnel : '',
  2327. 'source_id' => $had->source_id ? $had->source_id : 0,
  2328. 'status' => !empty($vlglist) ? 1 : 2,
  2329. 'cus_employee_time' => $had->employee_time,
  2330. 'is_resource' => $had->is_resource,
  2331. 'valid_time' => $had->valid_time
  2332. ];
  2333. CustomerInvalidLog::create($invalidlog);
  2334. Customer::where('id', $param['customer_id'])->update(['state' => 7, 'employee_id' => NULL, 'org_id' => $this->request->token['org_id'], 'is_resource' => 0, 'before_pool' => json_encode($before_pool), 'designer_id' => NULL, 'ext->ext6' => '', 'employee_time' => NULL, 'assigned_personnel' => NULL]);
  2335. // -------------------- 企业微信逻辑相关 start -----------------
  2336. // 判断是否绑定有企业微信外部联系人关系,并做解绑操作
  2337. $company_id = Company::where('root_id', '=', $this->request->token['root_org'])->value('id');
  2338. $company_setting = WeworksingleCompanySetting::where('company_id', '=', $company_id)->find();
  2339. if (!empty($company_setting)) {
  2340. $w_where['company_id'] = $company_id;
  2341. $w_where['employee_id'] = $this->request->token['employee_id'];
  2342. $w_where['customer_id'] = $param['customer_id'];
  2343. WeworksingleCustomer::where($w_where)->save(['customer_id' => 0]);
  2344. }
  2345. // -------------------- 企业微信逻辑相关 end -----------------
  2346. }
  2347. // //如果签单,默认交定
  2348. // if (strpos($param['state'], "签单") !== false) {
  2349. // trace(strpos($param['state'], "签单"));
  2350. // $lw[] = CustomerVisitLog::changeState(['state', '=', '交定']);
  2351. // $lw[] = ['customer_id', '=', $param['customer_id']];
  2352. // $check = CustomerVisitLog::where($lw)->find();
  2353. // if (!$check) {
  2354. // $l_visitlog = $visitLog->toArray();
  2355. // unset($l_visitlog['id']);
  2356. // $l_visitlog['state'] = '交定';
  2357. // $l_visitlog['remark'] = !empty($param['remark']) ? $param['remark'] : $employeeTypeName . $employeeName . '变更客户状态为交定';
  2358. // $new_visitlog = array_merge($param, $l_visitlog);
  2359. // $new_visitlog['money'] = 0; //直接签单默认交定金额为0
  2360. // $mr = CustomerVisitLog::create($new_visitlog);
  2361. // $this->preformance_tasks('已交定', $param['customer_id'], $param['money'], $mr->id); //计算业绩
  2362. // }
  2363. // }
  2364. if (in_array($param['state'], ['已到店', '已量房', '已到场'])) {
  2365. $state = str_replace('已', '', $param['state']);
  2366. $subscribe = CustomersSubscribe::where([['customer_id', '=', $had['id']], ['type', '=', array_search($state, $stateType)], ['state', '=', 0]])->find();
  2367. if (!empty($subscribe)) {
  2368. $subscribe->state = 1;
  2369. $subscribe->save();
  2370. } elseif ($param['aid'] && in_array($param['state'], ['已到场'])) { //没有预约可以直接确认到场
  2371. $this->activityState($param, $had);
  2372. }
  2373. }
  2374. if (in_array($param['state'], ['未到店', '未量房', '未到场'])) {
  2375. $state = str_replace('未', '', $param['state']);
  2376. $subscribe = CustomersSubscribe::where([['customer_id', '=', $had['id']], ['type', '=', array_search($state, $stateType)], ['state', '=', 0]])->find();
  2377. if (!empty($subscribe)) {
  2378. $subscribe->state = -1;
  2379. $subscribe->save();
  2380. }
  2381. $data = [
  2382. 'eid' => $had->employee_id,
  2383. 'org_id' => $returnvisit['customer_org_id'],
  2384. 'designer_id' => $had->designer_id,
  2385. 'confirm_date' => $param['confirm_date'],
  2386. 'customer_id' => $had->id,
  2387. 'return_visit' => $had->return_visit,
  2388. 'name' => $had->name,
  2389. 'state' => $param['state']
  2390. ];
  2391. $this->cancelReservation($data);
  2392. //取消预约后,待回访状态也要取消
  2393. $had->return_visit = 0;
  2394. $had->save();
  2395. }
  2396. //增加经纪人送积分功能
  2397. if ($had->agents_id && in_array($param['state'], ['已到店', '已交定', '已签单', '已量房'])) {
  2398. $state_type = CustomerPortraitFieldSelect::where('id', $param['state_type'])->value('name');
  2399. $this->agents_integral($had->agents_id, $param['state'], $had->id, $state_type, $param['money'], $param['state_type']);
  2400. }
  2401. // 微爆活动
  2402. if (in_array($param['state'], ['已到店', '已量房', '已到场', '已交定', '已签单'])) {
  2403. $activity_data['customer_id'] = $param['customer_id'];
  2404. $activity_data['employee_id'] = $had['employee_id'];
  2405. $activity_data['org_id'] = $had['org_id'];
  2406. switch ($param['state']) {
  2407. case '已到店':
  2408. $activity_data['type'] = 2;
  2409. break;
  2410. case '已量房':
  2411. $activity_data['type'] = 3;
  2412. break;
  2413. case '已交定':
  2414. $activity_data['type'] = 4;
  2415. break;
  2416. case '已签单':
  2417. $activity_data['type'] = 5;
  2418. break;
  2419. case '已到场':
  2420. $activity_data['type'] = 7;
  2421. break;
  2422. default:
  2423. break;
  2424. }
  2425. WechatActivityIntegral::addIntegral($activity_data, $token['root_org']);
  2426. }
  2427. Db::commit();
  2428. // $from_wework = input('from_wework', '', 'trim');
  2429. // if ($from_wework) {
  2430. // Console::call('download', ['customer', 'wework', (string)$token['root_org'], (string)$visitLog->id]);
  2431. // Console::call('download', ['customer1', 'wework', (string)$token['root_org'], (string)$visitLog->id]);
  2432. // } else {
  2433. // Console::call('download', ['customer', 'mini', (string)$token['root_org'], (string)$visitLog->id]);
  2434. // Console::call('download', ['customer1', 'mini', (string)$token['root_org'], (string)$visitLog->id]);
  2435. // }
  2436. //2022-10-28 更新交定/签单凭证
  2437. // if (in_array($param['state'], ['已交定', '已签单'])) {
  2438. // $deliveryType = $param['state'] == '已交定' ? 'delivery' : 'sign';
  2439. // // Console::call('download', [$deliveryType]);
  2440. // }
  2441. Console::call('medal', ['visit_log', (string)$this->request->token['employee_id'], (string)$this->request->token['root_org']]); //勋章
  2442. //给业务经理和设计是发送提醒消息回访
  2443. $data = ['phone' => $had->phone, 'org_id' => $returnvisit['customer_org_id'], 'state' => $param['state'], 'confirm_date' => $param['confirm_date'], 'name' => $had->name, 'designer_id' => $had->designer_id, 'eid' => $had->employee_id, 'customer_id' => $had->id, 'assigned_personnel' => $had->assigned_personnel, 'actmeet_type' => $param['actmeet_type']];
  2444. $index = uniqid();
  2445. Cache::set($index, $data, 60);
  2446. // $this->returnVisit($data);
  2447. Customer::where('id', $had->id)->update(['return_visit' => 1]); //跟进后改为待回访状态
  2448. $data['name'] = !empty($data['name']) ? $data['name'] : '';
  2449. $data['phone'] = substr_replace($data['phone'], '******', 3, 6);
  2450. //如果开关开启才发送消息
  2451. if (in_array($param['state'], $dd_state)) {
  2452. // 发送管理层模板消息
  2453. $msg = ['first' => '行为通知', 'keyword1' => '客户确认到店', 'keyword2' => "客户" . $data['name'] . "(" . $data['phone'] . ")确认到店", 'keyword3' => date('Y/m/d'), 'remark' => '请悉知'];
  2454. TmpMsg::sendMsgToLeader($msg, $token['org_id']);
  2455. }
  2456. if ($state == '已签单') {
  2457. // 发送管理层模板消息
  2458. $msg = ['first' => '行为通知', 'keyword1' => '客户签单', 'keyword2' => "客户" . $data['name'] . "(" . $data['phone'] . ")签单", 'keyword3' => date('Y/m/d'), 'remark' => '请悉知'];
  2459. TmpMsg::sendMsgToLeader($msg, $token['org_id']);
  2460. }
  2461. return json(['code' => 0, 'msg' => '跟进成功', 'index' => $index]);
  2462. }
  2463. /**
  2464. * 取消预约 给部门管理员和设计师发送消息提醒
  2465. * 张三取消了客户李四2020年8月1日的量房/到店/到场预约
  2466. */
  2467. public function cancelReservation($data)
  2468. {
  2469. $token = $this->request->token;
  2470. if ($data['return_visit'] == 1) {
  2471. $token['name'] = Employee::where([['id', '=', $data['eid']]])->value('name');
  2472. $eids = Employee::where([['root_id', '=', $token['root_org']], ['org_id', '=', $data['org_id']], ['state', '=', '在职'], ['is_manager', '=', 1], ['uid', '>', 0]])->column('id');
  2473. if ($data['designer_id']) array_push($eids, $data['designer_id']);
  2474. $date = date('Y-m-d', strtotime($data['confirm_date']));
  2475. $date = explode('-', $date);
  2476. $state = str_replace('未', '', $data['state']);
  2477. $msg = $token['name'] . '取消了客户' . $data['name'] . ',于' . $date[0] . '年' . $date[1] . '月' . $date[2] . '日的' . $state;
  2478. $eids = array_unique($eids);
  2479. foreach ($eids as $key => $val) {
  2480. event(new Msg($val, $msg, 'returnVisit', $data['customer_id']));
  2481. }
  2482. return true;
  2483. }
  2484. return false;
  2485. }
  2486. /**
  2487. * 消息提醒
  2488. * eid 客户所属业务员id,
  2489. * org_id 业务员部门id
  2490. * state 跟进状态
  2491. * name 业务员姓名
  2492. * designer_id 设计师id
  2493. * 01、客户邀约提醒管理层和指派的设计师。没指派设计师时,不提醒设计师,提醒管理层去指派设计师。在员工客户里面需要管理层回访的客户红色标签提示。
  2494. * 02、业务员确认客户量房、到店、到场、交定、签单,提醒管理层回访客户。
  2495. * a、管理层点击提醒,进入对应客户详情页面。进行客户跟踪。
  2496. * b、在员工客户里面需要管理层回访的客户红色标签提示。
  2497. * 2022-11-14 发送消息范围修改 ,操作人员和所在部门管理员发消息,同时如果是确认操作要给客户所属业务员及其管理发消息
  2498. */
  2499. public function returnVisit($index = '')
  2500. {
  2501. $data = Cache::get($index);
  2502. if (empty($index) || empty($data)) return true;
  2503. $token = $this->request->token;
  2504. $state1 = CustomerVisitLog::changeState('确认到店', 'chaos');
  2505. $state2 = CustomerVisitLog::changeState('确认量房', 'chaos');
  2506. $state3 = CustomerVisitLog::changeState('确认到场', 'chaos');
  2507. $state4 = CustomerVisitLog::changeState('交定', 'chaos');
  2508. $state5 = CustomerVisitLog::changeState('签单', 'chaos');
  2509. $make_state1 = array_merge($state1, $state2, $state3, $state4, $state5);
  2510. $make_state3 = array_merge($state1, $state2, $state3);
  2511. $state6 = CustomerVisitLog::changeState('预约到店', 'chaos');
  2512. $state7 = CustomerVisitLog::changeState('预约量房', 'chaos');
  2513. $state8 = CustomerVisitLog::changeState('预约活动', 'chaos');
  2514. $make_state2 = array_merge($state6, $state7, $state8);
  2515. //增加馨居尚预约活动见面方式
  2516. $actmeet_type = null;
  2517. //if($token['client_type'] == 'vL0CQQ' && !empty($data['actmeet_type'])){
  2518. if ($token['client_type'] == 'uwlxOU' && !empty($data['actmeet_type'])) {
  2519. if ($data['actmeet_type'] == 1) {
  2520. $actmeet_type = ',见面方式为外场活动';
  2521. } elseif ($data['actmeet_type'] == 2) {
  2522. $actmeet_type = ',见面方式为茶楼见面';
  2523. } elseif ($data['actmeet_type'] == 3) {
  2524. $actmeet_type = ',见面方式为网谈登记';
  2525. }
  2526. }
  2527. if (in_array($data['state'], $make_state2)) {
  2528. // $date = $office_date = date('Y-m-d', strtotime($data['confirm_date']));
  2529. $date = $office_date = date('Y-m-d');
  2530. $state = str_replace('预约', '', $data['state']);
  2531. $msg = $token['name'] . '预约了客户' . $data['name'] . ',预计于' . date('Y-m-d', strtotime($data['confirm_date'])) . $state;
  2532. $msg = !empty($actmeet_type) ? $msg . $actmeet_type : $msg;
  2533. $msg = $data['designer_id'] ? $msg : $msg . ',该客户暂未指派设计师,请及时指派!!!';
  2534. $type = '预约';
  2535. //预约状态发送消息范围 预约状态只给操作人员,操作人员部门经理,(设计师/业务员)发送消息
  2536. $eid_where1[] = ['org_id', '=', $token['org_id']];
  2537. } elseif (in_array($data['state'], $make_state1)) {
  2538. $date = $office_date = date('Y-m-d');
  2539. $state = str_replace('已', '', $data['state']);
  2540. $msg = $token['name'] . '确认客户' . $data['name'] . ',于' . $data['confirm_date'] . $state;
  2541. $msg = !empty($actmeet_type) ? $msg . $actmeet_type : $msg;
  2542. $type = '确认';
  2543. //确认状态发送消息范围 操作业务员和设计师及双方部门经理都要发送
  2544. $org_ids = Employee::where([['id', 'in', [$token['employee_id'], $data['designer_id']]]])->column('org_id');
  2545. $eid_where1[] = ['org_id', 'in', $org_ids];
  2546. } else {
  2547. return false;
  2548. }
  2549. $eid_where1[] = ['is_manager', '=', 1];
  2550. $eid_where1[] = ['state', '=', '在职'];
  2551. $eid_where1[] = ['uid', '>', 0];
  2552. $eid_where1[] = ['root_id', '=', $token['root_org']];
  2553. $eid_where2[] = ['id', 'in', [$data['eid'], $data['designer_id']]];
  2554. $eids = Employee::whereOr([$eid_where1, $eid_where2])->column('id,official_openid');
  2555. $official = array_column($eids, 'official_openid', 'id');
  2556. $eids = array_column($eids, 'id');
  2557. $new_actmeet_type = !empty($actmeet_type) ? trim($actmeet_type, ',') . ',' : '';
  2558. $param = ['name' => $data['name'], 'sale_name' => $token['name'], 'type' => $type, 'state' => $state, 'phone' => $data['phone'], 'date' => $office_date, 'actmeet_type' => $new_actmeet_type];
  2559. //查询公众号信息
  2560. $client_type = Miniprogram::where('root_id', $token['root_org'])->value('notify');
  2561. $param['client_type'] = $client_type;
  2562. $param['make_state2'] = $make_state2;
  2563. $param['eids'] = Employee::where([['root_id', '=', $token['root_org']]])->column('id');
  2564. //
  2565. $count_type = ($type == '确认') ? $make_state3 : $make_state2;
  2566. $param['count'] = CustomerVisitLog::where([['addtime', 'like', '%' . date('Y-m-d') . '%'], ['state', 'in', $count_type], ['employee_id', 'in', $param['eids']]])->count();
  2567. //公众号appid
  2568. $miniAppid = Miniprogram::where('root_id', $token['root_org'])->find()->appid;
  2569. foreach ($eids as $key => $val) {
  2570. event(new Msg($val, $msg, 'returnVisit', $data['customer_id']));
  2571. $param['count'] += 1;
  2572. if (!empty($official[$val])) {
  2573. //公众号消息
  2574. $param['employee_id'] = $val;
  2575. $param['cid'] = $data['customer_id'];
  2576. $param['official_openid'] = $official[$val];
  2577. $param['miniAppid'] = $miniAppid;
  2578. $this->sendOfficialAccount($param);
  2579. }
  2580. }
  2581. return true;
  2582. }
  2583. /**
  2584. * 发送公众号消息
  2585. * $data['name'] 客户姓名
  2586. * $data['type'] 预约/确认
  2587. * $data['state'] 到店,量房,到场
  2588. * $data['phone'] 客户电话
  2589. * $data['sale_name'] 业务员姓名
  2590. * $data['employee_id] 业务员id
  2591. * $data['date'] 日期
  2592. */
  2593. public function sendOfficialAccount($data)
  2594. {
  2595. if (in_array($data['state'], ['交定', '签单'])) return true;
  2596. $token = $this->request->token;
  2597. $dates = date('Ymd', strtotime($data['date']));
  2598. // $client_type = Miniprogram::where('root_id', $token['root_org'])->value('notify');
  2599. $client_type = $data['client_type'];
  2600. $number = $dates . $data['count'];
  2601. $data['page'] = "/pages/index/index?office_type=cread&cid=" . $data['cid'] . '&clientype=' . $client_type;
  2602. if ($data['type'] == '预约') {
  2603. $data['param'] = [
  2604. 'first' => '预约提醒', //标题
  2605. 'keyword1' => $number, //预约编号
  2606. 'keyword2' => $data['type'] . $data['name'] . $data['state'], //预约项目
  2607. 'keyword3' => $data['date'], //预约时间
  2608. 'keyword4' => substr_replace($data['phone'], '******', 3, 6),
  2609. 'keyword5' => $data['name'], //预约姓名
  2610. 'remark' => '您好,业务员' . $data['sale_name'] . '新增一次预约记录,' . $data['actmeet_type'] . '请及时回访' //电话
  2611. ];
  2612. } elseif ($data['type'] == '确认') {
  2613. $data['param'] = [
  2614. 'first' => '确认提醒', //标题
  2615. 'keyword1' => $number, //预约编号
  2616. 'keyword2' => $data['type'] . $data['name'] . $data['state'], //预约项目
  2617. 'keyword3' => $data['date'], //预约时间
  2618. 'keyword4' => substr_replace($data['phone'], '******', 3, 6), //预约电话
  2619. 'keyword5' => $data['name'], //预约姓名
  2620. 'remark' => '您好,业务员' . $data['sale_name'] . '确认' . $data['name'] . $data['state'] . ',' . $data['actmeet_type'] . '请及时回访' //电话
  2621. ];
  2622. }
  2623. $msg = [
  2624. 'type' => 'returnVisit',
  2625. 'employee_id' => $data['employee_id'],
  2626. 'official_openid' => $data['official_openid'],
  2627. 'root_id' => $token['root_org'],
  2628. 'miniAppid' => $data['miniAppid']
  2629. ];
  2630. EmployeeMsg::temploateMsg($msg, $data);
  2631. return true;
  2632. }
  2633. /**
  2634. * 计算业绩任务
  2635. * 2023/8/7 业绩算在客户所属人身上
  2636. */
  2637. public function preformance_tasks($state, $customer_id, $money = 0, $vislog_id)
  2638. {
  2639. $token = request()->token;
  2640. $customer = Customer::find($customer_id);
  2641. $org_id = Employee::where('id', $customer['employee_id'])->value('org_id');
  2642. if ($state == '已交定') {
  2643. $w2[] = ['customer_id', '=', $customer_id];
  2644. $w2[] = ['state', 'in', CustomerVisitLog::changeState('已交定', 'chaos')];
  2645. $w2[] = ['customer_employee_id', '=', $customer['employee_id']];
  2646. $w2[] = ['customer_org_id', '=', $org_id];
  2647. //切换部门重复交定仍然算业绩
  2648. $check = CustomerVisitLog::where($w2)->count(); //没有交定过计算业绩
  2649. if ($check == 1) {
  2650. $time = date('Y-m-d H:i:s');
  2651. //查询进行中的指派到所属部门的所有进度
  2652. // $w[] = ['org_id','=',$token['org_id']];
  2653. $w[] = ['root_id', '=', $token['root_org']];
  2654. $w[] = ['start_date', '<=', $time];
  2655. $w[] = ['end_date', '>=', $time];
  2656. $w[] = ['is_deposit', '=', 1];
  2657. $preformance_tasks = PreformanceTasksModel::where($w)->column('id');
  2658. $w1[] = ['root_id', '=', $token['root_org']];
  2659. $w1[] = ['org_id', '=', $org_id];
  2660. $w1[] = ['performance_tasks_id', 'in', $preformance_tasks];
  2661. $w1[] = ['is_deposit', '=', 1];
  2662. //指派到自己部门
  2663. $pid = PreformanceTasksOrg::where($w1)->group('performance_tasks_id')->column('*');
  2664. $w4[] = ['id', 'in', array_column($pid, 'performance_tasks_id')];
  2665. $model = PreformanceTasksModel::where($w4)->column('*');
  2666. foreach ($model as $k => $v) {
  2667. $u = [];
  2668. $u['ok_deposit'] = $v['ok_deposit'] + 1;
  2669. $u['customer_visit_log_id'] = $v['customer_visit_log_id'] ? $v['customer_visit_log_id'] . ',' . $vislog_id : $vislog_id;
  2670. PreformanceTasksModel::where('id', $v['id'])->update($u);
  2671. unset($u);
  2672. }
  2673. PreformanceTasksOrg::where($w1)->inc('ok_deposit')->update();
  2674. }
  2675. } elseif ($state == '已签单') {
  2676. $w2[] = ['customer_id', '=', $customer_id];
  2677. $w2[] = ['state', 'in', CustomerVisitLog::changeState('已签单', 'chaos')];
  2678. $w2[] = ['customer_employee_id', '=', $customer['employee_id']];
  2679. $check = CustomerVisitLog::where($w2)->count(); //没有交定过计算业绩
  2680. if ($check == 1) {
  2681. $time = date('Y-m-d H:i:s');
  2682. //查询进行中的指派到所属部门的所有进度
  2683. // $w[] = ['org_id','=',$token['org_id']];
  2684. $w[] = ['root_id', '=', $token['root_org']];
  2685. $w[] = ['start_date', '<=', $time];
  2686. $w[] = ['end_date', '>=', $time];
  2687. $w[] = ['is_money', '=', 1];
  2688. $preformance_tasks = PreformanceTasksModel::where($w)->column('id');
  2689. $w1[] = ['root_id', '=', $token['root_org']];
  2690. $w1[] = ['org_id', '=', $org_id];
  2691. $w1[] = ['performance_tasks_id', 'in', $preformance_tasks];
  2692. $w1[] = ['is_money', '=', 1];
  2693. //指派到自己部门
  2694. $pid = PreformanceTasksOrg::where($w1)->group('performance_tasks_id')->column('*');
  2695. $w4[] = ['id', 'in', array_column($pid, 'performance_tasks_id')];
  2696. $model = PreformanceTasksModel::where($w4)->column('*');
  2697. foreach ($model as $k => $v) {
  2698. $u = [];
  2699. $u['ok_money'] = $v['ok_money'] + $money;
  2700. $u['customer_visit_log_id'] = $v['customer_visit_log_id'] ? $v['customer_visit_log_id'] . ',' . $vislog_id : $vislog_id;
  2701. PreformanceTasksModel::where('id', $v['id'])->update($u);
  2702. unset($u);
  2703. }
  2704. PreformanceTasksOrg::where($w1)->inc('ok_money', (int) $money)->update();
  2705. }
  2706. }
  2707. return 1;
  2708. }
  2709. /**
  2710. * 没有预约活动,跟进时传了aid和state='预约活动'
  2711. * 没有预约可以直接确认到场
  2712. * 补全数据添加预约和的追踪记录
  2713. */
  2714. public function activityState($param, $had)
  2715. {
  2716. $employeeTypeName = $this->request->token['org_type'] == 2 ? '设计师' : '销售';
  2717. // 备注
  2718. $employeeName = Employee::where(['id' => $this->request->token['employee_id']])->value('name');
  2719. $remark = $param['remark'];
  2720. if (empty($remark)) {
  2721. $remark = $employeeTypeName . $employeeName . '对客户进行了回访';
  2722. }
  2723. //预约记录
  2724. $visitLog = [
  2725. 'customer_id' => $had->id,
  2726. 'type' => $param['type'],
  2727. 'next_contact_date' => !empty($param['next_contact_date']) ? $param['next_contact_date'] : date('Y-m-d'),
  2728. 'employee_id' => $this->request->token['employee_id'],
  2729. 'user_id' => $this->request->token['uid'],
  2730. 'remark' => $remark,
  2731. 'state' => 6,
  2732. 'weixin_media' => '',
  2733. 'media_id' => '',
  2734. 'starts' => $param['starts'],
  2735. 'money' => $param['money'],
  2736. 'confirm_date' => $param['confirm_date'],
  2737. 'org_id' => $this->request->token['org_id'],
  2738. 'aid' => $param['aid'],
  2739. 'weixin_media1' => '',
  2740. 'media_id1' => '',
  2741. 'customer_employee_id' => $had->employee_id,
  2742. 'customer_org_id' => Employee::where('id', $had->employee_id)->value('org_id')
  2743. ];
  2744. CustomerVisitLog::create($visitLog);
  2745. //
  2746. $subscribe = [
  2747. 'customer_id' => $had['id'],
  2748. 'subscribe_date' => $param['confirm_date'],
  2749. 'employee_id' => $had->employee_id,
  2750. 'designer_id' => $had->designer_id,
  2751. 'type' => 2,
  2752. 'aid' => $param['aid'],
  2753. 'org_id' => $visitLog['customer_org_id'],
  2754. 'state' => 1
  2755. ];
  2756. CustomersSubscribe::create($subscribe);
  2757. return 1;
  2758. }
  2759. /**
  2760. * 客户意向折线图
  2761. */
  2762. public function line_chart()
  2763. {
  2764. $customerId = $this->request->param('customer_id');
  2765. $token = $this->request->token;
  2766. $w[] = ['id', '=', $customerId];
  2767. $w[] = ['employee_id', '=', $token['employee_id']];
  2768. $check = Customer::where($w)->findOrEmpty();
  2769. if ($check->isEmpty()) return json(['code' => 0, 'data' => [], 'msg' => '操作成功']);
  2770. $w1[] = ['customer_id', '=', $customerId];
  2771. $w1[] = ['starts', '>', 0];
  2772. $ids = CustomerVisitLog::where($w1)->order('id desc')->limit(30)->column('id');
  2773. $w1[] = ['id', 'in', $ids];
  2774. $row = CustomerVisitLog::where($w1)->order('id asc')->column('starts');
  2775. return json(['code' => 0, 'data' => $row, 'msg' => '操作成功']);
  2776. }
  2777. /**
  2778. * 重新跟踪
  2779. */
  2780. public function transfer()
  2781. {
  2782. $customerId = $this->request->param('customer_id');
  2783. $condition = [
  2784. ['id', '=', $customerId],
  2785. ['state', 'in', Customer::changeState('无效', 'chaos')]
  2786. ];
  2787. $had = Customer::where($condition)->find();
  2788. if (!$had)
  2789. return json(['code' => 0, 'msg' => '添加失败,数据不存在或已被分配,请刷新后再试']);
  2790. $had->state = '未到访';
  2791. // 原客服获取
  2792. $oldEmployeeName = Employee::where([['id', '=', $had->employee_id]])->value('name');
  2793. $param = [
  2794. 'customer_id' => $customerId,
  2795. 'type' => '重新跟踪',
  2796. 'remark' => '公共库提取,重新跟踪, 原客服为:' . $oldEmployeeName,
  2797. 'employee_id' => $this->request->token['employee_id'],
  2798. 'user_id' => $this->request->token['uid'],
  2799. 'state' => '未到访',
  2800. ];
  2801. CustomerVisitLog::create($param);
  2802. $had->employee_id = $this->request->token['employee_id'];
  2803. $had->employee_time = date('Y-m-d H:i:s', time()); //更新员工获取此客户时间
  2804. $had->save();
  2805. // 更新客户保护期
  2806. Customer::changeProtectedTo($customerId, $this->request->token['root_org']);
  2807. return json(['code' => 0, 'msg' => '重新跟踪成功']);
  2808. }
  2809. /**
  2810. * 客户详情
  2811. */
  2812. public function detail()
  2813. {
  2814. $id = $this->request->param('id');
  2815. $share = input('share');
  2816. $token = $this->request->token;
  2817. // 查询自己的客户
  2818. $condition1 = [
  2819. ['employee_id', '=', $this->request->token['employee_id']],
  2820. ['id', '=', $id]
  2821. ];
  2822. $condition2 = [
  2823. ['designer_id', '=', $this->request->token['employee_id']],
  2824. ['id', '=', $id]
  2825. ];
  2826. // 或者查询公司内,无效的客户
  2827. // 公司部门列表获取
  2828. $orgIdsList = Org::where([['path', 'like', $this->request->token['root_org'] . '-%']])->column('id');
  2829. $condition3 = [
  2830. ['id', '=', $id],
  2831. ['org_id', 'in', $orgIdsList],
  2832. ['state', 'in', Customer::changeState('无效', 'chaos')]
  2833. ];
  2834. // 或者是公司领导看员工的客户
  2835. if (isset($this->request->token['isManager']) && $this->request->token['isManager']) {
  2836. $team_orgs = (new Org())->getChildOrg($this->request->token['org_id']);
  2837. if ($this->request->token['org_type'] == 1) {
  2838. $condition4 = [
  2839. ['org_id', 'in', $team_orgs],
  2840. ['id', '=', $id]
  2841. ];
  2842. $orCondition = [$condition1, $condition2, $condition3, $condition4];
  2843. } else {
  2844. $empIdList = Employee::where([['org_id', 'in', $team_orgs]])->column('id');
  2845. $condition4 = [
  2846. ['designer_id', 'in', $empIdList],
  2847. ['id', '=', $id]
  2848. ];
  2849. $condition5 = [
  2850. ['employee_id', 'in', $empIdList],
  2851. ['id', '=', $id]
  2852. ];
  2853. $orCondition = [$condition1, $condition2, $condition3, $condition4, $condition5];
  2854. }
  2855. } else {
  2856. $orCondition = [$condition1, $condition2, $condition3];
  2857. }
  2858. //指派给自己的员工
  2859. $where_or = [['assigned_personnel', 'find in set', $token['employee_id']], ['id', '=', $id]];
  2860. $orCondition[] = $where_or;
  2861. //共有客户管理层查看其他部门的客户
  2862. if ($share && isset($this->request->token['isManager']) && $this->request->token['isManager']) $orCondition[] = [['org_id', 'in', $orgIdsList], ['id', '=', $id]];
  2863. $data = Customer::with(['source', 'designer' => function ($query) {
  2864. $query->field('id,name,headimgurl,org_id,uid');
  2865. }, 'employee' => function ($query) {
  2866. $query->withField(['uid', 'id', 'headimgurl', 'is_manager', 'image_photo', 'is_newbie', 'name', 'nickname', 'org_id', 'position', 'role', 'root_id']);
  2867. }])->whereOr($orCondition)->find();
  2868. if (empty($data)) return json(['code' => 1, 'msg' => '数据权限发生变化,无法查看']);
  2869. // if ($data->aid) {
  2870. // $data->date = CustomerVisitLog::where([['aid', '=', $data->aid], ['customer_id', '=', $id], ['state', '=', $data->state]])->value('next_contact_date') ?: '';
  2871. // } else {
  2872. // $data->date = '';
  2873. // }
  2874. // 获取设计师部门
  2875. if (!empty($data->designer))
  2876. $data->designer->orgName = Org::where(['id' => $data->designer->org_id])->value('name');
  2877. if ($data->employee_id == $this->request->token['employee_id'] && $data->fresh == 1) {
  2878. $data->fresh = 2;
  2879. $data->save();
  2880. }
  2881. $count = CustomerVisitLog::where('customer_id', $id)->count();
  2882. $data['visit_count'] = $count;
  2883. // 首付款
  2884. $data['down_payment'] = CustomerVisitLog::where([['customer_id', '=', $id], CustomerVisitLog::changeState(['state', '=', '签单'])])->order('addtime desc')->value('down_payment');
  2885. $data['deposit'] = CustomerVisitLog::where([['customer_id', '=', $id], CustomerVisitLog::changeState(['state', '=', '交定'])])->order('addtime desc')->value('confirm_date');
  2886. $data['sign'] = CustomerVisitLog::where([['customer_id', '=', $id], CustomerVisitLog::changeState(['state', '=', '签单'])])->order('addtime desc')->value('addtime');
  2887. $data['deposit_mode'] = CustomerVisitLog::where([['customer_id', '=', $id], CustomerVisitLog::changeState(['state', '=', '交定'])])->order('addtime desc')->value('deposit_mode');
  2888. // 量房、活动、到店次数统计
  2889. $data['liangfangNum'] = CustomerVisitLog::where([['customer_id', '=', $id], CustomerVisitLog::changeState(['state', '=', '确认量房'])])->count();
  2890. $data['activityNum'] = CustomerVisitLog::where([['customer_id', '=', $id], CustomerVisitLog::changeState(['state', '=', '确认到场'])])->count();
  2891. $data['daodianNum'] = CustomerVisitLog::where([['customer_id', '=', $id], CustomerVisitLog::changeState(['state', '=', '确认到店'])])->count();
  2892. $data['deposit_count'] = CustomerVisitLog::where([['customer_id', '=', $id], ['state', 'in', CustomerVisitLog::changeState('已交定', 'chaos')]])->count();
  2893. $data['square'] = floatval($data['square']);
  2894. if ($data['employee_id'] != $this->request->token['employee_id'] && (empty($data['designer']) || $data['designer']['id'] != $this->request->token['employee_id'])) $data['editAble'] = false;
  2895. else $data['editAble'] = true;
  2896. // 设计师头像
  2897. if ($data['designer'])
  2898. $data['designer']['headimgurl'] = User::where('id', $data['designer']['uid'])->value('headimgurl');
  2899. // 查询客户是否标星
  2900. $data['addtoptime'] = CustomerTop::where(['customer_id' => $id, 'employee_id' => $this->request->token['employee_id'], 'root_id' => request()->token['root_org']])->value('addtoptime');
  2901. // 查询客户是否有预约
  2902. $data['subscirbe'] = CustomersSubscribe::with(['activity' => function ($query) {
  2903. $query->field('id,title');
  2904. }])->where([['customer_id', '=', $id], ['state', '=', 0]])->field('id,state,type,subscribe_date,aid')->select()->toArray();
  2905. //查询我最近一次的签单和交定金额
  2906. $state = CustomerVisitLog::changeState('已交定', 'chaos');
  2907. $data['deposit_money1'] = CustomerVisitLog::where([['customer_id', '=', $id], ['state', 'in', $state]])->order('id desc')->value('money') ?: 0;
  2908. $data['money'] = $data->getData('signed_money');
  2909. //查询最近一次签单的记录id
  2910. $state = CustomerVisitLog::changeState('已签单', 'chaos');
  2911. $data['vlogid'] = CustomerVisitLog::where([['customer_id', '=', $id], ['state', 'in', $state]])->order('id desc')->value('id') ?: 0;
  2912. // 查询今日发送短信数量
  2913. $data['smsNum'] = CustomerSmsLog::where([['sendTime', 'between', [date('Ymd') . '000000', date('Ymd', strtotime('+1 day')) . '000000']], ['employee_id', '=', $this->request->token['employee_id']], ['state', '=', 0]])->count();
  2914. // 如果线索值为空,查询线索表跟本用户手机号一样并员工id一样,进行线索绑定
  2915. if (empty($data['clue_id']) && $data->employee_id == $this->request->token['employee_id']) {
  2916. $clue_data = CustomerClue::where([['employee_id', '=', $this->request->token['employee_id']], ['phone', '=', $data['phone']]])->find();
  2917. if (!empty($clue_data)) {
  2918. $data['clue_id'] = $clue_data['id'];
  2919. $data->clue_id = $clue_data['id'];
  2920. $data->save();
  2921. $clue_data->state = 1;
  2922. $clue_data->save();
  2923. }
  2924. }
  2925. // 企业微信外部联系人
  2926. $external_customer = WeworksingleCustomer::where('customer_id', '=', $id)->findOrEmpty();
  2927. if (!$external_customer->isEmpty()) {
  2928. $data['external_userid'] = $external_customer['external_userid'];
  2929. $data['external_username'] = $external_customer['name'];
  2930. } else {
  2931. $data['external_userid'] = '';
  2932. $data['external_username'] = '';
  2933. }
  2934. //业务员头像
  2935. if (!empty($data['employee']) && !$data['employee']['headimgurl'])
  2936. $data['employee']['headimgurl'] = User::where('id', $data['employee']['uid'])->value('headimgurl');
  2937. //指派人员头像
  2938. if ($data->assigned_personnel) {
  2939. $assigned_personnel = explode(',', $data->assigned_personnel);
  2940. $assigned_business = array_diff($assigned_personnel, [$data['designer_id']]);
  2941. $assigned_employee = Employee::with(['org', 'user'])->where('id', 'in', $assigned_business)->select()->toArray();
  2942. $assigned_employee_list = [];
  2943. foreach ($assigned_employee as $ass) {
  2944. $assigned_employee_list[] = [
  2945. 'name' => $ass['name'],
  2946. 'headimgurl' => !empty($ass['user']) ? $ass['user']['headimgurl'] : '',
  2947. 'orgName' => !empty($ass['org']) ? $ass['org']['name'] : ''
  2948. ];
  2949. }
  2950. $data['assigned_personnel_list'] = $assigned_employee_list;
  2951. $uids = Employee::where([['id', 'in', $data->assigned_personnel]])->column('uid');
  2952. $data['assigned_personnel_imgs'] = User::where([['id', 'in', $uids]])->column('headimgurl');
  2953. } else {
  2954. $data['assigned_personnel_imgs'] = [];
  2955. $data['assigned_personnel_list'] = [];
  2956. }
  2957. //2022-11-09 增加业务逻辑 在团队客户中高层和中高层领导不可以回访和跟进 ,只有基层领导可以
  2958. if (!$token['isManager']) {
  2959. $data['is_manager'] = 0;
  2960. } else {
  2961. //判断是否是基层领导 , 最底层部门的管理员
  2962. $child = Org::where('pid', $token['org_id'])->field('id')->findOrEmpty();
  2963. $data['is_manager'] = $child->isEmpty() ? 1 : 0;
  2964. }
  2965. // 有效申请
  2966. // 申请配置
  2967. $settingObj = Setting::where(['root_id' => $this->request->token['root_org'], 'name' => 'valid_check_person'])->find();
  2968. if ($settingObj) {
  2969. $setting = explode(',', $settingObj['content']);
  2970. if (in_array('xiaoshou', $setting) && $data['employee_id'] == $this->request->token['employee_id']) {
  2971. $data['valid_check'] = true;
  2972. } elseif (in_array('sheji', $setting) && $data['designer_id'] == $this->request->token['employee_id']) {
  2973. $data['valid_check'] = true;
  2974. } else {
  2975. $data['valid_check'] = false;
  2976. }
  2977. // 检测是否已经提交
  2978. $check = CustomerStateCheck::where(['customer_id' => $id, 'root_id' => $this->request->token['root_org']])->find();
  2979. if ($check) $data['check_state'] = $check->check_state;
  2980. else $data['check_state'] = -1;
  2981. } else {
  2982. $data['valid_check'] = false;
  2983. }
  2984. return json(['code' => 0, 'data' => $data]);
  2985. }
  2986. /**
  2987. * 判断客户业务员是否重复
  2988. *
  2989. */
  2990. public function checkRepeat()
  2991. {
  2992. $param = $this->request->param(['customer_id' => 0, 'employee_id' => 0]);
  2993. $phone = Customer::where('employee_id', $param['employee_id'])->column('phone,phone1,phone2');
  2994. $c_phone = Customer::where('id', $param['customer_id'])->column('phone,phone1,phone2');
  2995. if (empty($phone) || empty($c_phone)) return json(['code' => 0, 'data' => 1]);
  2996. $phones = [];
  2997. foreach ($phone as $v) {
  2998. $phones = array_merge($phones, array_values($v));
  2999. }
  3000. $phones = array_filter($phones);
  3001. $res = array_intersect($phones, array_filter($c_phone[0]));
  3002. return json(['code' => 0, 'data' => $res ? 0 : 1]);
  3003. }
  3004. /**
  3005. * 房源信息
  3006. */
  3007. public function house()
  3008. {
  3009. $id = $this->request->param('id');
  3010. $condition = [
  3011. ['id', '=', $id],
  3012. ['employee_id', '=', $this->request->token['employee_id']]
  3013. ];
  3014. Db::startTrans();
  3015. try {
  3016. $customer = Customer::where($condition)->lock(true)->find();
  3017. if (empty($customer)) return json(['code' => 1, 'msg' => '数据不存在']);
  3018. $param = request()->only(['community', 'area', 'house_type', 'delivery_time', 'estimate_date', 'budget', 'style', 'house_status']);
  3019. $data = [
  3020. 'community_name' => $param['community'],
  3021. 'square' => $param['area'],
  3022. 'house_type' => $param['house_type'],
  3023. 'house_status' => $param['house_status'],
  3024. 'house_delivery_time' => $param['delivery_time'],
  3025. 'plan_deco_time' => $param['estimate_date'],
  3026. 'budget' => $param['budget'],
  3027. 'deco_style' => $param['style']
  3028. ];
  3029. $data = array_filter($data);
  3030. if (empty($data))
  3031. return json(['code' => 1, 'msg' => '请输入要保存的信息']);
  3032. $customer->save($data);
  3033. Db::commit();
  3034. } catch (Exception $e) {
  3035. // 回滚事务
  3036. Db::rollback();
  3037. return json(['code' => 1, 'msg' => $e->getMessage()]);
  3038. }
  3039. return json(['code' => 0, 'msg' => '保存成功']);
  3040. }
  3041. public function forhouseinfo()
  3042. {
  3043. $communities = Community::field('id,name')->where([['root_id', '=', request()->token['root_org']], ['type', '=', 0]])->select();
  3044. $decostyles = Decostyle::field('id,name')->where([['root_id', '=', request()->token['root_org']], ['type', '=', 0]])->select();
  3045. $data = [
  3046. 'communities' => $communities,
  3047. 'decostyles' => $decostyles
  3048. ];
  3049. return json(['code' => 0, 'msg' => '获取成功', 'data' => $data]);
  3050. }
  3051. public function invalidCustomer()
  3052. {
  3053. $request = request();
  3054. $param = $request->param();
  3055. $customer_id = $param['customer_id'];
  3056. $employee_id = $this->request->token['employee_id'];
  3057. $tracking = new CustomerVisitLog();
  3058. $data = [
  3059. 'customer_id' => $customer_id,
  3060. 'employee_id' => $employee_id,
  3061. 'state' => '无效'
  3062. ];
  3063. $tracking->save($data);
  3064. //
  3065. if (Customer::where('id', $customer_id)->update(['state' => 7, 'employee_id' => NULL, 'is_resource' => 0])) {
  3066. return json(['code' => 0, 'msg' => '无效成功']);
  3067. } else {
  3068. return json(['code' => 1, 'msg' => '无效失败']);
  3069. }
  3070. }
  3071. ////////////
  3072. /// 资源库
  3073. ////////////
  3074. public function resource_log_list()
  3075. {
  3076. $request = request();
  3077. $root_id = request()->token['root_org'];
  3078. $subOrg = orgSubIds($root_id);
  3079. $param = $request->only(['page', 'limit', 'org_id']);
  3080. if (!in_array($param['org_id'], $subOrg)) {
  3081. return json(['code' => 0, 'data' => [], 'count' => 0]);
  3082. }
  3083. $data = CrmImportLog::where('org_id', $param['org_id'])->with('employee')->page($param['page'])->limit($param['limit'])->order('addtime', 'desc')->select();
  3084. $count = CrmImportLog::where('org_id', $param['org_id'])->count();
  3085. return json(['code' => 0, 'data' => $data, 'count' => $count]);
  3086. }
  3087. public function resourcepool()
  3088. {
  3089. $request = request();
  3090. $param = $request->only(['page', 'limit', 'order', 'cilid']);
  3091. $condition = [];
  3092. $order = isset($param['order']) ? $param['order'] : 'id desc';
  3093. $condition[] = ['employee_id', '=', NULL];
  3094. $condition[] = ['is_resource', '=', 1];
  3095. $condition[] = ['crm_res_id', '=', $param['cilid']];
  3096. $condition[] = ['bad_phone', '=', 0];
  3097. $root_id = request()->token['root_org'];
  3098. $subOrg = orgSubIds($root_id);
  3099. $condition[] = ['org_id', 'in', $subOrg];
  3100. $data = CustomerLogic::resourcelist($condition, $param['page'], $param['limit'], $order);
  3101. $count = CustomerLogic::count($condition);
  3102. return json(['code' => 0, 'data' => $data, 'count' => $count]);
  3103. }
  3104. public function employee4resource($org)
  3105. {
  3106. $param['page'] = input('page', 1);
  3107. $param['limit'] = input('limit', 1000000);
  3108. $employee = EmployeeLogic::employeelist4resource($org, [], $param['page'], $param['limit']);
  3109. return json(['code' => 0, 'data' => $employee]);
  3110. }
  3111. public function subnodes()
  3112. {
  3113. $request = request();
  3114. $param = $request->param();
  3115. //$nodes = OrgLogic::subnodes($param['org']);
  3116. $nodes = OrgLogic::subfirstlevelnodes($param['org']);
  3117. return json(['code' => 0, 'data' => $nodes, 'msg' => '获取成功']);
  3118. }
  3119. ///
  3120. public function subnodeswithempnum()
  3121. {
  3122. $request = request();
  3123. $param = $request->param();
  3124. $nodes = OrgLogic::subfirstlevelnodeswithempnum($param['org']);
  3125. return json(['code' => 0, 'data' => $nodes, 'msg' => '获取成功']);
  3126. }
  3127. public function resdistributing()
  3128. {
  3129. $request = request();
  3130. $param = $request->param();
  3131. $token = $this->request->token;
  3132. $target_customer_ids_arr = explode(',', $param['targets']);
  3133. $root_id = request()->token['root_org'];
  3134. $subOrg = orgSubIds($root_id);
  3135. $target_customer_ids_arr = Customer::where([['id', 'in', $target_customer_ids_arr], ['org_id', 'in', $subOrg]])->column('id');
  3136. $using_num = count($target_customer_ids_arr);
  3137. Db::startTrans();
  3138. $repeat = 0; //重复phone
  3139. if ($param['type'] == 'toemp' && isset($param['emp_id'])) {
  3140. $employee_id = $param['emp_id'];
  3141. $emp_obj = Employee::find($employee_id);
  3142. $org_id = $emp_obj->org_id;
  3143. // 设计师能否报备、获取客户
  3144. $de_where[] = ['root_id', '=', $root_id];
  3145. $de_where[] = ['name', '=', 'designer_get_customer'];
  3146. $info_de_where = Setting::where($de_where)->findOrEmpty();
  3147. $org_type = Org::where('id', '=', $org_id)->value('org_type');
  3148. if (!$info_de_where->isEmpty() && $org_type == 2) {
  3149. if ((int)$info_de_where['content'] != 1) {
  3150. return json(['code' => 1, 'msg' => '无法分配给设计师']);
  3151. }
  3152. }
  3153. $is_source = 0;
  3154. //2022-10-16 逻辑修改重复录入客户表有重复手机号,手动分配需要去重
  3155. $customers = Customer::where([['id', 'in', $target_customer_ids_arr]])->column('id,phone,phone1,phone2');
  3156. $phone = Customer::where('employee_id', $employee_id)->column('phone,phone1,phone2');
  3157. $phones = [];
  3158. foreach ($phone as $v) {
  3159. $phones = array_merge($phones, array_values($v));
  3160. }
  3161. $phones = array_filter($phones);
  3162. $cids = [];
  3163. foreach ($customers as $v2) {
  3164. $l_phone = array_filter([$v2['phone'], $v2['phone1'], $v2['phone2']]);
  3165. if (empty(array_intersect($l_phone, $phones))) {
  3166. $cids[] = $v2['id'];
  3167. } else {
  3168. $repeat += 1;
  3169. }
  3170. }
  3171. $using_num -= $repeat;
  3172. if ($cids) {
  3173. Customer::where([['id', 'in', $cids]])->update([
  3174. 'employee_id' => $employee_id,
  3175. 'org_id' => $org_id,
  3176. 'is_resource' => $is_source,
  3177. 'ext->ext6' => '',
  3178. 'designer_id' => NULL,
  3179. 'employee_time' => date('Y-m-d H:i:s', time()),
  3180. 'is_distribution' => 1
  3181. ]);
  3182. Customer::changeProtectedTo($cids, $this->request->token['root_org']);
  3183. // $this->sendOfficialAccount([$employee_id => count($cids)]);
  3184. //添加一条跟进记录
  3185. $visitlog = [];
  3186. foreach ($cids as $val) {
  3187. $visitlog[] = [
  3188. 'customer_id' => $val,
  3189. 'type' => 1,
  3190. 'remark' => '资源库分配',
  3191. 'employee_id' => $token['employee_id'],
  3192. 'user_id' => $token['uid'],
  3193. 'state' => '待确认'
  3194. ];
  3195. }
  3196. CustomerVisitLog::insertAll($visitlog);
  3197. }
  3198. // $employee_id = $param['emp_id'];
  3199. // $emp_obj = Employee::find($employee_id);
  3200. // $org_id = $emp_obj->org_id;
  3201. // $is_source = 0;
  3202. // foreach ($target_customer_ids_arr as $item_id) {
  3203. // Customer::where(['id' => (int)$item_id])->update([
  3204. // 'employee_id' => $employee_id,
  3205. // 'org_id' => $org_id,
  3206. // 'is_resource' => $is_source,
  3207. // 'ext->ext6' => '',
  3208. // 'designer_id' => null,
  3209. // 'employee_time' => date('Y-m-d H:i:s', time()) //更新员工获取客户时间
  3210. // ]);
  3211. // }
  3212. // // 更新客户保护期
  3213. // Customer::changeProtectedTo($target_customer_ids_arr, $this->request->token['root_org']);
  3214. } else {
  3215. $employee_id = null;
  3216. $aimed_org = Org::find($param['org_pool']);
  3217. $org_id = $aimed_org->id;
  3218. $is_source = 1;
  3219. foreach ($target_customer_ids_arr as $item_id) {
  3220. Customer::where(['id' => (int)$item_id])->update([
  3221. 'employee_id' => $employee_id,
  3222. 'org_id' => $org_id,
  3223. 'is_resource' => $is_source
  3224. ]);
  3225. }
  3226. //build log
  3227. $metaLog = CrmImportLog::find($param['cilid']);
  3228. $newlog = new CrmImportLog();
  3229. $newdata = [
  3230. 'pid' => $metaLog->id,
  3231. 'employee_id' => $metaLog->employee_id,
  3232. 'org_id' => $org_id,
  3233. 'name' => $metaLog->name,
  3234. 'count' => $using_num,
  3235. 'state' => 0,
  3236. 'left_num' => $using_num
  3237. ];
  3238. $newlog->save($newdata);
  3239. ///
  3240. Customer::where(['crm_res_id' => $param['cilid'], 'org_id' => $org_id])->update(['crm_res_id' => $newlog->id]);
  3241. }
  3242. ///
  3243. $leftNum = CrmImportLog::where('id', $param['cilid'])->column('left_num');
  3244. $newleftNum = ($leftNum[0] - $using_num) > 0 ? $leftNum[0] - $using_num : 0;
  3245. if (CrmImportLog::where('id', $param['cilid'])->update(['state' => 1, 'left_num' => $newleftNum]) !== false) {
  3246. Db::commit();
  3247. $result = $repeat ? ['code' => 1, 'msg' => '有' . $repeat . '条客户手机号是重复数据,无法分配'] : ['code' => 0, 'msg' => '操作成功'];
  3248. return json($result);
  3249. } else {
  3250. Db::rollback();
  3251. return json(['code' => 1, 'msg' => '操作失败']);
  3252. }
  3253. }
  3254. public function patchdistributing()
  3255. {
  3256. $token = $this->request->token;
  3257. $request = request();
  3258. $param = $request->param();
  3259. //$target_ids_arr = json_decode($param['targets'],true);
  3260. $target_ids_arr = explode(',', $param['targets']);
  3261. $resource = Customer::where(['crm_res_id' => $param['cilid'], 'bad_phone' => 0])->select()->toArray();
  3262. $timesNum = floor(count($resource) / count($target_ids_arr));
  3263. $leftNum = count($resource) % count($target_ids_arr);
  3264. $root_id = $request->token['root_org'];
  3265. $repeat = [];
  3266. Db::startTrans();
  3267. if ($param['type'] == 'topool') {
  3268. $customer_data = [];
  3269. for ($i = 0; $i < count($target_ids_arr); $i++) {
  3270. for ($t = 0; $t < $timesNum; $t++) {
  3271. unset($customer_data_once);
  3272. $customer_data_once['id'] = $resource[$i + $t * count($target_ids_arr)]['id'];
  3273. $customer_data_once['employee_id'] = NULL;
  3274. $customer_data_once['org_id'] = $target_ids_arr[$i];
  3275. $customer_data_once['is_resource'] = 1;
  3276. $customer_data[] = $customer_data_once;
  3277. }
  3278. }
  3279. (new Customer())->saveAll($customer_data);
  3280. ///build log
  3281. $metaLog = CrmImportLog::find($param['cilid']);
  3282. foreach ($target_ids_arr as $item) {
  3283. $newlog = new CrmImportLog();
  3284. $newdata = [
  3285. 'pid' => $metaLog->id,
  3286. 'employee_id' => $metaLog->employee_id,
  3287. 'org_id' => $item,
  3288. 'name' => $metaLog->name,
  3289. 'count' => $timesNum,
  3290. 'state' => 0,
  3291. 'left_num' => $timesNum
  3292. ];
  3293. $newlog->save($newdata);
  3294. ///
  3295. Customer::where(['crm_res_id' => $param['cilid'], 'org_id' => $item])->update(['crm_res_id' => $newlog->id, 'is_distribution' => 1]);
  3296. }
  3297. }
  3298. if ($param['type'] == 'toemp') {
  3299. // 设计师能否报备、获取客户
  3300. $de_where[] = ['root_id', '=', $root_id];
  3301. $de_where[] = ['name', '=', 'designer_get_customer'];
  3302. $info_de_where = Setting::where($de_where)->findOrEmpty();
  3303. $employee_org_ids = Employee::where('id', 'in', $target_ids_arr)->column('org_id');
  3304. $org_type = Org::where('id', 'in', $employee_org_ids)->column('org_type');
  3305. if (!$info_de_where->isEmpty() && in_array(2, $org_type)) {
  3306. if ((int)$info_de_where['content'] != 1) {
  3307. return json(['code' => 1, 'msg' => '无法分配给设计师']);
  3308. }
  3309. }
  3310. //2023-02-18 待分配的业务员
  3311. $employees = Employee::where([['id', 'in', $target_ids_arr]])->column('org_id', 'id');
  3312. //待分配的客户 //只分配,后台分配到我部门下的客户资源
  3313. $customers = Customer::where([['crm_res_id', '=', $param['cilid']], ['bad_phone', '=', 0], ['employee_id', '=', NULL], ['org_id', '=', $token['org_id']], ['is_distribution', '=', 1]])->column('id'); //要分配的所有客户
  3314. //每人分得客户数量
  3315. $count = ceil(count($customers) / count($employees));
  3316. $arr = [];
  3317. foreach ($employees as $kx => $vx) {
  3318. $where = [];
  3319. $where = [
  3320. ['crm_res_id', '=', $param['cilid']],
  3321. ['bad_phone', '=', 0],
  3322. ['employee_id', '=', NULL],
  3323. ['org_id', '=', $token['org_id']],
  3324. ['is_distribution', '=', 1]
  3325. ];
  3326. //已有手机号列表
  3327. $phone = Customer::where([['employee_id', '=', $kx]])->column('phone,phone1,phone2');
  3328. $phones = [];
  3329. foreach ($phone as $kx1 => $vx2) {
  3330. $lxs_phone = array_filter([$vx2['phone'], $vx2['phone1'], $vx2['phone2']]);
  3331. $phones = array_merge($phones, $lxs_phone);
  3332. }
  3333. //手机号去重
  3334. if ($phones) $where[] = ['phone&phone1&phone2', 'not in', $phones];
  3335. $cids = Customer::where($where)->limit($count)->column('id');
  3336. Customer::where([['id', 'in', $cids]])->update([
  3337. 'employee_id' => $kx,
  3338. 'org_id' => $vx,
  3339. 'is_resource' => 0,
  3340. 'ext->ext6' => '',
  3341. 'designer_id' => NULL,
  3342. 'employee_time' => date('Y-m-d H:i:s', time()),
  3343. 'is_distribution' => 1
  3344. ]);
  3345. $arr[$kx] = $cids;
  3346. }
  3347. if ($arr) {
  3348. $visitlog = [];
  3349. //分配客户
  3350. $send = []; //发送公众号消息数组
  3351. foreach ($arr as $k4 => $v4) {
  3352. // 更新客户保护期
  3353. Customer::changeProtectedTo($v4, $token['root_org']);
  3354. $send[$k4] = count($v4);
  3355. //添加一条跟进记录
  3356. foreach ($v4 as $val) {
  3357. $visitlog[] = [
  3358. 'customer_id' => $val,
  3359. 'type' => 1,
  3360. 'remark' => '资源库分配',
  3361. 'employee_id' => $token['employee_id'],
  3362. 'user_id' => $token['uid'],
  3363. 'state' => '待确认'
  3364. ];
  3365. }
  3366. }
  3367. if ($visitlog) CustomerVisitLog::insertAll($visitlog);
  3368. // $this->sendOfficialAccount($send);
  3369. }
  3370. //剩余没有分配的人员
  3371. $repeat = Customer::where([['crm_res_id', '=', $param['cilid']], ['bad_phone', '=', 0], ['employee_id', '=', NULL]])->column('id');
  3372. $leftNum = count($repeat);
  3373. }
  3374. if ($param['type'] == 'toinstitue') {
  3375. $resource = Customer::where(['crm_res_id' => $param['cilid'], 'bad_phone' => 0])->select()->toArray();
  3376. $resourceNum = count($resource);
  3377. $leftNum = count($resource);
  3378. $sumedempnum = 0;
  3379. $empnumarr = [];
  3380. foreach ($target_ids_arr as $targtid) {
  3381. $orgids = orgSubIds($targtid);
  3382. $allempnum = Employee::where([['org_id', 'in', $orgids]])->count();
  3383. if ($allempnum == 0) {
  3384. return json(['code' => 1, 'msg' => '有机构人员为0,操作失败']);
  3385. }
  3386. $sumedempnum += $allempnum;
  3387. $empnumarr[$targtid] = $allempnum;
  3388. }
  3389. if ($sumedempnum == 0) {
  3390. return json(['code' => 1, 'msg' => '人员为0,操作失败']);
  3391. }
  3392. $data_arr = [];
  3393. foreach ($target_ids_arr as $targtid) {
  3394. unset($data_arr_once);
  3395. $data_arr_once['key'] = $targtid;
  3396. $data_arr_once['val'] = floor($resourceNum * ($empnumarr[$targtid] / $sumedempnum));
  3397. $data_arr[] = $data_arr_once;
  3398. }
  3399. /*foreach ($target_ids_arr as $targtid) {
  3400. $target_arr['_keys'][] = $targtid;
  3401. $target_arr['_vals'][] = floor($resourceNum * ($empnumarr[$targtid] / $sumedempnum));
  3402. }
  3403. //var_dump($target_arr['_keys']);
  3404. //var_dump($target_arr['_vals']);
  3405. $data_arr = [];
  3406. for ($i = 0; $i < count($target_arr['_keys']); $i++) {
  3407. $data_arr[$i] = [
  3408. 'key' => $target_arr['_keys'][$i],
  3409. 'val' => $target_arr['_vals'][$i]
  3410. ];
  3411. }*/
  3412. //
  3413. $starter = 0;
  3414. $customer_data = [];
  3415. for ($k = 0; $k < count($data_arr); $k++) {
  3416. $leftNum -= $data_arr[$k]['val'];
  3417. if ($k > 0) {
  3418. $starter += $k * $data_arr[$k - 1]['val'];
  3419. }
  3420. for ($n = $starter; $n < $starter + $data_arr[$k]['val']; $n++) {
  3421. unset($customer_data_once);
  3422. $customer_data_once['id'] = $resource[$n]['id'];
  3423. $customer_data_once['employee_id'] = NULL;
  3424. $customer_data_once['org_id'] = $data_arr[$k]['key'];
  3425. $customer_data_once['is_resource'] = 1;
  3426. $customer_data[] = $customer_data_once;
  3427. /*$updatedata = [
  3428. 'employee_id' => null,
  3429. 'org_id' => $data_arr[$k]['key'],
  3430. 'is_resource' => 1
  3431. ];
  3432. Customer::where('id', $resource[$n]['id'])->update($updatedata);*/
  3433. }
  3434. }
  3435. (new Customer())->saveAll($customer_data);
  3436. ///build log
  3437. $metaLog = CrmImportLog::find($param['cilid']);
  3438. foreach ($data_arr as $item) {
  3439. $newlog = new CrmImportLog();
  3440. $newdata = [
  3441. 'pid' => $metaLog->id,
  3442. 'employee_id' => $metaLog->employee_id,
  3443. 'org_id' => $item['key'],
  3444. 'name' => $metaLog->name,
  3445. 'count' => $item['val'],
  3446. 'state' => 0,
  3447. 'left_num' => $item['val']
  3448. ];
  3449. $newlog->save($newdata);
  3450. ///
  3451. Customer::where(['crm_res_id' => $param['cilid'], 'org_id' => $item['key']])->update(['crm_res_id' => $newlog->id, 'is_distribution' => 1]);
  3452. }
  3453. }
  3454. if (CrmImportLog::where('id', '=', $param['cilid'])->update(['state' => 1, 'left_num' => $leftNum > 0 ? $leftNum : 0]) !== false) {
  3455. Db::commit();
  3456. $result = $repeat ? ['code' => 1, 'msg' => '有' . count($repeat) . '条客户手机号是重复数据,无法分配'] : ['code' => 0, 'msg' => '操作成功'];
  3457. return json($result);
  3458. } else {
  3459. Db::rollback();
  3460. return json(['code' => 1, 'msg' => '操作失败']);
  3461. }
  3462. }
  3463. public function cil_detail()
  3464. {
  3465. $request = request();
  3466. $param = $request->param();
  3467. $emparr = [];
  3468. $resource = Customer::where([
  3469. ['crm_res_id', '=', $param['cilid']],
  3470. ['employee_id', 'not null', '']
  3471. ])->select()->toArray();
  3472. $eids = array_unique(array_column($resource, 'employee_id'));
  3473. $emps = Employee::with(['user' => function ($query) {
  3474. $query->field('headimgurl,id')->bind(['headimgurl' => 'headimgurl']);
  3475. }])->where([['id', 'in', $eids]])->field('id,name,uid')->select()->toArray();
  3476. $name = array_column($emps, 'name', 'id');
  3477. $headimgurl = array_column($emps, 'headimgurl', 'id');
  3478. $count = Customer::where([['crm_res_id', '=', $param['cilid']], ['employee_id', 'not null', '']])->group('employee_id')->column('count(id)', 'employee_id');
  3479. foreach ($resource as $customer) {
  3480. // $emp = Employee::with('user')->find($customer['employee_id']);
  3481. // $count = Customer::where([['crm_res_id', '=', $param['cilid']], ['employee_id', '=', $customer['employee_id']]])->count();
  3482. $id = $customer['employee_id'];
  3483. $emparr[$id] = [
  3484. 'name' => isset($name[$id]) ? $name[$id] : '',
  3485. 'headimgurl' => isset($headimgurl[$id]) ? $headimgurl[$id] : '',
  3486. 'count' => isset($count[$id]) ? $count[$id] : 0,
  3487. 'employee_id' => $id
  3488. ];
  3489. }
  3490. $emparrval = array_values($emparr);
  3491. ////
  3492. $logs = CrmImportLog::where('pid', $param['cilid'])->select();
  3493. $resourcePoolNodes = [];
  3494. foreach ($logs as $item) {
  3495. $orgob = Org::find($item['org_id']);
  3496. $resourcePoolNodes[] = ['name' => $orgob->info, 'count' => $item['count'], 'org_id' => $item['org_id']];
  3497. }
  3498. $data = [
  3499. 'respool' => $resourcePoolNodes,
  3500. 'emp' => $emparrval
  3501. ];
  3502. return json(['code' => 0, 'data' => $data, 'msg' => '操作成功', 'crm_res_id' => $param['cilid']]);
  3503. }
  3504. ///////////
  3505. /// 公海
  3506. ///////////
  3507. public function pool()
  3508. {
  3509. $request = request();
  3510. $param = $request->only(['page' => 1, 'limit' => 20, 'order', 'org', 'keyword', 'state', 'date' => '']);
  3511. $condition = [];
  3512. $order = isset($param['order']) ? $param['order'] : 'id desc';
  3513. $condition[] = ['employee_id', '=', NULL];
  3514. $condition[] = ['is_resource', '=', 0];
  3515. $org_id = $request->token['org_id'];
  3516. $subOrg = orgSubIds($org_id);
  3517. if (isset($param['org']) && in_array($param['org'], $subOrg)) {
  3518. $condition[] = ['org_id', '=', $param['org']];
  3519. } else {
  3520. $condition[] = ['org_id', 'in', $subOrg];
  3521. }
  3522. if (isset($param['keyword']) && $param['keyword']) {
  3523. $condition[] = ['name|community_name', 'like', '%' . trim($param['keyword']) . '%'];
  3524. }
  3525. // 查询id列表
  3526. $customerIdList = Customer::where($condition)->column('id');
  3527. if (isset($param['state']) && $param['state']) {
  3528. // 筛查状态
  3529. $customerIdList = CustomerVisitLog::where([['state', 'in', CustomerVisitLog::changeState($param['state'])], ['customer_id', 'in', $customerIdList]])->group('customer_id')->column('customer_id');
  3530. }
  3531. $pageIdList = array_slice($customerIdList, ($param['page'] - 1) * $param['limit'], $param['limit']);
  3532. $condition[] = ['id', 'in', $pageIdList];
  3533. $customersStateList = CustomerVisitLog::where([['customer_id', 'in', $pageIdList]])->group('state,customer_id')->field('count(state) as num, state, customer_id')->select()->toArray();
  3534. $customersState = [];
  3535. foreach ($customersStateList as $s) {
  3536. if (!isset($customersState[$s['customer_id']]))
  3537. $customersState[$s['customer_id']] = ['count' => 0, 'shop' => 0, 'measure' => 0, 'activity' => 0, 'deposit' => 0, 'signed' => 0];
  3538. $customersState[$s['customer_id']]['count'] += $s['num'];
  3539. // 到店,量房,活动,定金,签单
  3540. if ($s['state'] == '已到店') $customersState[$s['customer_id']]['shop'] += $s['num'];
  3541. elseif ($s['state'] == '已量房') $customersState[$s['customer_id']]['measure'] += $s['num'];
  3542. elseif ($s['state'] == '已到场') $customersState[$s['customer_id']]['activity'] += $s['num'];
  3543. elseif ($s['state'] == '已交定') $customersState[$s['customer_id']]['deposit'] += $s['num'];
  3544. elseif ($s['state'] == '已签单') $customersState[$s['customer_id']]['signed'] += $s['num'];
  3545. }
  3546. // 上方id已分页,此处分页参数传固定1
  3547. $data = CustomerLogic::poollist($condition, 1, $param['limit'], $order);
  3548. $customer_id = array_column($data, 'id');
  3549. $visitLogNum = CustomerVisitLog::where([['customer_id', 'in', $customer_id], CustomerVisitLog::changeState(['state', '=', '无效'])])->group('customer_id')->column('count(customer_id) as num', 'customer_id');
  3550. $visitLogDate = CustomerVisitLog::where([['customer_id', 'in', $customer_id], CustomerVisitLog::changeState(['state', '=', '无效'])])->order('addtime')->column('addtime', 'customer_id');
  3551. foreach ($data as &$value) {
  3552. //回收次数
  3553. $value['recoverNum'] = isset($visitLogNum[$value['id']]) ? $visitLogNum[$value['id']] : 0;
  3554. //最近的回收时间
  3555. $value['recoverLatelyDate'] = isset($visitLogDate[$value['id']]) ? $visitLogDate[$value['id']] : null;
  3556. //上次跟进人信息
  3557. $value['before_pool'] = !empty($value['before_pool']) ? json_decode($value['before_pool'], true) : null;
  3558. $value[$value['id']]['stateNum'] = $customersState[$value['id']] ?? ['count' => 0, 'shop' => 0, 'measure' => 0, 'activity' => 0, 'deposit' => 0, 'signed' => 0];
  3559. }
  3560. foreach ($condition as $k => $v) {
  3561. if ($v[0] == 'id') {
  3562. if (isset($v[2])) {
  3563. $condition[$k][2] = $customerIdList;
  3564. }
  3565. }
  3566. }
  3567. $count = CustomerLogic::count($condition);
  3568. return json(['code' => 0, 'data' => $data, 'count' => $count]);
  3569. }
  3570. /**
  3571. * 资源分配
  3572. */
  3573. public function resourceAllocation()
  3574. {
  3575. $param = Request()->only(['cids' => '', 'eid' => 0]);
  3576. $token = $this->request->token;
  3577. $info = Employee::where([['state', '=', '在职'], ['id', '=', $param['eid']], ['root_id', '=', $token['root_org']]])->findOrEmpty();
  3578. if ($info->isEmpty()) return json(['code' => 1, 'msg' => '指派失败']);
  3579. $cids = explode(',', $param['cids']);
  3580. $cids = Customer::where([['id', 'in', $cids], ['employee_id', '=', null]])->column('id');
  3581. if (empty($cids)) return json(['code' => 1, 'msg' => '指派失败']);
  3582. foreach ($cids as $v) {
  3583. if (Customer::where('id', $v)->update(['employee_id' => $param['eid'], 'org_id' => $info->org_id, 'state' => 0, 'remark' => '公海获取', 'fresh' => 1, 'ext->ext6' => '', 'designer_id' => null])) {
  3584. CustomerVisitLog::create([
  3585. 'customer_id' => $v,
  3586. 'type' => 1,
  3587. 'remark' => '管理员指派',
  3588. 'employee_id' => $param['eid'],
  3589. 'user_id' => $info->uid,
  3590. 'state' => '待确认'
  3591. ]);
  3592. }
  3593. }
  3594. return json(['code' => 0, 'msg' => '指派成功']);
  3595. }
  3596. public function distributing()
  3597. {
  3598. $request = request();
  3599. $param = $request->param();
  3600. $target_customer_ids_arr = explode(',', $param['targets']);
  3601. $root_id = request()->token['root_org'];
  3602. $subOrg = orgSubIds($root_id);
  3603. $target_customer_ids_arr = Customer::where([['id', 'in', $target_customer_ids_arr], ['org_id', 'in', $subOrg]])->column('id');
  3604. if ($param['type'] == 'toemp' && isset($param['emp_id'])) {
  3605. $employee_id = $param['emp_id'];
  3606. $emp_obj = Employee::find($employee_id);
  3607. $org_id = $emp_obj->org_id;
  3608. } else {
  3609. $employee_id = null;
  3610. $org_id = $param['org_pool'];
  3611. }
  3612. foreach ($target_customer_ids_arr as $item_id) {
  3613. $update = [
  3614. 'employee_id' => $employee_id,
  3615. 'org_id' => $org_id,
  3616. ];
  3617. if ($employee_id) {
  3618. $update['ext->ext6'] = '';
  3619. $update['designer_id'] = null;
  3620. }
  3621. Customer::where(['id' => (int)$item_id])->update($update);
  3622. }
  3623. return json(['code' => 0, 'msg' => '操作成功']);
  3624. }
  3625. /**
  3626. * 公海获取客户
  3627. * customer_id来源:业务员获取(int)、报备录入时查询公海存在自动获取(逗号分隔字符串)
  3628. */
  3629. public function fetchpoolitem()
  3630. {
  3631. $param = request()->param();
  3632. $customer_id = explode(',', $param['customer_id']);
  3633. $employee_id = $this->request->token['employee_id'];
  3634. $root_id = request()->token['root_org'];
  3635. $subOrg = orgSubIds($root_id);
  3636. $otheremp = Customer::where([['id', 'in', $customer_id], ['employee_id', '=', NULL], ['org_id', 'in', $subOrg]])->field('employee_id,phone,phone1,phone2')->select();
  3637. if (empty($otheremp)) {
  3638. return json(['code' => 1, 'msg' => '客户已被人抢先获取。记得下次抓住机会。']);
  3639. }
  3640. //判断名下是否存在该客户手机号,存在则不可获取
  3641. foreach ($otheremp as $item) {
  3642. $phone_arr = [];
  3643. !empty($item['phone']) ? $phone_arr[] = cypherphone($item['phone']) : '';
  3644. !empty($item['phone1']) ? $phone_arr[] = cypherphone($item['phone1']) : '';
  3645. !empty($item['phone2']) ? $phone_arr[] = cypherphone($item['phone2']) : '';
  3646. $phone_arr = array_filter($phone_arr);
  3647. $haveCrm = Customer::where([['employee_id', '=', $employee_id], ['phone|phone1|phone2', 'in', $phone_arr]])->count();
  3648. if ($haveCrm) {
  3649. return json(['code' => 1, 'msg' => '您名下已存在该客户信息。']);
  3650. }
  3651. }
  3652. if (Customer::where([['id', 'in', $customer_id]])->update(['employee_id' => $employee_id, 'org_id' => $this->request->token['org_id'], 'state' => 0, 'remark' => '公海获取', 'fresh' => 1, 'ext->ext6' => '', 'designer_id' => null, 'employee_time' => date('Y-m-d H:i:s')])) {
  3653. $saveAll = [];
  3654. foreach ($customer_id as $ids) {
  3655. $saveAll[] = [
  3656. 'customer_id' => $ids,
  3657. 'type' => 1,
  3658. 'remark' => '公海获取',
  3659. 'employee_id' => $employee_id,
  3660. 'user_id' => $this->request->token['uid'],
  3661. 'state' => 1
  3662. ];
  3663. }
  3664. if (CustomerVisitLog::insertAll($saveAll)) {
  3665. return json(['code' => 0, 'msg' => '跟进成功']);
  3666. } else {
  3667. return json(['code' => 1, 'msg' => '跟进失败']);
  3668. }
  3669. } else {
  3670. return json(['code' => 1, 'msg' => '跟进失败']);
  3671. }
  3672. }
  3673. // /**
  3674. // * 预约确认
  3675. // */
  3676. // public function subscribeConfirm($id, $type)
  3677. // {
  3678. // if ($this->request->token['org_type'] == 2) {
  3679. // $column = 'designer_id';
  3680. // $employeeType = '设计师';
  3681. // } else {
  3682. // $column = 'employee_id';
  3683. // $employeeType = '销售';
  3684. // }
  3685. // $customer = Customer::where([[$column, '=', $this->request->token['employee_id']], ['id', '=', $id]])->find();
  3686. // $subscribe = CustomersSubscribe::where([['customer_id', '=', $id], ['type', '=', $type], ['state', '=', 0], [$column, '=', $this->request->token['employee_id']]])->find();
  3687. // if (!empty($subscribe)) {
  3688. // $subscribe->state = 1;
  3689. // $subscribe->save();
  3690. // }
  3691. // $employeeName = Employee::find($this->request->token['employee_id'])->name;
  3692. // $state = [
  3693. // 1 => '已到店',
  3694. // 2 => '已到场',
  3695. // 3 => '已量房'
  3696. // ];
  3697. // $customer->state = $state[$type];
  3698. // $customer->save();
  3699. // // 跟进记录添加
  3700. // $visitLog = [
  3701. // 'customer_id' => $id,
  3702. // 'type' => 4,
  3703. // 'remark' => $employeeType . $employeeName . '确认客户' . $customer->name . $state[$type],
  3704. // 'employee_id' => $this->request->token['employee_id'],
  3705. // 'user_id' => $this->request->token['uid'],
  3706. // 'state' => $state[$type]
  3707. // ];
  3708. // CustomerVisitLog::create($visitLog);
  3709. // return json(['code' => 0, 'msg' => '确认成功']);
  3710. // }
  3711. // /**
  3712. // * 确认到店
  3713. // */
  3714. // public function visitConfirm($id)
  3715. // {
  3716. // return $this->subscribeConfirm($id, 1);
  3717. // }
  3718. // /**
  3719. // * 确认到场
  3720. // */
  3721. // public function activityConfirm($id)
  3722. // {
  3723. // return $this->subscribeConfirm($id, 2);
  3724. // }
  3725. // /**
  3726. // * 确认量房
  3727. // */
  3728. // public function measureConfirm($id, array $img)
  3729. // {
  3730. // return $this->subscribeConfirm($id, 3);
  3731. // }
  3732. // /**
  3733. // * 取消到店/量房
  3734. // */
  3735. // public function cancelSubscribe($id)
  3736. // {
  3737. // $customer = Customer::where([['id', '=', $id], ['employee_id|designer_id', '=', $this->request->token['employee_id']]])->find();
  3738. // if (empty($customer)) return json(['code' => 1, 'msg' => '客户不存在']);
  3739. // $subscribe = CustomersSubscribe::where([['customer_id', '=', $id], ['type', '=', $type], ['state', '=', 0], ['subscribe_date', '=', date('Y-m-d')], [$column, '=', $this->request->token['employee_id']]])->find();
  3740. // if (!empty($subscribe)) {
  3741. // $subscribe->state = 1;
  3742. // $subscribe->save();
  3743. // }
  3744. // // 跟进记录添加
  3745. // $employeeName = Employee::where(['id' => $this->request->token['employee_id']])->value('name');
  3746. // $visitLog = [
  3747. // 'customer_id' => $customer->id,
  3748. // 'type' => 4,
  3749. // 'remark' => "${employeeName}取消了客户的" . $customer->state,
  3750. // 'employee_id' => $this->request->token['employee_id'],
  3751. // 'user_id' => $this->request->token['uid'],
  3752. // 'state' => $customer->state
  3753. // ];
  3754. // $customer->state = $customer->state == '预约活动' ? '未到场' : str_replace('预约', '未', $customer->state);
  3755. // // $customer->state = str_replace('预约', '未', $customer->state);
  3756. // // 数据保存
  3757. // Db::startTrans();
  3758. // try {
  3759. // CustomerVisitLog::create($visitLog);
  3760. // $customer->save();
  3761. // Db::commit();
  3762. // } catch (\Exception $e) {
  3763. // Db::rollback();
  3764. // return json(['code' => 1, 'msg' => $e->getMessage()]);
  3765. // }
  3766. // return json(['code' => 0, 'msg' => '取消成功']);
  3767. // }
  3768. /**
  3769. * 共有客户头部统计
  3770. */
  3771. public function shareStatistics()
  3772. {
  3773. $token = $this->request->token;
  3774. $is_manager = $token['isManager'];
  3775. $param = $this->request->only(['org_id', 'start_time' => '', 'end_time' => '']);
  3776. if ($is_manager == 1) {
  3777. $team_orgs = orgSubIds($token['org_id']);
  3778. $org_employee = Employee::where([['org_id', 'in', $team_orgs], ['state', '=', '在职'], ['uid', '>', 0]])->column('id');
  3779. } else {
  3780. $org_employee = [$token['employee_id']];
  3781. }
  3782. $condition = [
  3783. ['state', 'not in', Customer::changeState('无效', 'chaos')],
  3784. //['employee_id|designer_id|assigned_personnel', 'find in set', $token['employee_id']],
  3785. ['designer_id|assigned_personnel', 'not null', ""],
  3786. ['employee_id', '>', 0]
  3787. ];
  3788. $condition[] = ['died', '<>', 2]; // 死单客户过滤
  3789. if ($param['start_time'] && $param['end_time']) {
  3790. $condition[] = ['assign_time', 'between', [$param['start_time'] . ' 00:00:00', $param['end_time'] . ' 23:59:59']];
  3791. }
  3792. $customerIdList = Customer::where($condition)->where(function ($query) use ($org_employee) {
  3793. foreach ($org_employee as $v) {
  3794. $query->whereOr([['employee_id|designer_id|assigned_personnel', 'find in set', $v]]);
  3795. }
  3796. })->column('id');
  3797. $asg_num = count($customerIdList);
  3798. $measure_num = $toshop_num = $deposit_num = $sing_num = 0;
  3799. $cusvislog = CustomerVisitLog::where([['customer_id', 'in', $customerIdList]])->group('state,customer_id')->field('id,state,customer_id')->select()->toArray();
  3800. foreach ($cusvislog as $key => $val) {
  3801. if ($val['state'] == '已量房') $measure_num++;
  3802. if ($val['state'] == '已到店') $toshop_num++;
  3803. if ($val['state'] == '已交定') $deposit_num++;
  3804. if ($val['state'] == '已签单') $sing_num++;
  3805. }
  3806. $data = ['asg_num' => $asg_num, 'measure_num' => $measure_num, 'toshop_num' => $toshop_num, 'deposit_num' => $deposit_num, 'sing_num' => $sing_num];
  3807. return json(['code' => 0, 'data' => $data, 'msg' => '获取成功']);
  3808. }
  3809. /**
  3810. * 共有客户列表
  3811. */
  3812. public function shareList()
  3813. {
  3814. $token = $this->request->token;
  3815. $is_manager = $token['isManager'];
  3816. $team_orgs = orgSubIds($token['org_id']);
  3817. $param = $this->request->only([
  3818. 'page' => 1,
  3819. 'limit' => 20,
  3820. 'keyword' => "",
  3821. "state" => "",
  3822. 'assign_start_time' => '',
  3823. 'assign_end_time' => '',
  3824. 'employee_name' => ''
  3825. ]);
  3826. $employee_where[] = ['org_id', 'in', $team_orgs];
  3827. $employee_where[] = ['state', '=', '在职'];
  3828. $employee_where[] = ['uid', '>', 0];
  3829. if (!empty($param['employee_name'])) {
  3830. $employee_where[] = ['name', 'like', '%' . $param['employee_name'] . '%'];
  3831. }
  3832. if ($is_manager == 1) {
  3833. $org_employee = Employee::where($employee_where)->column('id');
  3834. } else {
  3835. $org_employee = [$token['employee_id']];
  3836. }
  3837. //2022-11-15 逻辑修改 销售/设计师已经指派的客户 在自己的共有客户中都能看到
  3838. $condition = [
  3839. ['state', 'not in', Customer::changeState('无效', 'chaos')],
  3840. //['employee_id|designer_id|assigned_personnel', 'find in set', $token['employee_id']],
  3841. ['designer_id|assigned_personnel', 'not null', ""],
  3842. ['employee_id', '>', 0]
  3843. ];
  3844. $condition[] = ['died', '<>', 2]; // 死单客户过滤
  3845. // $cids = Customer::where($condition)->select();
  3846. // if ($token['org_type'] == 2) {
  3847. // $condition[] = ['designer_id', '=', $token['employee_id']];
  3848. // } else {
  3849. // $condition[] = ['designer_id', 'not null', ""];
  3850. // $condition[] = ['employee_id', '=', $token['employee_id']];
  3851. // }
  3852. if (!empty($param['keyword'])) {
  3853. $list = Customer::where($condition)->where(function ($query) use ($org_employee) {
  3854. foreach ($org_employee as $v) {
  3855. $query->whereOr([['employee_id|designer_id|assigned_personnel', 'find in set', $v]]);
  3856. }
  3857. })->order('addtime desc')->field('id,name,community_name,phone')->select()->toArray();
  3858. $customerIdList = [];
  3859. foreach ($list as $v) {
  3860. $str = $v['name'] . $v['community_name'] . $v['phone'];
  3861. if (strpos($str, trim($param['keyword'])) !== false) $customerIdList[] = $v['id'];
  3862. }
  3863. } else {
  3864. $customerIdList = Customer::where($condition)->where(function ($query) use ($org_employee) {
  3865. foreach ($org_employee as $v) {
  3866. $query->whereOr([['employee_id|designer_id|assigned_personnel', 'find in set', $v]]);
  3867. }
  3868. })->column('id');
  3869. }
  3870. if (!empty($param['state'])) {
  3871. if ($param['state'] == '待确认') {
  3872. // 筛查状态
  3873. /* $customerIdList1 = CustomerVisitLog::where([['customer_id', 'in', $customerIdList], ['state', 'not in', CustomerVisitLog::changeState('待确认', 'chaos')]])->group('customer_id')->column('customer_id');
  3874. $customerIdList = array_diff($customerIdList, $customerIdList1); */
  3875. $customerIdList = Customer::where([['id', 'in', $customerIdList], ['state', 'in', Customer::changeState($param['state'], 'chaos')], ['crm_res_id', 'NULL', null]])->column('id');
  3876. } elseif (CustomerVisitLog::changeState($param['state']) == '回访' || $param['state'] == '有效') {
  3877. //有效状态 未到访,已到访,确定到场,已量房,交定,签单
  3878. $visit_status = ['未到访', '已到访', '已量房', '已到场', '已到店', '交定', '签单'];
  3879. $now_status = [];
  3880. foreach ($visit_status as $v) {
  3881. $now_status = array_merge(CustomerVisitLog::changeState($v, 'chaos'), $now_status);
  3882. }
  3883. $customerIdList = CustomerVisitLog::where([['customer_id', 'in', $customerIdList], ['state', 'in', $now_status], ['employee_id|customer_employee_id', '=', $token['employee_id']]])->group('customer_id')->column('customer_id');
  3884. } else {
  3885. // 筛查状态
  3886. $customerIdList = CustomerVisitLog::where([['customer_id', 'in', $customerIdList], ['state', 'in', CustomerVisitLog::changeState($param['state'], 'chaos')]])->group('customer_id')->column('customer_id');
  3887. }
  3888. }
  3889. //2022-11-14 增加 查询共有客户当天待到店,待量房列表
  3890. if (input('search_type', 0)) {
  3891. $search_where = [
  3892. ['subscribe_date', '=', date('Y-m-d')],
  3893. ['customer_id', 'in', $customerIdList],
  3894. ['state', '=', 0],
  3895. ['type', 'in', [1, 3]] //1到店,3量房
  3896. ];
  3897. $arr = CustomersSubscribe::where($search_where)->column('type', 'customer_id');
  3898. $customerIdList = array_keys($arr);
  3899. }
  3900. //增加按指派时间查询
  3901. if (!empty($param['assign_start_time']) && !empty($param['assign_end_time'])) {
  3902. $assign_where[] = ['assign_time', 'between', [$param['assign_start_time'] . ' 00:00:00', $param['assign_end_time'] . ' 23:59:59']];
  3903. $assign_where[] = ['id', 'in', $customerIdList];
  3904. $assign_where[] = ['assigned_personnel', 'not null', null];
  3905. $customerIdList = Customer::where($assign_where)->column('id');
  3906. }
  3907. $customers = Customer::where([['id', 'in', $customerIdList]])->order('assign_time desc')->page($param['page'], $param['limit'])->select();
  3908. //2022-11-08 增加指派人员
  3909. // $query1 = [['employee_id', '>', 0], ['assigned_personnel', 'find in set', $token['employee_id']]];
  3910. // if (input('search_type', 0)) $query1[] = ['id', 'in', $customerIdList]; //当天待到店,量房的客户
  3911. // $assigned_personnel = Customer::where($query1)->column('id');
  3912. // $where_or[] = ['id', 'in', $assigned_personnel];
  3913. // $customers = Customer::whereOr([$condition, $where_or])->page($param['page'], $param['limit'])->select();
  3914. $count = Customer::where([['id', 'in', $customerIdList]])->count();
  3915. $data = $customers->toArray();
  3916. $pageIdList = array_column($data, 'id');
  3917. $employeeList = array_column($data, 'employee_id');
  3918. $designerList = array_column($data, 'designer_id');
  3919. $empIdList = array_merge($employeeList, $designerList, [$token['employee_id']]);
  3920. $empList = Employee::where([['id', 'in', $empIdList]])->column('name,org_id', 'id');
  3921. $orgList = Org::where([['id', 'in', array_column($empList, 'org_id')]])->column('name', 'id');
  3922. // $customers = $customers->visible(['id', 'name', 'sex', 'level', 'community_name', 'state'])->toArray();
  3923. // 查询跟踪记录
  3924. $depositVisitLog = CustomerVisitLog::where([CustomerVisitLog::changeState(['state', '=', '已交定']), ['customer_id', 'in', $pageIdList]])->group('customer_id')->column('count(id) as num', 'customer_id');
  3925. $signVisitLog = CustomerVisitLog::where([CustomerVisitLog::changeState(['state', '=', '已签单']), ['customer_id', 'in', $pageIdList]])->group('customer_id')->column('count(id) as num', 'customer_id');
  3926. // 状态统计获取
  3927. $customersStateList = CustomerVisitLog::where([['customer_id', 'in', $customerIdList]])->group('state,customer_id')->field('count(state) as num, state, customer_id')->select()->toArray();
  3928. $customersState = [];
  3929. foreach ($customersStateList as $s) {
  3930. if (!isset($customersState[$s['customer_id']]))
  3931. $customersState[$s['customer_id']] = ['count' => 0, 'shop' => 0, 'measure' => 0, 'activity' => 0, 'deposit' => 0, 'signed' => 0];
  3932. $customersState[$s['customer_id']]['count'] += $s['num'];
  3933. // 到店,量房,活动,定金,签单
  3934. if ($s['state'] == '已到店') $customersState[$s['customer_id']]['shop'] += $s['num'];
  3935. elseif ($s['state'] == '已量房') $customersState[$s['customer_id']]['measure'] += $s['num'];
  3936. elseif ($s['state'] == '已到场') $customersState[$s['customer_id']]['activity'] += $s['num'];
  3937. elseif ($s['state'] == '已交定') $customersState[$s['customer_id']]['deposit'] += $s['num'];
  3938. elseif ($s['state'] == '已签单') $customersState[$s['customer_id']]['signed'] += $s['num'];
  3939. }
  3940. $data = [];
  3941. // 最后跟进时间获取
  3942. $lastTime = CustomerVisitLog::where([['customer_id', 'in', $customerIdList]])->group('customer_id')->column('max(addtime)', 'customer_id');
  3943. // 交定时间获取
  3944. $dingTime = CustomerVisitLog::where([['customer_id', 'in', $customerIdList], ['state', 'in', CustomerVisitLog::changeState('已交定', 'chaos')]])->group('customer_id')->column("max(confirm_date)", "customer_id");
  3945. // 指派类型
  3946. $assign_type_default['yixiang'] = '意向客户指派';
  3947. $assign_type_default['liangfang'] = '量房客户指派';
  3948. $assign_type_default['daodian'] = '到店客户指派';
  3949. foreach ($customers as $item) {
  3950. $assignIdList = !empty($item['assigned_personnel']) ? explode(',', $item['assigned_personnel']) : [];
  3951. if (!empty($assignIdList) && !empty($item['designer_id'])) {
  3952. $assignIdList = array_diff($assignIdList, [$item['designer_id']]);
  3953. }
  3954. $assignIdList[] = $item['employee_id']; // 所属销售
  3955. $assignIdList = array_unique($assignIdList);
  3956. //$assignIdList[] = $item['designer_id']; // 指派的设计师
  3957. $assign_list = Employee::where('id', 'in', $assignIdList)->column('name');
  3958. $is_follow = 0;
  3959. if (!in_array($item['org_id'], $team_orgs) && !in_array($token['employee_id'], $assignIdList) && $token['org_type'] != 2) $is_follow = 1;
  3960. $assign_type_name = '';
  3961. if ($item['assign_type']) {
  3962. if (isset($assign_type_default[$item['assign_type']])) {
  3963. $assign_type_name = $assign_type_default[$item['assign_type']];
  3964. }
  3965. }
  3966. $data[] = [
  3967. 'id' => $item['id'],
  3968. 'name' => $item['name'],
  3969. 'sex' => $item['sex'],
  3970. 'level' => $item['level'],
  3971. 'community_name' => $item['community_name'],
  3972. 'state' => $item['state'],
  3973. 'deposit_num' => isset($depositVisitLog[$item['id']]) ? $depositVisitLog[$item['id']] : 0,
  3974. 'sign_num' => isset($signVisitLog[$item['id']]) ? $signVisitLog[$item['id']] : 0,
  3975. 'employee' => [
  3976. 'name' => $empList[$item['employee_id']]['name']
  3977. ],
  3978. 'employeeOrg' => [
  3979. 'name' => $orgList[$empList[$item['employee_id']]['org_id']]
  3980. ],
  3981. 'designer' => empty($item['designer_id']) ? null : [
  3982. 'name' => $empList[$item['designer_id']]['name']
  3983. ],
  3984. 'designerOrg' => empty($item['designer_id']) ? null : [
  3985. 'name' => $orgList[$empList[$item['designer_id']]['org_id']]
  3986. ],
  3987. 'btn_type' => !empty($arr[$item['id']]) ? $arr[$item['id']] : 0, ////1到店,3量房
  3988. 'square' => $item['square'], //房屋面积
  3989. 'agents' => !empty($item['agents_id']) ? $item['agents_id'] : '', //是否是经纪人推荐的
  3990. 'stateNum' => !empty($customersState[$item['id']]) ? $customersState[$item['id']] : ['count' => 0, 'shop' => 0, 'measure' => 0, 'activity' => 0, 'deposit' => 0, 'signed' => 0],
  3991. //'assign_time' => !empty($item['designer_id']) ? CustomerSharing::where([['employee_id','=',$item['designer_id']],['customer_id','=',$item['id']]])->value('addtime') ? date('Y-m-d H:i:s',CustomerSharing::where([['employee_id','=',$item['designer_id']],['customer_id','=',$item['id']]])->value('addtime')) : '' : '',
  3992. 'assign_time' => !empty($item['assign_time']) ? $item['assign_time'] : '',
  3993. 'assign_list' => $assign_list,
  3994. 'assign_type' => $item['assign_type'],
  3995. 'assigned_personnel' => $item['assigned_personnel'],
  3996. 'assign_type_name' => $assign_type_name,
  3997. 'is_follow' => $is_follow,
  3998. 'last_visit_day' => isset($lastTime[$item['id']]) ? get_date_diff(time(), $lastTime[$item['id']])->days : -1,
  3999. 'last_ding_day' => isset($dingTime[$item['id']]) ? get_date_diff(time(), $dingTime[$item['id']])->days : 0
  4000. ];
  4001. }
  4002. return json(['code' => 0, 'data' => $data, 'count' => $count]);
  4003. }
  4004. /**
  4005. * 获取客户画像展示字段
  4006. */
  4007. public function show_fields()
  4008. {
  4009. $token = $this->request->token;
  4010. $w[] = ['root_id', '=', $token['root_org']];
  4011. $info = CustomerPortrait::where($w)->findOrEmpty();
  4012. $data = $info->fields;
  4013. return json(['code' => 0, 'data' => $data]);
  4014. }
  4015. /**
  4016. * 获取加微类型
  4017. * wechat_type 加微类型
  4018. * img_type 跟进图片类型
  4019. * employees 直播人员列表
  4020. * next_visit_time_is_ok 回访时间是否必传 默认必传
  4021. *
  4022. */
  4023. public function get_setting()
  4024. {
  4025. $token = $this->request->token;
  4026. //wechat_type 加微类型
  4027. $where[] = ['root_id', '=', $token['root_org']];
  4028. $where[] = ['name', '=', 'customerWechatSetting'];
  4029. $info = Setting::where($where)->value('content');
  4030. $data['wechat_type'] = $info ? explode(',', $info) : ['常规加微'];
  4031. //img_type 跟进图片类型
  4032. $where1[] = ['root_id', '=', $token['root_org']];
  4033. $where1[] = ['name', '=', 'customerLfSetting'];
  4034. $info = Setting::where($where1)->value('content');
  4035. $data['img_type'] = $info ? explode(',', $info) : ['量房图片'];
  4036. //employees 直播人员列表
  4037. $data['employees'] = $this->live_broadcast_personnel(1);
  4038. //next_visit_time_is_ok 回访时间是否必传 默认必传
  4039. $where2[] = ['root_id', '=', $token['root_org']];
  4040. $where2[] = ['name', '=', 'nextVisitTimeIsOk'];
  4041. $info = Setting::where($where2)->value('content');
  4042. $data['next_visit_time_is_ok'] = $info == 1 ? 1 : 0;
  4043. $where3[] = ['root_id', '=', $token['root_org']];
  4044. $where3[] = ['name', '=', 'addWechatDay'];
  4045. $visit = Setting::where($where3)->findOrEmpty();
  4046. $res = !$visit->isEmpty() ? explode('@', $visit->content) : [1, 0];
  4047. $data['add_wechat_day'] = $res[0];
  4048. $data['add_wechat_day_switch'] = isset($res[1]) ? $res[1] : 0;
  4049. $company = Company::where('root_id', $token['root_org'])->find();
  4050. $data['city'] = $company->city;
  4051. $data['province_city'] = $company->province_city;
  4052. $data['province_city_code'] = $company->province_city_code;
  4053. return json(['code' => 0, 'data' => $data]);
  4054. }
  4055. /**
  4056. * 获取直播人员
  4057. */
  4058. public function live_broadcast_personnel($type = 0)
  4059. {
  4060. $token = $this->request->token;
  4061. $param = Request()->only(['org_id' => 0, 'name']);
  4062. $root_id = $token['root_org'];
  4063. $subOrg = orgSubIds($root_id);
  4064. if (in_array($param['org_id'], $subOrg)) {
  4065. $path = Org::where('id', $param['org_id'])->value('path');
  4066. } else {
  4067. $path = $token['root_org'] . '-';
  4068. }
  4069. $where[] = ['path', 'like', $path . '%'];
  4070. $empwhere[] = ['e.state', '=', '在职'];
  4071. if (!empty($param['name'])) {
  4072. $empwhere[] = ['e.name', 'like', '%' . $param['name'] . '%'];
  4073. }
  4074. $orgs = Org::with(['employee' => function ($query) use ($empwhere) {
  4075. $query->field('e.id,e.name,user.headimgurl,e.org_id')
  4076. ->alias('e')
  4077. ->where($empwhere)
  4078. ->join('user', 'user.id=e.uid');
  4079. }])->where($where)->order('level asc, id desc')->field('id,name,pid')->select()->toArray();
  4080. $data = [];
  4081. while (!empty($orgs)) {
  4082. $org = array_pop($orgs);
  4083. // $data[$org['pid']]['designer_num'] = isset($data[$org['pid']]) ? $data[$org['pid']]['designer_num'] + count($org['employee']) : 0;
  4084. $childOrg = [
  4085. 'id' => $org['id'],
  4086. 'name' => $org['name'],
  4087. 'pid' => $org['pid'],
  4088. 'designer' => $org['employee'],
  4089. 'designer_num' => count($org['employee'])
  4090. ];
  4091. if (isset($data[$org['id']])) {
  4092. $childOrg['child_org'] = $data[$org['id']]['child_org'];
  4093. $childOrg['designer_num'] += $data[$org['id']]['designer_num'];
  4094. unset($data[$org['id']]);
  4095. }
  4096. $data[$org['pid']]['child_org'][] = $childOrg;
  4097. $data[$org['pid']]['designer_num'] = isset($data[$org['pid']]['designer_num']) ? $data[$org['pid']]['designer_num'] + $childOrg['designer_num'] : $childOrg['designer_num'];
  4098. }
  4099. $data = array_pop($data);
  4100. $result = [
  4101. 'designer' => isset($data['designer']) ? $data['designer'] : [],
  4102. 'child_org' => isset($data['child_org']) ? $data['child_org'] : []
  4103. ];
  4104. if ($type) {
  4105. return $result;
  4106. } else {
  4107. return json(['code' => 0, 'data' => $result]);
  4108. }
  4109. }
  4110. /**
  4111. * 新客户列表
  4112. */
  4113. public function newList()
  4114. {
  4115. $param = $this->request->only([
  4116. 'page' => 1,
  4117. 'limit' => 20
  4118. ]);
  4119. // 剔除掉关注过的客户
  4120. $customerTopIdList = CustomerTop::where(['employee_id' => $this->request->token['employee_id'], 'root_id' => request()->token['root_org']])->column('customer_id');
  4121. $condition = [
  4122. ['fresh', '>', 0],
  4123. ['employee_id', '=', $this->request->token['employee_id']],
  4124. ['id', 'not in', $customerTopIdList]
  4125. ];
  4126. $data = Customer::where($condition)->page($param['page'], $param['limit'])->order('addtime desc')->select();
  4127. $count = Customer::where($condition)->count();
  4128. foreach ($data as &$item) {
  4129. if (1 == $item->crm_res_id) $item->new = 1;
  4130. }
  4131. $data = $data->visible(['id', 'name', 'sex', 'community_name', 'square', 'new'])->toArray();
  4132. return json(['code' => 0, 'data' => $data, 'count' => $count]);
  4133. }
  4134. /**
  4135. * 自动回收列表
  4136. */
  4137. public function drop_pool()
  4138. {
  4139. $param = $this->request->only(['page' => 1, 'limit' => 20, 'order', 'org', 'emp_id', 'state', 'keyword']);
  4140. $orgids = orgSubIds($this->request->token['org_id']);
  4141. $org_employee = Employee::where('org_id', 'in', $orgids)->column('id');
  4142. $condition[] = ['employee_id', 'in', $org_employee];
  4143. $order = isset($param['order']) ? $param['order'] : 'id desc';
  4144. setCondition($param, ['emp_id', 'employee_id'], '=', $condition);
  4145. empty($param['state']) ?: setCondition(['state' => Customer::changeState($param['state'], 'chaos')], 'state', 'in', $condition);
  4146. //关键词搜索
  4147. if (!empty($param['keyword'])) {
  4148. $list = CustomerDropPool::where($condition)->order($order)->field('customer_id,name,community_name,phone,employee_id,designer_id')->select()->toArray();
  4149. $search_employee = Employee::where([['id', 'in', $org_employee], ['name', 'like', '%' . $param['keyword'] . '%']])->column('id');
  4150. $search_designer = Employee::where([['root_id', '=', $this->request->token['root_org']], ['name', 'like', '%' . $param['keyword'] . '%']])->column('id');
  4151. $employee_customer = [];
  4152. $customersIdList = [];
  4153. foreach ($list as $k => $v) {
  4154. $str = $v['name'] . $v['community_name'];
  4155. if (strpos($str, trim($param['keyword'])) !== false) $customersIdList[] = $v['customer_id'];
  4156. if (in_array($v['employee_id'], $search_employee)) {
  4157. $employee_customer[] = $v['customer_id'];
  4158. }
  4159. if (in_array($v['designer_id'], $search_designer)) {
  4160. $employee_customer[] = $v['customer_id'];
  4161. }
  4162. $employee_customer = array_values(array_filter(array_unique($employee_customer)));
  4163. }
  4164. $customersIdList = array_values(array_filter(array_unique(array_merge($customersIdList, $employee_customer))));
  4165. } else {
  4166. $customersIdList = CustomerDropPool::where($condition)->order($order)->column('customer_id');
  4167. }
  4168. $data = CustomerDropPool::with(['employee', 'org', 'designer'])->withCount(['visitLog' => function ($query) {
  4169. $query->whereOr([[CustomerVisitLog::changeState(['state', '=', '预约量房'])], [CustomerVisitLog::changeState(['state', '=', '预约到店'])], [CustomerVisitLog::changeState(['state', '=', '预约活动'])]]);
  4170. }])->withCount(['activityFrequency' => function ($query) {
  4171. $query->where([CustomerVisitLog::changeState(['state', '=', '确认到场'])]);
  4172. }])
  4173. ->where([['customer_id', 'in', $customersIdList]])
  4174. ->page($param['page'], $param['limit'])->order($order)->select();
  4175. $data = $data->visible(['id', 'customer_id', 'employee_id', 'designer_id', 'name', 'community_name', 'phone', 'phone1', 'phone2', 'level', 'state', 'square', 'revisit_time', 'addtime', 'org_id', 'protected_to', 'is_resource', 'employee.name', 'org_name', 'designer.name', 'visit_log_count', 'activity_frequency_count', 'droptime', 'sex'])->toArray();
  4176. $ids = CustomerDropPool::where([['customer_id', 'in', $customersIdList]])->field('id,phone,phone1,phone2')->select();
  4177. foreach ($data as &$item) {
  4178. $item['protected'] = false;
  4179. if (isset($item['protected_to']) && time() < strtotime($item['protected_to'])) {
  4180. $item['protected'] = true;
  4181. }
  4182. $item['square'] = floatval($item['square']);
  4183. $item['mobile'] = $item['phone'];
  4184. $item['mobile1'] = $item['phone1'];
  4185. $item['mobile2'] = $item['phone2'];
  4186. $item['phone'] = substr_replace($item['phone'], '******', 3, 6);
  4187. $record_list = CustomerDropRecord::where('customer_id', '=', $item['customer_id'])->order('droptime desc')->select();
  4188. $item['recoverNum'] = $record_list->count();
  4189. $item['recoverLatelyDate'] = isset($record_list[0]) ? $record_list[0]['droptime'] : '';
  4190. $latest_visit_log = CustomerVisitLog::where('customer_id', '=', $item['customer_id'])->order('id desc')->find();
  4191. if (empty($latest_visit_log)) {
  4192. $item['latest_visit_employee'] = '';
  4193. $item['latest_visit_time'] = '';
  4194. } else {
  4195. $latest_visit_employee = Employee::find($latest_visit_log['customer_id']);
  4196. if (!empty($latest_visit_employee)) {
  4197. $item['latest_visit_employee'] = $latest_visit_employee['name'];
  4198. $item['latest_visit_time'] = $latest_visit_log['addtime'];
  4199. } else {
  4200. $item['latest_visit_employee'] = '';
  4201. $item['latest_visit_time'] = '';
  4202. }
  4203. }
  4204. }
  4205. $count = CustomerDropPool::where($condition)->count();
  4206. return json(['code' => 0, 'data' => $data, 'count' => $count, 'ids' => $ids]);
  4207. }
  4208. /**
  4209. * 自动回收还原
  4210. */
  4211. public function undrop()
  4212. {
  4213. $id = input('id', '', 'trim');
  4214. if (!$id) {
  4215. return json(['code' => 1, 'msg' => '参数错误']);
  4216. }
  4217. $list = CustomerDropPool::where([['id', 'in', $id]])->select();
  4218. $root_id = $this->request->token['root_org'];
  4219. $setting = Setting::where([['root_id', '=', $root_id], ['name', '=', 'pubpool']])->findOrEmpty();
  4220. $error = 0;
  4221. $repeat = 0;
  4222. foreach ($list as $k => $v) {
  4223. //查询重复
  4224. $l_phone = array_filter([$v->getData('phone'), $v->getData('phone1'), $v->getData('phone2')]);
  4225. $query = [];
  4226. $query[] = ['phone|phone1|phone2', 'in', $l_phone];
  4227. $query[] = ['employee_id', '=', $v->employee_id];
  4228. $check = Customer::where($query)->findOrEmpty();
  4229. if (!$check->isEmpty()) {
  4230. $repeat += 1;
  4231. continue;
  4232. }
  4233. $customer_state = Customer::changeState($v['state'], 'n');
  4234. $info = $v->toArray();
  4235. $info['protected_to'] = null;
  4236. if (!empty($setting)) {
  4237. $setting_content = json_decode($setting['content'], true);
  4238. } else {
  4239. $setting_content = [];
  4240. }
  4241. if (!empty($setting_content[$customer_state]['state']) && $setting_content[$customer_state]['state'] != 0 && !empty($setting_content[$customer_state]['day'])) {
  4242. $day = $setting_content[$customer_state]['day'];
  4243. $info['protected_to'] = $day > 0 ? date('Y-m-d H:i:s', time() + $day * 24 * 3600) : null;
  4244. }
  4245. $info['deposit_money'] = $v->getData('deposit_money');
  4246. $info['signed_money'] = $v->getData('signed_money');
  4247. $info['id'] = $info['customer_id'];
  4248. unset($info['customer_id']);
  4249. unset($info['droptime']);
  4250. unset($info['add_wechat_time']);
  4251. unset($info['group_building_date']);
  4252. unset($info['live_broadcast_date']);
  4253. unset($info['subscribe_meet_outside']);
  4254. unset($info['meet_outside']);
  4255. unset($info['sign_time']);
  4256. unset($info['reputation_gather']);
  4257. unset($info['into_owner_group']);
  4258. Db::startTrans();
  4259. $result = Customer::create($info);
  4260. $d_result = $v->delete();
  4261. if ($result && $d_result) {
  4262. Db::commit();
  4263. $param = [
  4264. 'customer_id' => $info['id'],
  4265. 'type' => 1,
  4266. 'remark' => '客户还原',
  4267. 'employee_id' => $this->request->token['employee_id'],
  4268. 'user_id' => $this->request->token['uid'],
  4269. 'state' => ''
  4270. ];
  4271. CustomerVisitLog::create($param);
  4272. } else {
  4273. Db::rollback();
  4274. $error++;
  4275. }
  4276. }
  4277. if ($repeat) return json(['code' => 1, 'msg' => '有' . $repeat . '条客户手机号已经属于业务员,无法还原']);
  4278. if ($error == 0) {
  4279. return json(['code' => 0, 'msg' => '操作成功']);
  4280. } else {
  4281. return json(['code' => 0, 'msg' => '操作成功,部分数据失败']);
  4282. }
  4283. }
  4284. /**
  4285. * 自动回收再分配
  4286. */
  4287. public function drop_pool_resdistribute()
  4288. {
  4289. $id = input('id', '', 'trim');
  4290. $employee_id = input('employee_id', '', 'intval');
  4291. $from = input('from', '', 'trim');
  4292. $target_ids_arr = explode(',', $id);
  4293. if (!empty($employee_id)) {
  4294. $emp_obj = Employee::find($employee_id);
  4295. $org_id = $emp_obj->org_id;
  4296. } else {
  4297. return json(['code' => 1, 'msg' => '操作失败']);
  4298. }
  4299. $root_id = request()->token['root_org'];
  4300. $subOrg = orgSubIds($root_id);
  4301. $target_ids_arr = Customer::where([['id', 'in', $target_ids_arr], ['org_id', 'in', $subOrg]])->column('id');
  4302. //2022-10-21 19:25:59-----------------
  4303. //2022-10-21 重复录入 重复验证 check=1,2&3,4 表示ID=2和3的客户手机号重复 1,4不重复
  4304. $repeat_customer = [];
  4305. $vislog_id = []; //跟进记录合并数组
  4306. $z_type = $from;
  4307. if (input('check', '')) {
  4308. $target_ids_arr = [];
  4309. $check_arr = explode(',', input('check', ''));
  4310. //先已第一个位置 以后可能会已保护期排序
  4311. foreach ($check_arr as $check_arr_key => $check_arr_val) {
  4312. //默认第一个ID 为准
  4313. $temporary_arr = explode('@', $check_arr_val);
  4314. $vislog_id[$temporary_arr[0]] = $temporary_arr;
  4315. }
  4316. foreach ($vislog_id as $vislog_id_key => $vislog_id_val) {
  4317. $temporary_customer = ($from == 'index') ? Customer::where('id', $vislog_id_key)->find() : CustomerDropPool::where('id', $vislog_id_key)->find();
  4318. $query = [];
  4319. $query[] = ['employee_id', '=', $employee_id];
  4320. $l_phone = array_filter([$temporary_customer->getData('phone'), $temporary_customer->getData('phone1'), $temporary_customer->getData('phone2')]);
  4321. $query[] = ['phone|phone1|phone2', 'in', $l_phone];
  4322. $check = Customer::where($query)->findOrEmpty();
  4323. if ($check->isEmpty()) {
  4324. $target_ids_arr[] = $vislog_id_key;
  4325. } else {
  4326. $repeat_customer[] = $temporary_customer->name;
  4327. }
  4328. }
  4329. }
  4330. if ($repeat_customer) {
  4331. return json(['code' => 1, 'msg' => '您选择的客户“' . implode('”,“', $repeat_customer) . '”手机号已经属于业务员' . $emp_obj->name . '请重新选择']);
  4332. }
  4333. if ($z_type != 'index') {
  4334. $drop = $vislog_id;
  4335. $vislog_ids = [];
  4336. foreach ($vislog_id as $k => $v) {
  4337. $ls_id = CustomerDropPool::where('id', $k)->value('customer_id');
  4338. $vislog_ids[$ls_id] = CustomerDropPool::where([['id', 'in', $v]])->column('customer_id');
  4339. }
  4340. $vislog_id = $vislog_ids;
  4341. }
  4342. //2022-10-21 19:25:59-----------------
  4343. $root_id = $this->request->token['root_org'];
  4344. $setting = Setting::where([['root_id', '=', $root_id], ['name', '=', 'pubpool']])->findOrEmpty();
  4345. $error = 0;
  4346. $repeat = [];
  4347. if (!empty($target_ids_arr)) {
  4348. if ($from == 'index') {
  4349. $list = Customer::where([['id', 'in', $target_ids_arr]])->select();
  4350. if (!$list->isEmpty()) {
  4351. foreach ($list as $k => $v) {
  4352. //如果该客户已经属于业务员则不需要分配 ,提示分配人
  4353. if ($v->employee_id == $employee_id) {
  4354. $repeat[] = [$v->name, $v->phone];
  4355. continue;
  4356. }
  4357. $customer_state = Customer::changeState($v['state'], 'n');
  4358. $v_data['protected_to'] = null;
  4359. if (!$setting->isEmpty()) {
  4360. $setting_content = !empty($setting['content']) ? json_decode($setting['content'], true) : [];
  4361. if (!empty($setting_content[$customer_state]['state']) && $setting_content[$customer_state]['state'] != 0 && !empty($setting_content[$customer_state]['day'])) {
  4362. $day = $setting_content[$customer_state]['day'];
  4363. $v_data['protected_to'] = date('Y-m-d H:i:s', time() + $day * 24 * 3600);
  4364. }
  4365. }
  4366. // //重复手机号验证 ,如果重复则合并客户信息和跟进记录
  4367. // $query = [];
  4368. // $l_phone = array_filter([$v->getData('phone'),$v->getData('phone1'),$v->getData('phone2')]);
  4369. // $query[] = ['phone|phone1|phone2','in',$l_phone];
  4370. // $query[] = ['employee_id','=',$employee_id];
  4371. // $check = Customer::where($query)->column('*');
  4372. // if ($check) {
  4373. // $this->customerMerge($v->id,$check,'emp',$v_data['protected_to']);
  4374. // continue;
  4375. // }
  4376. $v_data['employee_id'] = $employee_id;
  4377. $v_data['org_id'] = $org_id;
  4378. $v_data['ext->ext6'] = '';
  4379. $v_data['designer_id'] = NULL;
  4380. $v_data['revisit_time'] = NULL;
  4381. $result = Customer::where('id', $v['id'])->update($v_data);
  4382. if ($result === false) {
  4383. $error++;
  4384. } else {
  4385. $param = [
  4386. 'customer_id' => $v->id,
  4387. 'type' => 1,
  4388. 'remark' => '客户再分配',
  4389. 'employee_id' => $this->request->token['employee_id'],
  4390. 'user_id' => $this->request->token['uid'],
  4391. 'state' => ''
  4392. ];
  4393. CustomerVisitLog::create($param);
  4394. }
  4395. }
  4396. }
  4397. } elseif ($from == 'drop') {
  4398. $list = CustomerDropPool::where([['id', 'in', $target_ids_arr]])->select();
  4399. if (!$list->isEmpty()) {
  4400. foreach ($list as $k => $v) {
  4401. $customer_state = Customer::changeState($v['state'], 'n');
  4402. $info = $v->toArray();
  4403. $info['protected_to'] = null;
  4404. if (!$setting->isEmpty()) {
  4405. $setting_content = !empty($setting['content']) ? json_decode($setting['content'], true) : [];
  4406. if (!empty($setting_content[$customer_state]['state']) && $setting_content[$customer_state]['state'] != 0 && !empty($setting_content[$customer_state]['day'])) {
  4407. $day = $setting_content[$customer_state]['day'];
  4408. $info['protected_to'] = date('Y-m-d H:i:s', time() + $day * 24 * 3600);
  4409. }
  4410. }
  4411. // //重复手机号验证 ,如果重复则合并客户信息和跟进记录
  4412. // $query = [];
  4413. // $l_phone = array_filter([$v->getData('phone'),$v->getData('phone1'),$v->getData('phone2')]);
  4414. // $query[] = ['phone|phone1|phone2','in',$l_phone];
  4415. // $query[] = ['employee_id','=',$employee_id];
  4416. // $check = Customer::where($query)->column('*');
  4417. // if ($check) {
  4418. // $this->customerMerge($v->id,$check,'drop',$info['protected_to']);
  4419. // continue;
  4420. // }
  4421. Customer::where('id', $info['customer_id'])->delete(); //删除错误数据
  4422. $info['employee_id'] = $employee_id;
  4423. $info['org_id'] = $org_id;
  4424. $info['id'] = $info['customer_id'];
  4425. $info['signed_money'] = $v->getData('signed_money');
  4426. $info['deposit_money'] = $v->getData('deposit_money');
  4427. $info['designer_id'] = NULL;
  4428. $info['revisit_time'] = NULL;
  4429. unset($info['customer_id']);
  4430. unset($info['droptime']);
  4431. unset($info['add_wechat_time']);
  4432. unset($info['group_building_date']);
  4433. unset($info['live_broadcast_date']);
  4434. unset($info['subscribe_meet_outside']);
  4435. unset($info['meet_outside']);
  4436. unset($info['sign_time']);
  4437. unset($info['reputation_gather']);
  4438. unset($info['into_owner_group']);
  4439. Db::startTrans();
  4440. $result = Customer::create($info);
  4441. $d_result = $v->delete();
  4442. if (!empty($drop[$v->id])) CustomerDropPool::where([['id', 'in', $drop[$v->id]]])->delete();
  4443. if ($result && $d_result) {
  4444. $result['ext->ext6'] = '';
  4445. $result->save();
  4446. Db::commit();
  4447. $param = [
  4448. 'customer_id' => $v->customer_id,
  4449. 'type' => 1,
  4450. 'remark' => '客户再分配',
  4451. 'employee_id' => $this->request->token['employee_id'],
  4452. 'user_id' => $this->request->token['uid'],
  4453. 'state' => ''
  4454. ];
  4455. CustomerVisitLog::create($param);
  4456. } else {
  4457. Db::rollback();
  4458. $error++;
  4459. }
  4460. }
  4461. }
  4462. }
  4463. }
  4464. // if($repeat) return json(['code' => 1, 'msg' => '有'.count($repeat).'条客户已经属于所选业务员,无法分配']);
  4465. if ($error == 0) {
  4466. //2022-10-21 19:25:59-----------------
  4467. $this->customerMerge($vislog_id, $z_type);
  4468. //2022-10-21 19:25:59-----------------
  4469. return json(['code' => 0, 'msg' => '操作成功']);
  4470. } else {
  4471. return json(['code' => 0, 'msg' => '操作成功,部分数据失败']);
  4472. }
  4473. }
  4474. /**
  4475. * 合并跟进数据
  4476. */
  4477. private function customerMerge($array, $type)
  4478. {
  4479. foreach ($array as $array_key => $array_val) {
  4480. foreach ($array_val as $item) {
  4481. if ($array_key != $item) Customer::destroy($item);
  4482. }
  4483. $query = [];
  4484. $query[] = ['customer_id', 'in', $array_val];
  4485. $query[] = ['customer_id', '<>', $array_key];
  4486. CustomerVisitLog::where($query)->update(['customer_id' => $array_key, 'is_merge' => 1]);
  4487. CustomersSubscribe::where($query)->update(['customer_id' => $array_key, 'is_merge' => 1]);
  4488. }
  4489. return true;
  4490. }
  4491. /**
  4492. * 主动回收
  4493. */
  4494. public function drop_to_pool()
  4495. {
  4496. $ids = input('id', '', 'trim');
  4497. $orgIds = orgSubIds($this->request->token['root_org']);
  4498. $data = Customer::where([['org_id', 'in', $orgIds], ['id', 'in', $ids]])->select();
  4499. foreach ($data as $item) {
  4500. Db::startTrans();
  4501. $drop_data = $item->toArray();
  4502. $drop_data['customer_id'] = $drop_data['id'];
  4503. $drop_data['deposit_money'] = $item->getData('deposit_money');
  4504. $drop_data['signed_money'] = $item->getData('signed_money');
  4505. unset($drop_data['id']);
  4506. unset($drop_data['add_wechat_time']);
  4507. unset($drop_data['group_building_date']);
  4508. unset($drop_data['live_broadcast_date']);
  4509. unset($drop_data['subscribe_meet_outside']);
  4510. unset($drop_data['meet_outside']);
  4511. unset($drop_data['sign_time']);
  4512. unset($drop_data['reputation_gather']);
  4513. unset($drop_data['into_owner_group']);
  4514. $save_result = CustomerDropPool::create($drop_data);
  4515. $delete_result = $item->force()->delete();
  4516. $record_data['customer_id'] = $item->id;
  4517. CustomerDropRecord::create($record_data);
  4518. // 客户预约中改为无效
  4519. CustomersSubscribe::where([['customer_id', '=', $item->id], ['state', '=', 0]])->save(['state' => -1]);
  4520. if ($save_result && $delete_result) {
  4521. Db::commit();
  4522. $param = [
  4523. 'customer_id' => $item->id,
  4524. 'type' => 1,
  4525. 'remark' => '客户回收',
  4526. 'employee_id' => $this->request->token['employee_id'],
  4527. 'user_id' => $this->request->token['uid'],
  4528. 'state' => ''
  4529. ];
  4530. CustomerVisitLog::create($param);
  4531. } else {
  4532. Db::rollback();
  4533. }
  4534. }
  4535. return json(['code' => self::success, 'msg' => '回收成功']);
  4536. }
  4537. public function drop_to_pool_check()
  4538. {
  4539. $ids = input('id', '', 'trim');
  4540. $customer_list = Customer::where([['id', 'in', $ids]])->select();
  4541. $state_list = $customer_list->column('state');
  4542. $sign_state = Customer::changeState('签单', 'chaos');
  4543. $sign_count = 0;
  4544. foreach ($state_list as $k => $v) {
  4545. if (in_array($v, $sign_state)) {
  4546. $sign_count++;
  4547. }
  4548. }
  4549. $protected = 0;
  4550. $setting = Setting::where([['name', '=', 'pubpool'], ['root_id', '=', $this->request->token['root_org']]])->find();
  4551. if (!empty($setting)) {
  4552. $content = !empty($setting['content']) ? json_decode($setting['content'], true) : [];
  4553. if (!empty($content)) {
  4554. $empty = false; //判断是否是正常数据,因为之前可能有垃圾数据
  4555. foreach ($content as $k => $v) {
  4556. if (!isset($v['day']) || !isset($v['state'])) {
  4557. $empty = true;
  4558. }
  4559. }
  4560. if (!$empty) {
  4561. foreach ($customer_list as $k => $v) {
  4562. $n = Customer::changeState($v['state'], 'n');
  4563. foreach ($content as $kk => $vv) {
  4564. if (intval($kk) == intval($n) && $vv['state'] == 1 && $vv['day'] > 0 && !empty($v['protected_to']) && $v['protected_to'] > date('Y-m-d H:i:s', time())) {
  4565. $protected++;
  4566. }
  4567. }
  4568. }
  4569. }
  4570. }
  4571. }
  4572. $msg = '';
  4573. if ($sign_count && $protected) {
  4574. $msg = '包含已签单及未到保护期客户';
  4575. } elseif ($sign_count) {
  4576. $msg = '包含已签单客户';
  4577. } elseif ($protected) {
  4578. $msg = '包含未到保护期客户';
  4579. }
  4580. if ($msg == '') {
  4581. return json(['code' => self::success, 'msg' => '']);
  4582. } else {
  4583. return json(['code' => self::error_msg, 'msg' => $msg]);
  4584. }
  4585. }
  4586. /**
  4587. * 客户互动 短信
  4588. */
  4589. public function sms($customerid, $type)
  4590. {
  4591. $num = CustomerSmsLog::where([['sendTime', 'between', [date('Ymd') . '000000', date('Ymd', strtotime('+1 day')) . '000000']], ['employee_id', '=', $this->request->token['employee_id']], ['state', '=', 0]])->count();
  4592. if ($num >= 3) return json(['code' => 1, 'msg' => '今日短信条数已用尽']);
  4593. $customer = Customer::where([['id', '=', $customerid]])->find();
  4594. if (empty($customer)) return json(['code' => 1, 'msg' => '客户不存在']);
  4595. if ($customer->employee_id != $this->request->token['employee_id'] && $customer->designer_id != $this->request->token['employee_id']) {
  4596. if (isset($this->request->token['isManager']) && $this->request->token['isManager']) {
  4597. $orgidList = orgSubIds($this->request->token['org_id']);
  4598. $checkOrg = -1;
  4599. if ($this->request->token['org_type'] == 2 && !empty($customer->designer_id)) {
  4600. $checkOrg = Employee::where(['id' => $customer->designer_id])->value('org_id');
  4601. } elseif ($this->request->token['org_type'] == 1) {
  4602. $checkOrg = Employee::where(['id' => $customer->employee_id])->value('org_id');
  4603. }
  4604. if (!in_array($checkOrg, $orgidList))
  4605. return json(['code' => 1, 'msg' => '客户不存在']);
  4606. }
  4607. }
  4608. $param = $this->request->param();
  4609. // 存储参数
  4610. $data = [
  4611. 'content' => json_encode($param),
  4612. 'type' => 'share'
  4613. ];
  4614. $shortUrl = ShortUrl::create($data);
  4615. // 将ID进行
  4616. $uri = dec52($shortUrl->id);
  4617. $shortUrl->uri = $uri;
  4618. $shortUrl->save();
  4619. $typeContentList = [
  4620. 'employeeCard' => '我的个人名片',
  4621. 'screen' => '我推荐的内容',
  4622. 'materialCase' => '我推荐的装修案例',
  4623. 'evidenceCate' => '我推荐的公司口碑',
  4624. ];
  4625. $typeContent = $typeContentList[$type];
  4626. $companyName = Org::where([['id', '=', $this->request->token['root_org']]])->value('name');
  4627. $employee_name = Employee::where([['id', '=', $this->request->token['employee_id']]])->value('name');
  4628. $domain = request()->domain();
  4629. $content = '【装修宝】老师您好, 我是{$var}的{$var},这是{$var}, 请您查看' . $domain . '/{$var}';
  4630. $param = "{$customer->phone},{$companyName},{$employee_name},{$typeContent},{$uri}";
  4631. $smsObj = new ChuanglanSmsApi();
  4632. $result = $smsObj->sendVariableSMS($content, $param);
  4633. $rs = json_decode($result, true);
  4634. if ($rs['code'] != 0) {
  4635. return json(['code' => 1, 'msg' => $rs['errorMsg']]);
  4636. }
  4637. // 创建发送记录
  4638. $log = [
  4639. 'customer_id' => $customerid,
  4640. 'employee_id' => $this->request->token['employee_id'],
  4641. 'org_type' => $this->request->token['org_type'],
  4642. 'type' => $type,
  4643. 'phone' => $customer->phone,
  4644. 'sendTime' => $rs['time'],
  4645. 'msgId' => $rs['msgId']
  4646. ];
  4647. CustomerSmsLog::create($log);
  4648. return json(['code' => 0, 'msg' => '发送成功']);
  4649. }
  4650. /**
  4651. * 短信发送记录
  4652. */
  4653. public function smslog($id)
  4654. {
  4655. $customer = Customer::where(['id' => $id])->find();
  4656. if (empty($customer)) return json(['code' => 0, 'data' => []]);
  4657. // 检测客户所属(部门领导查看,设计师查看,销售查看,销售的部门领导)
  4658. if ($customer->employee_id != $this->request->token['employee_id'] && $customer->designer_id != $this->request->token['employee_id']) {
  4659. if (isset($this->request->token['isManager']) && $this->request->token['isManager']) {
  4660. $orgidList = orgSubIds($this->request->token['org_id']);
  4661. $checkOrg = -1;
  4662. if ($this->request->token['org_type'] == 2 && !empty($customer->designer_id)) {
  4663. $checkOrg = Employee::where(['id' => $customer->designer_id])->value('org_id');
  4664. } elseif ($this->request->token['org_type'] == 1) {
  4665. $checkOrg = Employee::where(['id' => $customer->employee_id])->value('org_id');
  4666. }
  4667. if (!in_array($checkOrg, $orgidList))
  4668. return json(['code' => 0, 'data' => []]);
  4669. }
  4670. }
  4671. // 查询记录
  4672. // $page = $this->request->only(['page', 'limit']);
  4673. // $log = CustomerSmsLog::with('employee')->field('id,type,errorMsg')->where(['customer_id' => $id])->page($page['page'], $page['limit'])->order('id desc')->select();
  4674. $log = CustomerSmsLog::with('employee')->field('id,type,errorMsg,state,sendTime,employee_id,org_type')->where(['customer_id' => $id])->order('id desc')->select();
  4675. return json(['code' => 0, 'data' => $log]);
  4676. }
  4677. /**
  4678. * 获取提醒和跟进最新时间
  4679. */
  4680. public function get_date()
  4681. {
  4682. $token = $this->request->token;
  4683. $w[] = ['employee_id', '=', $token['employee_id']];
  4684. //我的客户
  4685. $cids = Customer::where($w)->column('id');
  4686. $state1 = CustomerVisitLog::changeState('预约量房', 'chaos');
  4687. $state2 = CustomerVisitLog::changeState('预约到店', 'chaos');
  4688. $state3 = CustomerVisitLog::changeState('预约活动', 'chaos');
  4689. // //提醒的最新时间
  4690. // $w1[] = ['customer_id', 'in', $cids];
  4691. // $w1[] = ['state', 'in', array_merge($state1, $state2, $state3)];
  4692. // $date = CustomerVisitLog::where($w1)->order('next_contact_date desc')->value('next_contact_date');
  4693. // $date = $date ? (strtotime($date) >= strtotime(date('Y-m')) ? date('Y-m', strtotime($date)) : date('Y-m')) : '';
  4694. //跟进的最新时间
  4695. $state4 = CustomerVisitLog::changeState('无效', 'chaos');
  4696. //$state5 = CustomerVisitLog::changeState('预约回访', 'chaos');
  4697. $state = array_merge($state1, $state2, $state3, $state4);
  4698. $w2[] = ['customer_id', 'in', $cids];
  4699. $w2[] = ['state', 'not in', $state];
  4700. $date1 = CustomerVisitLog::where($w2)->order('next_contact_date desc')->value('next_contact_date');
  4701. $date1 = $date1 ? (strtotime($date1) >= strtotime(date('Y-m')) ? date('Y-m', strtotime($date1)) : date('Y-m')) : '';
  4702. $date = CustomersSubscribe::where([
  4703. ['employee_id|designer_id', '=', $token['employee_id']],
  4704. ['state', '=', 0]
  4705. ])->order('subscribe_date desc')->value('subscribe_date');
  4706. $date = $date ? (strtotime($date) >= strtotime(date('Y-m')) ? date('Y-m', strtotime($date)) : date('Y-m')) : '';
  4707. $res['remind'] = $date;
  4708. $res['followup'] = $date1;
  4709. return json(['code' => 0, 'data' => $res]);
  4710. }
  4711. /**
  4712. * 客户预约记录
  4713. */
  4714. public function subscribe($id)
  4715. {
  4716. // 检测是否是我的客户
  4717. $customer = Customer::where(['id' => $id])->find();
  4718. if (empty($customer)) return json(['code' => 0, 'data' => []]);
  4719. // 检测客户所属(部门领导查看,设计师查看,销售查看,销售的部门领导)
  4720. if ($customer->employee_id != $this->request->token['employee_id'] && $customer->designer_id != $this->request->token['employee_id']) {
  4721. if (isset($this->request->token['isManager']) && $this->request->token['isManager']) {
  4722. $orgidList = orgSubIds($this->request->token['org_id']);
  4723. $checkOrg = -1;
  4724. if ($this->request->token['org_type'] == 2 && !empty($customer->designer_id)) {
  4725. $checkOrg = Employee::where(['id' => $customer->designer_id])->value('org_id');
  4726. } elseif ($this->request->token['org_type'] == 1) {
  4727. $checkOrg = Employee::where(['id' => $customer->employee_id])->value('org_id');
  4728. }
  4729. if (!in_array($checkOrg, $orgidList))
  4730. return json(['code' => 0, 'data' => []]);
  4731. } else {
  4732. return json(['code' => 0, 'data' => []]);
  4733. }
  4734. }
  4735. // 查询记录
  4736. $data = CustomersSubscribe::withoutField('org_id')->with(['employee' => function ($query) {
  4737. $query->withfield(['id', 'name']);
  4738. }, 'designer' => function ($query) {
  4739. $query->withfield(['id', 'name']);
  4740. }])->where([['customer_id', '=', $customer->id]])->order('addtime desc')->select();
  4741. return json(['code' => 0, 'data' => $data]);
  4742. }
  4743. /**
  4744. * 未回访记录
  4745. */
  4746. public function notVisitLog($page = 1, $date = null, $keyword = null)
  4747. {
  4748. // 判断当前登陆人是不是领导
  4749. if (!$this->request->token['isManager']) return json(['code' => 0, 'data' => []]);
  4750. $cOrgId = (new Org())->getChildOrg($this->request->token['org_id']);
  4751. $condition = [
  4752. ['org_id', 'in', $cOrgId]
  4753. ];
  4754. $orCondition = [];
  4755. if ($date) $condition[] = ['appoint_date', '=', $date];
  4756. if (!empty($keyword)) {
  4757. $guodu = CustomerNotVisit::where($condition)->column('customer_id,employee_id,designer_id,org_id');
  4758. if (empty($guodu)) return json(['code' => 0, 'data' => []]);
  4759. $customerIdLIst = Customer::where([['id', 'in', array_column($guodu, 'customer_id')], ['name', 'like', '%' . $keyword . '%']])->column('id');
  4760. $employeeIdList = Employee::where([
  4761. ['name', 'like', '%' . $keyword . '%'],
  4762. ['id', 'in', array_column($guodu, 'employee_id')]
  4763. ])->column('id');
  4764. $designerIdList = Employee::where([
  4765. ['name', 'like', '%' . $keyword . '%'],
  4766. ['id', 'in', array_column($guodu, 'designer_id')]
  4767. ])->column('id');
  4768. $orgIdList = Org::where([
  4769. ['name', 'like', '%' . $keyword . '%'],
  4770. ['id', 'in', array_column($guodu, 'org_id')]
  4771. ])->column('id');
  4772. $orCondition = [
  4773. ['employee_id', 'in', $employeeIdList],
  4774. ['designer_id', 'in', $designerIdList],
  4775. ['org_id', 'in', $orgIdList],
  4776. ['customer_id', 'in', $customerIdLIst]
  4777. ];
  4778. }
  4779. $data = CustomerNotVisit::with([
  4780. 'customer' => function ($query) {
  4781. $query->withField(['id', 'name', 'sex', 'level', 'community_name']);
  4782. },
  4783. 'employee' => function ($query) {
  4784. $query->withField(['id', 'name']);
  4785. },
  4786. 'designer' => function ($query) {
  4787. $query->withField(['id', 'name']);
  4788. },
  4789. 'org' => function ($query) {
  4790. $query->withField(['id', 'name']);
  4791. }
  4792. ])->where(function ($query) use ($orCondition) {
  4793. $query->whereOr($orCondition);
  4794. })->where($condition)
  4795. ->page($page, 30)
  4796. ->order('addtime desc')
  4797. ->select();
  4798. return json(['code' => 0, 'data' => $data]);
  4799. }
  4800. /**
  4801. * 客户报备自定义
  4802. * type:add根据后台勾选展示,edit展示全部
  4803. */
  4804. public function get_portrait_field()
  4805. {
  4806. $id = input('id', '', 'trim');
  4807. $type = input('type');
  4808. $token = $this->request->token;
  4809. $where = [
  4810. ['root_id', '=', $token['root_org']],
  4811. ['pid', '>', 0],
  4812. ['status', '=', 0]
  4813. ];
  4814. if ($type == 'add') {
  4815. $setting = Setting::where([['name', '=', 'settingCustomerReportField'], ['root_id', '=', $token['root_org']]])->find();
  4816. if ($setting && !empty($setting['content'])) {
  4817. $all_content = json_decode($setting['content'], true);
  4818. $field_id = array_column($all_content, 'id');
  4819. $where[] = ['id', 'in', $field_id];
  4820. } else {
  4821. //默认值
  4822. $where[] = ['keyname', 'in', ['name', 'phone', 'sex', 'age_range', 'intention', 'consumption_capacity', 'current_region', 'source_id', 'first', 'add_wechat_type', 'add_wechat_time', 'group_building', 'live_broadcast', 'group_building_date', 'follow', 'point', 'wechat', 'talking_about_single_time', 'community_name', 'unit_number', 'house_location', 'square', 'housetype_arrow', 'deco_style', 'house_type', 'house_status', 'plan_deco_time', 'budget', 'housing_use', 'peripheral_supporting', 'house_structure', 'decoration_mode', 'like_color', 'customer_demand', 'remarks_on_other_house_information', 'family_structure', 'decision_maker', 'family_opinion', 'hourse_price', 'car_price', 'buying_community', 'hobby', 'free_time', 'environmental_requirements', 'design', 'workmanship', 'space_design', 'service_satisfaction', 'quotation_satisfaction', 'program_satisfaction']];
  4823. }
  4824. }
  4825. //获取第二层
  4826. $all = CustomerPortraitField::with(['select'])->where($where)->orderRaw('if(isnull(sort),1,0),sort asc')->select()->toArray();
  4827. if ($type == 'add' && $setting && !empty($setting['content'])) {
  4828. //如果是设置自定义展示,则循序按照勾选的排序进行组装
  4829. $all_new = [];
  4830. foreach ($all_content as $c) {
  4831. foreach ($all as $vals) {
  4832. if ($c['id'] == $vals['id']) {
  4833. $all_new[] = $vals;
  4834. }
  4835. }
  4836. }
  4837. $all = $all_new;
  4838. }
  4839. $city = Company::where('root_id', $token['root_org'])->value('city');
  4840. foreach ($all as &$val) {
  4841. if ($val['keyname'] == 'current_region') {
  4842. $val['select'][] = ['id' => $token['root_org'], 'name' => $city, 'pid' => $val['id']];
  4843. }
  4844. if ($val['keyname'] == 'source_id') {
  4845. $val['select'] = CustomerSource::field('id,source as name')->where('root_id', $token['root_org'])->select()->toArray();
  4846. }
  4847. if ($val['keyname'] == 'deco_style') {
  4848. $val['select'] = Decostyle::field('id,name')->where([['root_id', '=', $token['root_org']], ['type', '=', 0]])->select()->toArray();
  4849. }
  4850. }
  4851. //获取第一层
  4852. $pid = array_column($all, 'pid');
  4853. $list = CustomerPortraitField::where([['id', 'in', $pid], ['status', '=', 0], ['pid', '=', 0]]);
  4854. if ($type == 'add' && $setting && !empty($setting['content'])) {
  4855. //如果是添加页面,把自定义字段追加到基本信息child下
  4856. $list = $list->order('id')->limit(1)->select()->toArray();
  4857. } else {
  4858. $list = $list->orderRaw('if(isnull(sort),1,0),sort asc')->select()->toArray();
  4859. }
  4860. //组装数组
  4861. foreach ($list as &$p) {
  4862. foreach ($all as &$item) {
  4863. $item['value'] = '';
  4864. $item['valname'] = '';
  4865. if ($type == 'add' && $setting && !empty($setting['content'])) {
  4866. $p['child'][] = $item;
  4867. } else {
  4868. if ($p['id'] == $item['pid']) $p['child'][] = $item;
  4869. }
  4870. }
  4871. }
  4872. $cuslog = new CustomerLogic;
  4873. if (isset($id) && !empty($id)) {
  4874. $cusdata = Customer::where([['id', '=', $id]])->find()->toArray();
  4875. if (!empty($cusdata['ext']) && $cusdata['ext'] != 'null') {
  4876. $extdata = json_decode($cusdata['ext'], true);
  4877. if (isset($extdata['ext1'])) {
  4878. $list = $cuslog->old_data_save($cusdata, $list);
  4879. } else {
  4880. $list = $cuslog->new_data_save($cusdata, $extdata, $list);
  4881. }
  4882. } else {
  4883. $list = $cuslog->no_ext_save($cusdata, $list);
  4884. }
  4885. }
  4886. return json(['code' => 0, 'msg' => '获取成功', 'data' => $list]);
  4887. }
  4888. /**
  4889. * 手机端验证报名客户必填字段
  4890. */
  4891. public function check_must_field($ext)
  4892. {
  4893. $token = $this->request->token;
  4894. $house_type_value = '';
  4895. $live_broadcast_value = [];
  4896. foreach ($ext as $key => $val) {
  4897. if ($val['keyname'] == 'house_type' && !empty($val['value'])) {
  4898. $house_type_value = CustomerPortraitFieldSelect::where([['pid', '=', $val['id']], ['id', '=', $val['value']]])->value('name');
  4899. }
  4900. if ($val['keyname'] == 'live_broadcast' && !empty($val['value'])) {
  4901. $live_broadcast_value = CustomerPortraitFieldSelect::where([['pid', '=', $val['id']], ['id', 'in', explode(',', $val['value'])]])->column('name');
  4902. }
  4903. }
  4904. //判断必填项
  4905. $must_list = CustomerPortraitField::where([['root_id', '=', $token['root_org']], ['pid', '<>', 0], ['is_must', '=', 0]])->column('name', 'keyname');
  4906. foreach ($ext as $key => $val) {
  4907. if ($house_type_value != '期房' && $val['keyname'] == 'house_delivery_time' && in_array($val['keyname'], array_keys($must_list))) continue;
  4908. if (!in_array('1对1业务直播', $live_broadcast_value) && $val['keyname'] == 'live_broadcast_business' && in_array($val['keyname'], array_keys($must_list))) continue;
  4909. if (!in_array('1对1设计直播', $live_broadcast_value) && $val['keyname'] == 'live_broadcast_design' && in_array($val['keyname'], array_keys($must_list))) continue;
  4910. if (!in_array('一对多直播', $live_broadcast_value) && $val['keyname'] == 'live_broadcast_personnel' && in_array($val['keyname'], array_keys($must_list))) continue;
  4911. if (in_array($val['keyname'], array_keys($must_list)) && empty($val['value'])) {
  4912. return json(['code' => 1, 'msg' => $must_list[$val['keyname']] . '为必填项']);
  4913. }
  4914. }
  4915. }
  4916. //新添加客户扩展字段
  4917. public function add_customer_extfield()
  4918. {
  4919. $token = $this->request->token;
  4920. $ext = input('ext', '', 'trim');
  4921. $id = input('id');
  4922. $subOrg = orgSubIds($token['root_org']);
  4923. $cda = Customer::find($id);
  4924. if (empty($cda) || !in_array($cda['org_id'], $subOrg)) {
  4925. return json(['code' => 1, 'msg' => '客户数据为空']);
  4926. }
  4927. if (empty($ext)) return json(['code' => 1, 'msg' => '暂未设置数据']);
  4928. $seldata = CustomerPortraitField::with(['select'])->where([['root_id', '=', $token['root_org']], ['type', 'in', [3, 4]]])->select()->toArray();
  4929. $allselid = [];
  4930. foreach ($seldata as $key => $val) {
  4931. foreach ($val['select'] as $k => $v) {
  4932. $allselid[] = ['id' => $v['id'], 'name' => $v['name']];
  4933. }
  4934. }
  4935. foreach ($ext as $key => $val) {
  4936. $selval = '';
  4937. if ($val['keyname'] == 'community_name') {
  4938. $house_data['community_name'] = $val['value'];
  4939. }
  4940. if ($val['keyname'] == 'square') {
  4941. $house_data['square'] = $val['value'];
  4942. }
  4943. if ($val['keyname'] == 'house_type') {
  4944. foreach ($allselid as $k => $v) {
  4945. if ($val['value'] == $v['id']) {
  4946. $selval = $v['name'];
  4947. }
  4948. }
  4949. $house_data['house_type'] = $selval;
  4950. }
  4951. if ($val['keyname'] == 'house_status') {
  4952. foreach ($allselid as $k => $v) {
  4953. if ($val['value'] == $v['id']) {
  4954. $selval = $v['name'];
  4955. }
  4956. }
  4957. $house_data['house_status'] = $selval;
  4958. }
  4959. if ($val['keyname'] == 'house_delivery_time') {
  4960. $house_data['house_delivery_time'] = $val['value'];
  4961. }
  4962. if ($val['keyname'] == 'plan_deco_time') {
  4963. $house_data['plan_deco_time'] = $val['value'];
  4964. }
  4965. if ($val['keyname'] == 'budget') {
  4966. $house_data['budget'] = $val['value'];
  4967. }
  4968. if ($val['keyname'] == 'deco_style') {
  4969. foreach ($allselid as $k => $v) {
  4970. if ($val['value'] == $v['id']) {
  4971. $selval = $v['name'];
  4972. }
  4973. }
  4974. $house_data['deco_style'] = $selval;
  4975. }
  4976. if ($val['keyname'] == 'follow') {
  4977. if (!empty($val['value'])) {
  4978. $gza = explode(',', $val['value']);
  4979. foreach ($allselid as $k => $v) {
  4980. if (in_array($v['id'], $gza)) {
  4981. $selval .= $v['name'] . ',';
  4982. }
  4983. }
  4984. }
  4985. $house_data['product'] = trim($selval, ',');
  4986. }
  4987. if ($val['type'] == 6 && !empty($val['value'])) {
  4988. //上传图片类型
  4989. $file_media_id = [];
  4990. foreach ($val['value'] as $k => $img) {
  4991. $file_media_id[$k] = [
  4992. 'serverId' => !empty($img['serverId']) ? $img['serverId'] : '',
  4993. 'img' => !empty($img['img']) ? str_replace('https://' . config('app.ali_oss_bindurl') . '/', '', $img['img']) : ''
  4994. ];
  4995. }
  4996. $house_data['ext_down_status'] = 1;
  4997. $ext[$key]['value'] = json_encode($file_media_id);
  4998. } else {
  4999. //清除type类型
  5000. unset($ext[$key]['type']);
  5001. }
  5002. }
  5003. $c_logic = new CustomerLogic();
  5004. if (!empty($cda['ext']) && $cda['ext'] != 'null') {
  5005. $extdata = json_decode($cda['ext'], true);
  5006. if (isset($extdata['ext1'])) {
  5007. $new_ext = CustomerPortraitField::where([['root_id', '=', $token['root_org']], ['pid', '<>', 0]])->select()->toArray();
  5008. $c_logic->check_old_updatefield($cda, $ext, $new_ext, $token);
  5009. $ext = $c_logic->old_ext_edit($cda, $ext, $new_ext);
  5010. } else {
  5011. $c_logic->check_new_updatefield($cda, $ext, $token);
  5012. $ext = $c_logic->new_ext_edit($cda, $ext);
  5013. }
  5014. }
  5015. if (empty($cda['ext'])) $c_logic->check_not_updatefield($cda, $ext, $token);
  5016. $house_data['ext'] = json_encode($ext);
  5017. $ms = $cda->save($house_data);
  5018. // 微爆加微监听
  5019. $new_info = Customer::find($id);
  5020. if ($new_info['add_wechat_time'] && empty($cda['add_wechat_time'])) {
  5021. $i_data['add_wechat_time'] = $new_info['add_wechat_time'];
  5022. $i_data['customer_id'] = $id;
  5023. $i_data['employee_id'] = $new_info['employee_id'];
  5024. $i_data['type'] = 1;
  5025. $i_data['org_id'] = $new_info['org_id'];
  5026. WechatActivityIntegral::addIntegral($i_data, $token['root_org']);
  5027. }
  5028. Console::call('download', ['crm_ext_field']);
  5029. Console::call('download', ['save_portrait_field']);
  5030. if ($ms) {
  5031. return json(['code' => 0, 'msg' => '设置成功']);
  5032. } else {
  5033. return json(['code' => 1, 'msg' => '设置失败']);
  5034. }
  5035. }
  5036. /**
  5037. * 客户迁移
  5038. */
  5039. public function customerTransfer()
  5040. {
  5041. $param = $this->request->only(['customer_ids' => '', 'employee_id']);
  5042. $root_id = request()->token['root_org'];
  5043. $subOrg = orgSubIds($root_id);
  5044. $arr = explode(',', $param['customer_ids']);
  5045. $customers = Customer::where([['id', 'in', $arr], ['org_id', 'in', $subOrg]])->column('id,name,phone,phone1,phone2,employee_id');
  5046. $employee = Employee::find($param['employee_id']);
  5047. if (empty($customers) || empty($employee) || !in_array($employee['org_id'], $subOrg)) {
  5048. return json(['code' => 0, 'msg' => '迁移完成']);
  5049. }
  5050. // 要转移的客户电话合集 这个电话属于谁
  5051. $transfer_phones = [];
  5052. $phone_employee = [];
  5053. foreach ($customers as $k => $v) {
  5054. $v_phone = array_filter([$v['phone'], $v['phone1'], $v['phone2']]);
  5055. $transfer_phones = array_merge($transfer_phones, $v_phone);
  5056. if (empty($phone_employee[$v['employee_id']])) {
  5057. $phone_employee[$v['employee_id']] = $v_phone;
  5058. } else {
  5059. $phone_employee[$v['employee_id']] = array_merge($phone_employee[$v['employee_id']], $v_phone);
  5060. }
  5061. }
  5062. $all_ids = array_column($customers, 'id');
  5063. // 先判断撞单
  5064. // 同部门能否重复录入开关设置
  5065. $empcrm_repeat[] = ['root_id', '=', $root_id];
  5066. $empcrm_repeat[] = ['name', '=', 'empcrm_customer_repeat'];
  5067. $repeat_setting = Setting::where($empcrm_repeat)->findOrEmpty();
  5068. // 默认本部门不能撞单
  5069. if (!$repeat_setting->isEmpty()) {
  5070. $repeat_org = explode(',', $repeat_setting['content']);
  5071. if (!in_array($employee['org_id'], $repeat_org)) {
  5072. $repeat_org = [$employee['org_id']];
  5073. }
  5074. } else {
  5075. $repeat_org = [$employee['org_id']];
  5076. }
  5077. $ex_where[] = ['phone', 'in', $transfer_phones];
  5078. $ex_where[] = ['org_id', 'in', $repeat_org];
  5079. $ex_where[] = ['employee_id', '>', 0];
  5080. $ex_where[] = ['id', 'not in', $all_ids];
  5081. $customerExist = Customer::where($ex_where)->where(
  5082. function ($query) {
  5083. $not_sure = Customer::changeState('待确认', 'chaos');
  5084. $or1[] = ['crm_res_id', 'null', null];
  5085. $or2[] = ['crm_res_id', '>', 0];
  5086. $or2[] = ['state', 'not in', $not_sure];
  5087. $query->whereOr([$or1, $or2]);
  5088. }
  5089. )->column('id,name,phone,employee_id');
  5090. $repeat_ids = $repeat = $no_repeat = [];
  5091. if (!empty($customerExist)) {
  5092. foreach ($customerExist as $ex) {
  5093. $repeat[] = $ex['name'];
  5094. $repeat_ids[] = $ex['id'];
  5095. }
  5096. }
  5097. $no_repeat = array_diff($all_ids, $repeat_ids);
  5098. if ($no_repeat) {
  5099. $org_id = Employee::where('id', $param['employee_id'])->value('org_id');
  5100. Customer::where([['id', 'in', $no_repeat]])->update(['employee_id' => $param['employee_id'], 'org_id' => $org_id]);
  5101. //记录操作人信息PC端需要用到
  5102. Customer::where([['id', 'in', $no_repeat]])->update(['transfer_info' => json_encode(['transfer_empid' => request()->token['employee_id'], 'transfer_time' => date('Y-m-d H:i:s'), 'transfer_empname' => request()->token['name']])]);
  5103. //修改转移的客户的跟进记录的customer_employee_id为新员工的id
  5104. CustomerVisitLog::where([['customer_id', 'in', $no_repeat], ['org_id', 'in', $subOrg]])->update(['customer_employee_id' => $param['employee_id'], 'customer_org_id' => $org_id]);
  5105. }
  5106. if ($repeat) return json(['code' => 1, 'msg' => '迁移失败:[' . implode(',', $repeat) . ']撞单或员工名下已存在客户']);
  5107. return json(['code' => 0, 'msg' => '迁移完成']);
  5108. }
  5109. /**
  5110. * 客户自定义模块显示控制
  5111. */
  5112. public function moduleSwitch()
  5113. {
  5114. $root_id = $this->request->token['root_org'];
  5115. // 客户信息完善开关
  5116. $perfect_find = Setting::where([['root_id', '=', $root_id], ['name', '=', 'modulePerfectSwitch']])->findOrEmpty();
  5117. if ($perfect_find->isEmpty()) {
  5118. $perfect = 1;
  5119. } else {
  5120. $perfect = $perfect_find['content'];
  5121. }
  5122. $data['perfect'] = $perfect;
  5123. // 客户转化开关
  5124. $change_find = Setting::where([['root_id', '=', $root_id], ['name', '=', 'moduleChangeSwitch']])->findOrEmpty();
  5125. if ($change_find->isEmpty()) {
  5126. $change = 1;
  5127. } else {
  5128. $change = $change_find['content'];
  5129. }
  5130. $data['change'] = $change;
  5131. // 客户预约开关
  5132. $subscribe_find = Setting::where([['root_id', '=', $root_id], ['name', '=', 'moduleSubscribeSwitch']])->findOrEmpty();
  5133. if ($subscribe_find->isEmpty()) {
  5134. $subscribe = 1;
  5135. } else {
  5136. $subscribe = $subscribe_find['content'];
  5137. }
  5138. $data['subscribe'] = $subscribe;
  5139. return json(['code' => 0, 'data' => $data]);
  5140. }
  5141. /**
  5142. * 客户跟踪快速标签
  5143. */
  5144. public function clueTag()
  5145. {
  5146. $where[] = ['name', '=', 'clueTag'];
  5147. $where[] = ['root_id', '=', $this->request->token['root_org']];
  5148. $find = Setting::where($where)->findOrEmpty();
  5149. if ($find->isEmpty()) {
  5150. $list = ['已装修', '无需求', '有需求', '超地域', '未交房', '在外地', '无购买力', '未接通电话'];
  5151. } else {
  5152. $list = array_filter(explode(',', $find['content']));
  5153. }
  5154. return json(['code' => 0, 'data' => $list]);
  5155. }
  5156. /**
  5157. * 客户跟踪字段
  5158. */
  5159. public function visitField()
  5160. {
  5161. $id = input('id', '', 'intval');
  5162. $token = $this->request->token;
  5163. $v_where[] = ['root_id', '=', $token['root_org']];
  5164. $v_where[] = ['name', '=', 'visitSettingField'];
  5165. $visitField = Setting::where($v_where)->findOrEmpty();
  5166. $field = [];
  5167. if (!$visitField->isEmpty()) {
  5168. $v_field = !empty($visitField['content']) ? json_decode($visitField['content'], true) : [];
  5169. $ids = !empty($v_field) ? array_column($v_field, 'id') : [];
  5170. $v_list = CustomerPortraitField::with(['select'])->where('id', 'in', $ids)->select()->toArray();
  5171. foreach ($v_field as $k => $v) {
  5172. foreach ($v_list as $kk => $vv) {
  5173. if ($v['id'] == $vv['id']) {
  5174. $field[] = $vv;
  5175. }
  5176. }
  5177. }
  5178. } else {
  5179. $field = CustomerPortraitField::with(['select'])->where([['root_id', '=', $token['root_org']], ['keyname', 'in', ['wechat', 'add_wechat_type', 'add_wechat_time', 'level', 'intention', 'plan_deco_time', 'group_building']]])->order('sort asc')->select()->toArray();
  5180. }
  5181. $city = Company::where('root_id', $token['root_org'])->value('city');
  5182. foreach ($field as $k => $v) {
  5183. if ($v['keyname'] == 'current_region') {
  5184. $field[$k]['select'][] = ['id' => $token['root_org'], 'name' => $city, 'pid' => $v['pid']];
  5185. }
  5186. if ($v['keyname'] == 'source_id') {
  5187. $soudata = CustomerSource::field('id,source as name')->where('root_id', $token['root_org'])->select()->toArray();
  5188. $field[$k]['select'] = $soudata;
  5189. }
  5190. if ($v['keyname'] == 'deco_style') {
  5191. $decostyles = Decostyle::field('id,name')->where([['root_id', '=', $token['root_org']], ['type', '=', 0]])->select()->toArray();
  5192. $field[$k]['select'] = $decostyles;
  5193. }
  5194. }
  5195. if (!empty($id)) {
  5196. $c_logic = new CustomerLogic();
  5197. $cusdata = Customer::where([['id', '=', $id]])->find()->toArray();
  5198. if (!empty($cusdata['ext']) && $cusdata['ext'] != 'null') {
  5199. // $extdata=get_object_vars($cusdata['ext']);
  5200. $extdata = json_decode($cusdata['ext'], true);
  5201. if (isset($extdata['ext1'])) {
  5202. $field = $c_logic->old_data_saves($cusdata, $field);
  5203. } else {
  5204. $field = $c_logic->new_data_saves($cusdata, $extdata, $field);
  5205. }
  5206. } else {
  5207. $field = $c_logic->no_ext_saves($cusdata, $field);
  5208. }
  5209. }
  5210. return json(['code' => 0, 'data' => $field]);
  5211. }
  5212. /**
  5213. * 客户转化自定义设置
  5214. */
  5215. public function changeModule()
  5216. {
  5217. $id = input('id', '', 'intval');
  5218. $root_id = $this->request->token['root_org'];
  5219. // 子模块开关 量房、到店、活动、签单、转单、卖卡
  5220. $switch_where[] = ['name', 'in', ['changeSettingSwitchLF', 'changeSettingSwitchDD', 'changeSettingSwitchHD', 'changeSettingSwitchJD', 'changeSettingSwitchZD', 'changeSettingSwitchMK', 'changeSettingSwitchDDHD']];
  5221. $switch_where[] = ['root_id', '=', $root_id];
  5222. $z_setting = Setting::where($switch_where)->select()->toArray();
  5223. $lf_switch = 1; //量房
  5224. $dd_switch = 1; //到店
  5225. $hd_switch = 1; //活动
  5226. $jd_switch = 1; //签单 (交定)
  5227. $zd_switch = 1; //转单
  5228. $mk_switch = 1; //卖卡
  5229. $ddhd_switch = 1; //到店活动
  5230. foreach ($z_setting as $k => $v) {
  5231. if ($v['name'] == 'changeSettingSwitchLF') $lf_switch = $v['content'];
  5232. if ($v['name'] == 'changeSettingSwitchDD') $dd_switch = $v['content'];
  5233. if ($v['name'] == 'changeSettingSwitchHD') $hd_switch = $v['content'];
  5234. if ($v['name'] == 'changeSettingSwitchJD') $jd_switch = $v['content'];
  5235. if ($v['name'] == 'changeSettingSwitchZD') $zd_switch = $v['content'];
  5236. if ($v['name'] == 'changeSettingSwitchMK') $mk_switch = $v['content'];
  5237. if ($v['name'] == 'changeSettingSwitchDDHD') $ddhd_switch = $v['content'];
  5238. }
  5239. $data['lf']['show'] = $lf_switch;
  5240. $data['dd']['show'] = $dd_switch;
  5241. $data['hd']['show'] = $hd_switch;
  5242. $data['jd']['show'] = $jd_switch;
  5243. $data['zd']['show'] = $zd_switch;
  5244. $data['mk']['show'] = $mk_switch;
  5245. $data['ddhd']['show'] = $ddhd_switch;
  5246. $city = Company::where('root_id', $root_id)->value('city');
  5247. if (!empty($id)) {
  5248. $cusdata = Customer::where([['id', '=', $id]])->find()->toArray();
  5249. }
  5250. $array = ['LF', 'DD', 'HD', 'JD', 'ZD', 'MK'];
  5251. foreach ($array as $k => $v) {
  5252. $lower = strtolower($v);
  5253. unset($c_where);
  5254. $c_where[] = ['root_id', '=', $root_id];
  5255. $c_where[] = ['name', '=', 'changeSettingField' . $v];
  5256. $changeField = Setting::where($c_where)->findOrEmpty();
  5257. $new_list = [];
  5258. if (!$changeField->isEmpty()) {
  5259. $changeField_decode = !empty($changeField['content']) ? json_decode($changeField['content'], true) : [];
  5260. $ids_one = array_column($changeField_decode, 'id');
  5261. $ids_list = CustomerPortraitField::with('select')->where('id', 'in', $ids_one)->select()->toArray();
  5262. foreach ($changeField_decode as $kk => $vv) {
  5263. foreach ($ids_list as $vvv) {
  5264. if ($vv['id'] == $vvv['id']) {
  5265. $new_list[] = $vvv;
  5266. }
  5267. }
  5268. }
  5269. } elseif ($v == 'JD') {
  5270. $new_list = CustomerPortraitField::with('select')->where([['root_id', '=', $root_id], ['keyname', 'in', ['drawing_date', 'plan_issuing_date', 'plan_passing_date', 'material_selection_date', 'will_transfer_to_construction_date']]])->order('sort asc')->select()->toArray();
  5271. }
  5272. foreach ($new_list as $kk => $vv) {
  5273. if ($vv['keyname'] == 'current_region') {
  5274. $new_list[$kk]['select'][] = ['id' => $root_id, 'name' => $city, 'pid' => $vv['pid']];
  5275. }
  5276. if ($vv['keyname'] == 'source_id') {
  5277. $soudata = CustomerSource::field('id,source as name')->where('root_id', $root_id)->select()->toArray();
  5278. $new_list[$kk]['select'] = $soudata;
  5279. }
  5280. if ($vv['keyname'] == 'deco_style') {
  5281. $decostyles = Decostyle::field('id,name')->where([['root_id', '=', $root_id], ['type', '=', 0]])->select()->toArray();
  5282. $new_list[$kk]['select'] = $decostyles;
  5283. }
  5284. }
  5285. $c_logic = new CustomerLogic();
  5286. if (!empty($id)) {
  5287. if (!empty($cusdata['ext']) && $cusdata['ext'] != 'null') {
  5288. // $extdata=get_object_vars($cusdata['ext']);
  5289. $extdata = json_decode($cusdata['ext'], true);
  5290. if (isset($extdata['ext1'])) {
  5291. $new_list = $c_logic->old_data_saves($cusdata, $new_list);
  5292. } else {
  5293. $new_list = $c_logic->new_data_saves($cusdata, $extdata, $new_list);
  5294. }
  5295. } else {
  5296. $new_list = $c_logic->no_ext_saves($cusdata, $new_list);
  5297. }
  5298. }
  5299. $data[$lower]['field'] = $new_list;
  5300. }
  5301. return json(['code' => 0, 'data' => $data]);
  5302. }
  5303. /**
  5304. * 客户预约自定义设置
  5305. */
  5306. public function subscribeModule()
  5307. {
  5308. $id = input('id', '', 'intval');
  5309. $root_id = $this->request->token['root_org'];
  5310. // 子模块开关 活动、到店、量房
  5311. $switch_where[] = ['name', 'in', ['subscribeSettingSwitchYYLF', 'subscribeSettingSwitchYYDD', 'subscribeSettingSwitchYYHD']];
  5312. $switch_where[] = ['root_id', '=', $root_id];
  5313. $z_setting = Setting::where($switch_where)->select()->toArray();
  5314. $hd_switch = 1; //活动
  5315. $dd_switch = 1; //到店
  5316. $lf_switch = 1; //量房
  5317. foreach ($z_setting as $k => $v) {
  5318. if ($v['name'] == 'subscribeSettingSwitchYYLF') $lf_switch = $v['content'];
  5319. if ($v['name'] == 'subscribeSettingSwitchYYDD') $dd_switch = $v['content'];
  5320. if ($v['name'] == 'subscribeSettingSwitchYYHD') $hd_switch = $v['content'];
  5321. }
  5322. $data['lf']['show'] = $lf_switch;
  5323. $data['dd']['show'] = $dd_switch;
  5324. $data['hd']['show'] = $hd_switch;
  5325. $city = Company::where('root_id', $root_id)->value('city');
  5326. if (!empty($id)) {
  5327. $cusdata = Customer::where([['id', '=', $id]])->find()->toArray();
  5328. }
  5329. $array = ['YYHD', 'YYDD', 'YYLF'];
  5330. foreach ($array as $k => $v) {
  5331. $lower = strtolower($v);
  5332. unset($sub_where);
  5333. $sub_where[] = ['root_id', '=', $root_id];
  5334. $sub_where[] = ['name', '=', 'subscribeSettingField' . $v];
  5335. $subscribeField = Setting::where($sub_where)->findOrEmpty();
  5336. $new_list = [];
  5337. if (!$subscribeField->isEmpty()) {
  5338. $subscribeField_decode = !empty($subscribeField['content']) ? json_decode($subscribeField['content'], true) : [];
  5339. $ids_one = array_column($subscribeField_decode, 'id');
  5340. $ids_list = CustomerPortraitField::with('select')->where('id', 'in', $ids_one)->select()->toArray();
  5341. foreach ($subscribeField_decode as $kk => $vv) {
  5342. foreach ($ids_list as $vvv) {
  5343. if ($vv['id'] == $vvv['id']) {
  5344. $new_list[] = $vvv;
  5345. }
  5346. }
  5347. }
  5348. }
  5349. foreach ($new_list as $kk => $vv) {
  5350. if ($vv['keyname'] == 'current_region') {
  5351. $new_list[$kk]['select'][] = ['id' => $root_id, 'name' => $city, 'pid' => $vv['pid']];
  5352. }
  5353. if ($vv['keyname'] == 'source_id') {
  5354. $soudata = CustomerSource::field('id,source as name')->where('root_id', $root_id)->select()->toArray();
  5355. $new_list[$kk]['select'] = $soudata;
  5356. }
  5357. if ($vv['keyname'] == 'deco_style') {
  5358. $decostyles = Decostyle::field('id,name')->where([['root_id', '=', $root_id], ['type', '=', 0]])->select()->toArray();
  5359. $new_list[$kk]['select'] = $decostyles;
  5360. }
  5361. }
  5362. if (!empty($id)) {
  5363. $c_logic = new CustomerLogic();
  5364. if (!empty($cusdata['ext']) && $cusdata['ext'] != 'null') {
  5365. $extdata = json_decode($cusdata['ext'], true);
  5366. if (isset($extdata['ext1'])) {
  5367. $new_list = $c_logic->old_data_saves($cusdata, $new_list);
  5368. } else {
  5369. $new_list = $c_logic->new_data_saves($cusdata, $extdata, $new_list);
  5370. }
  5371. } else {
  5372. $new_list = $c_logic->no_ext_saves($cusdata, $new_list);
  5373. }
  5374. }
  5375. $data[$lower]['field'] = $new_list;
  5376. }
  5377. return json(['code' => 0, 'data' => $data]);
  5378. }
  5379. /**
  5380. * 店面列表
  5381. */
  5382. public function shop_list()
  5383. {
  5384. $shop_list = Shop::where('root_id', '=', $this->request->token['root_org'])->select()->toArray();
  5385. return json(['code' => 0, 'data' => $shop_list]);
  5386. }
  5387. /**
  5388. * 申请死单
  5389. */
  5390. public function dieCustomer()
  5391. {
  5392. $customer_id = input('customer_id', '', 'intval');
  5393. $reason = input('reason', '', 'trim');
  5394. $find = Customer::where('id', '=', $customer_id)->findOrEmpty();
  5395. if ($find->isEmpty() || $find['employee_id'] != request()->token['employee_id']) {
  5396. return json(['code' => 1, 'msg' => '操作失败']);
  5397. }
  5398. $data['died'] = 1;
  5399. $data['died_reason'] = $reason;
  5400. $data['died_date'] = date('Y-m-d H:i:s', time());
  5401. $result = $find->save($data);
  5402. if ($result !== false) {
  5403. return json(['code' => 0, 'msg' => '操作成功']);
  5404. } else {
  5405. return json(['code' => 1, 'msg' => '操作失败']);
  5406. }
  5407. }
  5408. /**
  5409. * 操作设置
  5410. */
  5411. public function moduleHandel()
  5412. {
  5413. $root_id = request()->token['root_org'];
  5414. $setting = Setting::where([['root_id', '=', $root_id], ['name', '=', 'customerHandel']])->findOrEmpty();
  5415. if (!$setting->isEmpty()) {
  5416. $content = json_decode($setting['content'], true);
  5417. } else {
  5418. $content = [
  5419. 'wechat' => 1,
  5420. 'group_building' => 1,
  5421. 'live_broadcast' => 1
  5422. ];
  5423. }
  5424. return json(['code' => 0, 'data' => $content]);
  5425. }
  5426. /**
  5427. * 智慧屏 讲解链接
  5428. */
  5429. public function produceUrl()
  5430. {
  5431. $token = $this->request->token;
  5432. $param = request()->only(['customer_id' => 0]);
  5433. $str = $token['root_org'] . '#' . $token['employee_id'] . '#' . $param['customer_id'];
  5434. $aec = new Aec(config('app.aec_key'), config('app.aec_iv'));
  5435. $value = $aec->encrypt($str);
  5436. // $ali_oss_bindurl = config('app.ali_oss_bindurl');
  5437. // $url = 'https://' . $ali_oss_bindurl . '/' . 'dashboard/wisdom?token='.$value;
  5438. return json(['code' => 0, 'data' => $value]);
  5439. }
  5440. /**
  5441. * 获取小区
  5442. */
  5443. public function getCommunity()
  5444. {
  5445. $token = $this->request->token;
  5446. $name = input('name', '', 'trim');
  5447. if ($name) {
  5448. $where[] = ['name', 'like', '%' . $name . '%'];
  5449. }
  5450. $where[] = ['root_id', '=', $token['root_org']];
  5451. $list = Community::where($where)->order('addtime desc')->select()->toArray();
  5452. // 交房时间新增到了小区信息中,下方代码注释不再使用 2023-03-06
  5453. /* foreach ($list as $k => $v) {
  5454. $building = Building::where('community_id', '=', $v['id'])->order('addtime desc')->findOrEmpty();
  5455. if ($building->isEmpty()) {
  5456. $list[$k]['duetime'] = '';
  5457. } else {
  5458. $list[$k]['duetime'] = $building['duetime'];
  5459. }
  5460. } */
  5461. return json(['code' => 0, 'data' => $list, 'msg' => '获取成功']);
  5462. }
  5463. /**
  5464. * 小程序资源库分配 已分配客户列表
  5465. */
  5466. public function assignedCustomer()
  5467. {
  5468. $param = Request::only(['employee_id' => 0, 'crm_res_id' => 0, 'org_id' => 0, 'page' => 1, 'limit' => 10]);
  5469. $token = $this->request->token;
  5470. $root_id = $token['root_org'];
  5471. $subOrg = orgSubIds($root_id);
  5472. $p_where[] = ['org_id', 'in', $subOrg];
  5473. $p_where[] = ['pid|id', '=', $param['crm_res_id']];
  5474. $pid = CrmImportLog::where($p_where)->column('id');
  5475. $where[] = ['crm_res_id', 'in', $pid];
  5476. if ($param['employee_id']) {
  5477. $where[] = ['employee_id', '=', $param['employee_id']];
  5478. } elseif ($param['org_id']) {
  5479. $where[] = ['org_id', '=', $param['org_id']];
  5480. $where[] = ['is_resource', '=', 1];
  5481. $where[] = ['employee_id', 'NULL', null];
  5482. } else {
  5483. return json(['code' => 0, 'data' => [], 'count' => 0, 'msg' => '获取成功']);
  5484. }
  5485. $list = Customer::where($where)->page($param['page'], $param['limit'])->field('name,phone')->select()->toArray();
  5486. $count = Customer::where($where)->count();
  5487. foreach ($list as $k => $v) {
  5488. $list[$k]['phone'] = substr_replace($v['phone'], '******', 3, 6);
  5489. }
  5490. return json(['code' => 0, 'data' => $list, 'count' => $count, 'msg' => '获取成功']);
  5491. }
  5492. /**
  5493. * 客户智慧屏保存实景图,效果图
  5494. * [{img: "", serverId: ""},{img: "", serverId: ""}]
  5495. */
  5496. public function saveWisdomImg()
  5497. {
  5498. $arr = input('content', []);
  5499. $customer_id = input('customer_id', 0);
  5500. $cate = input('type', 0);
  5501. if (empty($arr) || !is_array($arr) || count($arr) == count($arr, 1) || !$customer_id) return json(['code' => 1, 'data' => '参数错误', 'msg' => '参数错误']);
  5502. $img = array_filter(array_column($arr, 'img'));
  5503. $media_id = array_filter(array_column($arr, 'serverId'));
  5504. if ($img) {
  5505. $type = 'img';
  5506. $arr = $img;
  5507. } elseif ($media_id) {
  5508. $type = 'media_id';
  5509. $arr = $media_id;
  5510. } else {
  5511. return json(['code' => 1, 'data' => '参数错误', 'msg' => '参数错误']);
  5512. }
  5513. $token = $this->request->token;
  5514. // $token['root_org'] = 23;
  5515. $save = [];
  5516. foreach ($arr as $k => $v) {
  5517. $save[] = [
  5518. 'root_id' => $token['root_org'],
  5519. 'customer_id' => $customer_id,
  5520. $type => $v,
  5521. 'type' => $cate
  5522. ];
  5523. }
  5524. CustomerWisdomImg::insertAll($save);
  5525. if ($media_id) Console::call('download', ['wisdom']);
  5526. //保存客户跟进记录0实景图,1效果图
  5527. $str = $cate ? '智慧屏效果图上传' : '智慧屏实景图上传';
  5528. $field = $img ? 'img' : 'media_id';
  5529. if ($img) {
  5530. $imgs = implode(',', $img);
  5531. } else {
  5532. $imgs = CustomerWisdomImg::where([['media_id', 'in', $arr]])->column('img');
  5533. $imgs = implode(',', $imgs);
  5534. }
  5535. $remark = $str . '##' . $imgs;
  5536. $save = [
  5537. 'customer_id' => $customer_id,
  5538. 'type' => '',
  5539. 'next_contact_date' => date('Y-m-d'),
  5540. 'remark' => '智慧屏客户图片##' . $remark,
  5541. 'addtime' => date('Y-m-d H:i:s'),
  5542. 'employee_id' => $token['employee_id'],
  5543. 'user_id' => $token['uid'],
  5544. 'state' => '未到访',
  5545. 'org_id' => $token['org_id'],
  5546. 'customer_employee_id' => $token['employee_id'],
  5547. 'customer_org_id' => $token['org_id']
  5548. ];
  5549. CustomerVisitLog::insert($save);
  5550. return json(['code' => 0, 'data' => '保存成功', 'msg' => '保存成功']);
  5551. }
  5552. /**
  5553. * 获取客户智慧屏图片图片
  5554. */
  5555. public function getWisdomImg()
  5556. {
  5557. $param = Request::only(['customer_id' => 0, 'type' => 0]);
  5558. $token = $this->request->token;
  5559. // $token['root_org'] = 23;
  5560. $where = [
  5561. 'customer_id' => $param['customer_id'],
  5562. 'type' => $param['type'],
  5563. 'root_id' => $token['root_org']
  5564. ];
  5565. $list = CustomerWisdomImg::where($where)->field('id,img')->order('id asc')->select()->toArray();
  5566. return json(['code' => 0, 'data' => $list, 'msg' => '获取成功']);
  5567. }
  5568. /**
  5569. * 删除客户智慧屏图片图片
  5570. */
  5571. public function delWisdomImg()
  5572. {
  5573. $param = Request::only(['customer_id' => 0, 'id' => 0]);
  5574. $info = CustomerWisdomImg::where('id', $param['id'])->findOrEmpty();
  5575. if ($info->isEmpty()) return json(['code' => 1, 'data' => '删除失败', 'msg' => '删除失败']);
  5576. $token = $this->request->token;
  5577. // $token['root_org'] = 23;
  5578. $where = [
  5579. 'customer_id' => $param['customer_id'],
  5580. 'id' => $param['id'],
  5581. 'root_id' => $token['root_org']
  5582. ];
  5583. $list = CustomerWisdomImg::where($where)->delete();
  5584. $str = $info->type ? '智慧屏效果图删除' : '智慧屏实景图删除';
  5585. //智慧屏删除
  5586. $remark = $str . '##' . $info->getData('img');
  5587. $save = [
  5588. 'customer_id' => $param['customer_id'],
  5589. 'type' => '',
  5590. 'next_contact_date' => date('Y-m-d'),
  5591. 'remark' => '智慧屏客户图片##' . $remark,
  5592. 'addtime' => date('Y-m-d H:i:s'),
  5593. 'employee_id' => $token['employee_id'],
  5594. 'user_id' => $token['uid'],
  5595. 'state' => '未到访',
  5596. 'org_id' => $token['org_id'],
  5597. 'customer_employee_id' => $token['employee_id'],
  5598. 'customer_org_id' => $token['org_id']
  5599. ];
  5600. CustomerVisitLog::insert($save);
  5601. return json(['code' => 0, 'data' => '删除成功', 'msg' => '删除成功']);
  5602. }
  5603. /**
  5604. * 是否有外呼系统
  5605. */
  5606. public function haveOutCall()
  5607. {
  5608. $info = OutCallSetting::where('root_id', '=', request()->token['root_org'])->findOrEmpty();
  5609. $have = false;
  5610. if (!$info->isEmpty()) {
  5611. if (!isset($info->config['open']) || $info->config['open'] == 1)
  5612. $have = true;
  5613. }
  5614. return json(['code' => 0, 'data' => $have, 'msg' => 'success']);
  5615. }
  5616. /**
  5617. * 获取指派类型
  5618. */
  5619. public function getAssignType()
  5620. {
  5621. $setting = Setting::where([['root_id', '=', request()->token['root_org']], ['name', '=', 'assign_type']])->findOrEmpty();
  5622. $default['yixiang'] = '意向客户指派';
  5623. $default['liangfang'] = '量房客户指派';
  5624. $default['daodian'] = '到店客户指派';
  5625. $data = [];
  5626. if (!$setting->isEmpty()) {
  5627. $content = json_decode($setting['content'], true);
  5628. if (!empty($content)) {
  5629. foreach ($content as $k => $v) {
  5630. if (isset($default[$v])) {
  5631. $data[$v] = $default[$v];
  5632. }
  5633. }
  5634. }
  5635. }
  5636. return json(['code' => 0, 'data' => $data, 'msg' => 'success']);
  5637. }
  5638. /**
  5639. * 智慧屏绑定客户
  5640. */
  5641. public function bindCustomers()
  5642. {
  5643. $token = $this->request->token;
  5644. $param = Request::only(['customer_id' => 0, 'employee_id' => 0, 'token' => '']);
  5645. if (strpos($param['token'], '@' . $token['root_org'] . '@') === false) return json(['code' => 1, 'data' => '绑定失败', 'msg' => '绑定失败']);
  5646. $org = Org::where([['path', 'like', $token['root_org'] . '-%']])->column('id');
  5647. $where = [
  5648. // ['employee_id|designer_id','=',$param['employee_id']],
  5649. ['id', '=', $param['customer_id']],
  5650. ['org_id', 'in', $org]
  5651. ];
  5652. $find = Customer::where($where)->value('id');
  5653. if (!$find) return json(['code' => 1, 'data' => '绑定失败', 'msg' => '绑定失败']);
  5654. $str = $token['root_org'] . '#' . $param['employee_id'] . '#' . $param['customer_id'];
  5655. $aec = new Aec(config('app.aec_key'), config('app.aec_iv'));
  5656. $str = $aec->encrypt($str);
  5657. Cache::set($param['token'], $str, 60);
  5658. return json(['code' => 0, 'data' => '绑定成功', 'msg' => '获取成功']);
  5659. }
  5660. /**
  5661. * 龙虎榜
  5662. */
  5663. public function topStatistics()
  5664. {
  5665. $root_id = request()->token['root_org'];
  5666. $orgList = orgSubIds($root_id);
  5667. $param = request()->param(['start_date' => '2021-01-01', 'end_date' => date('Y-m-d')]);
  5668. $type = input('type', '', 'trim');
  5669. !empty($param['start_date']) ?: $param['start_date'] = '2021-01-01';
  5670. !empty($param['end_date']) ?: $param['end_date'] = date('Y-m-d');
  5671. $start_date = date('Y-m-d 00:00:00', strtotime($param['start_date']));
  5672. $end_date = date('Y-m-d 00:00:00', strtotime($param['end_date']) + 86400);
  5673. switch ($type) {
  5674. case 'jiav':
  5675. $where[] = ['org_id', 'in', $orgList];
  5676. $where[] = ['add_wechat_time', '>=', $start_date];
  5677. $where[] = ['add_wechat_time', '<', $end_date];
  5678. $where[] = ['employee_id', 'NOTNULL', ''];
  5679. $e = Customer::where($where)->field('employee_id, count(id) as num')->group('employee_id')->order('num desc')->select();
  5680. break;
  5681. case 'daodian':
  5682. $cvl = CustomerVisitLog::withJoin('customer')->where([['customer.org_id', 'in', $orgList], ['customer_visit_log.state', 'in', CustomerVisitLog::changeState('已到店', 'chaos')], ['customer_visit_log.addtime', '>=', $start_date], ['customer_visit_log.addtime', '<', $end_date], ['customer.employee_id', 'NOTNULL', '']])->group('customer_visit_log.customer_id')->column('customer.employee_id');
  5683. $cvl = array_count_values($cvl);
  5684. $e = [];
  5685. foreach ($cvl as $employee_id => $num) {
  5686. $e[] = [
  5687. 'employee_id' => $employee_id,
  5688. 'num' => $num
  5689. ];
  5690. }
  5691. array_multisort(array_column($e, 'num'), SORT_DESC, $e);
  5692. break;
  5693. case 'qiandan':
  5694. $cvl = CustomerVisitLog::withJoin('customer')->where([['customer.org_id', 'in', $orgList], ['customer_visit_log.state', 'in', CustomerVisitLog::changeState('签单', 'chaos')], ['customer_visit_log.addtime', '>=', $start_date], ['customer_visit_log.addtime', '<', $end_date], ['customer.employee_id', 'NOTNULL', '']])->group('customer_visit_log.customer_id')->column('sum(customer.signed_money) as money, customer.employee_id');
  5695. $dcvl = [];
  5696. foreach ($cvl as $i) {
  5697. if (!isset($dcvl[$i['employee_id']]))
  5698. $dcvl[$i['employee_id']] = 0;
  5699. $dcvl[$i['employee_id']] += $i['money'];
  5700. }
  5701. $e = [];
  5702. foreach ($dcvl as $employee_id => $money) {
  5703. $e[] = [
  5704. 'employee_id' => $employee_id,
  5705. 'num' => $money > 10000 ? round($money / 10000, 2) . '万元' : $money . '元',
  5706. 'money' => $money
  5707. ];
  5708. }
  5709. array_multisort(array_column($e, 'money'), SORT_DESC, $e);
  5710. break;
  5711. case 'sj_qiandan':
  5712. $cvl = CustomerVisitLog::withJoin('customer')->where([['customer.org_id', 'in', $orgList], ['customer_visit_log.state', 'in', CustomerVisitLog::changeState('签单', 'chaos')], ['customer_visit_log.addtime', '>=', $start_date], ['customer_visit_log.addtime', '<', $end_date], ['customer.designer_id', 'NOTNULL', '']])->group('customer_visit_log.customer_id')->column('sum(customer.signed_money) as money, customer.designer_id');
  5713. $dcvl = [];
  5714. foreach ($cvl as $i) {
  5715. if (!isset($dcvl[$i['designer_id']]))
  5716. $dcvl[$i['designer_id']] = 0;
  5717. $dcvl[$i['designer_id']] += $i['money'];
  5718. }
  5719. $e = [];
  5720. foreach ($dcvl as $employee_id => $money) {
  5721. $e[] = [
  5722. 'employee_id' => $employee_id,
  5723. 'num' => $money > 10000 ? round($money / 10000, 2) . '万元' : $money . '元',
  5724. 'money' => $money
  5725. ];
  5726. }
  5727. array_multisort(array_column($e, 'money'), SORT_DESC, $e);
  5728. break;
  5729. }
  5730. // 取前三名数据
  5731. $n = 3;
  5732. $i = 0;
  5733. $p = [];
  5734. foreach ($e as $ei) {
  5735. if (empty($p)) {
  5736. $p[] = $ei;
  5737. $i = $ei['num'];
  5738. continue;
  5739. }
  5740. if ($i == $ei['num']) {
  5741. $p[] = $ei;
  5742. continue;
  5743. } else {
  5744. $n--;
  5745. if ($n == 0) break;
  5746. $p[] = $ei;
  5747. $i = $ei['num'];
  5748. }
  5749. }
  5750. $eid = array_column($p, 'employee_id');
  5751. $emp = Employee::with('org')->where([['id', 'in', $eid]])->select()->toArray();
  5752. $emp = array_combine(array_column($emp, 'id'), $emp);
  5753. foreach ($p as &$ie) {
  5754. $ie['employee_name'] = $emp[$ie['employee_id']]['name'];
  5755. $ie['headimgurl'] = $emp[$ie['employee_id']]['headimgurl'];
  5756. $ie['org_name'] = $emp[$ie['employee_id']]['org']['name'];
  5757. }
  5758. return json(['code' => 0, 'data' => $p]);
  5759. }
  5760. }