CrmCustomer.php 298 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310
  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. // 2025
  1071. // 剔除掉未经历该状态的客户id
  1072. // 全部客户搜索当前状态 共有客户搜历史 2023-03-01 小胖
  1073. if (!empty($param['state'])) {
  1074. if ($param['state'] == '待确认') {
  1075. //2022-10-30 小程序客户列表的待确认状态是根据客户表的当前状态来展示的,所以查询待确认状态时 查询客户当前状态
  1076. //增加查询从公海获取的客户是资源库的,当前状态是待确认的
  1077. $daior[] = [['id', 'in', $customersIdList], ['state', 'in', Customer::changeState($param['state'], 'chaos')], ['crm_res_id', 'NULL', NULL]];
  1078. $daior[] = [['id', 'in', $customersIdList], ['state', 'in', Customer::changeState($param['state'], 'chaos')], ['crm_res_id', 'NOTNULL', NULL], ['valid_time', 'NOTNULL', NULL]];
  1079. //$customersIdList = Customer::where([['id', 'in', $customersIdList], ['state', 'in', Customer::changeState($param['state'], 'chaos')], ['crm_res_id', 'NULL', null]])->column('id');
  1080. $customersIdList = Customer::whereOr($daior)->column('id');
  1081. } elseif (CustomerVisitLog::changeState($param['state']) == '回访' || $param['state'] == '有效') {
  1082. //有效状态 未到访,已到访,确定到场,已量房,交定,签单
  1083. // $visit_status = ['未到访', '已到访', '已量房', '已到场', '已到店', '交定', '签单'];
  1084. // $now_status = [];
  1085. // foreach ($visit_status as $v) {
  1086. // $now_status = array_merge(CustomerVisitLog::changeState($v, 'chaos'), $now_status);
  1087. // }
  1088. // $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');
  1089. //客户表里排除了待确认的跟死单跟无效的客户就是有效的
  1090. $customersIdList = Customer::where([['id', 'in', $customersIdList], ['state', 'not in', array_merge(Customer::changeState('待确认', 'chaos'), Customer::changeState('无效', 'chaos'))], ['died', '<>', 2]])->column('id');
  1091. // 查询经历过回访以外所有状态的客户id(有效)
  1092. // $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');
  1093. // if ($param['state'] == '有效') {
  1094. // $customersIdList = $expectCustomersIdList;
  1095. // } else {
  1096. // $customersIdList = array_diff($customersIdList, $expectCustomersIdList);
  1097. // }
  1098. } else {
  1099. $customersIdList = CustomerVisitLog::where([['customer_id', 'in', $customersIdList], ['state', 'in', CustomerVisitLog::changeState($param['state'], 'chaos')]])->group('customer_id')->column('customer_id');
  1100. }
  1101. }
  1102. // 过保护期查询
  1103. $setting = Setting::where([['name', '=', 'pubpool'], ['root_id', '=', $token['root_org']]])->findOrEmpty();
  1104. if (!empty($param['protected'])) {
  1105. if (!$setting->isEmpty()) {
  1106. $content = !empty($setting['content']) ? json_decode($setting['content'], true) : [];
  1107. if (empty($content)) {
  1108. return json(['code' => 0, 'data' => ['list' => [], 'count' => 0, 'ids' => []], 'page' => 1]);
  1109. }
  1110. $empty = false; //判断是否是正常数据,因为之前可能有垃圾数据
  1111. foreach ($content as $k => $v) {
  1112. if (!isset($v['day']) || !isset($v['state'])) {
  1113. $empty = true;
  1114. }
  1115. }
  1116. if ($empty) {
  1117. return json(['code' => 0, 'data' => ['list' => [], 'count' => 0, 'ids' => []], 'page' => 1]);
  1118. }
  1119. $whereOr = [];
  1120. foreach ($content as $k => $v) {
  1121. if ($v['state'] == 1 && $v['day'] > 0) {
  1122. $whereOr[] = [
  1123. ['state', 'in', Customer::changeState($k, 'chaos')],
  1124. ['protected_to', '<', date('Y-m-d H:i:s')],
  1125. ['protected_to', '<>', ' null']
  1126. ];
  1127. }
  1128. }
  1129. if (!empty($whereOr)) {
  1130. $customersIdList = Customer::where([['id', 'in', $customersIdList]])->where(function ($query) use ($whereOr) {
  1131. $query->whereOr($whereOr);
  1132. })->column('id');
  1133. } else {
  1134. return json(['code' => 0, 'data' => ['list' => [], 'count' => 0, 'ids' => []], 'page' => 1]);
  1135. }
  1136. } else {
  1137. return json(['code' => 0, 'data' => ['list' => [], 'count' => 0, 'ids' => []], 'page' => 1]);
  1138. }
  1139. }
  1140. if (empty($param['protected'])) {
  1141. // 置顶数据获取
  1142. $top = CustomerTop::where([['root_id', '=', $token['root_org']], ['employee_id', '=', $token['employee_id']]])->where([['customer_id', 'in', $customersIdList]])->order('addtoptime asc')->column('customer_id');
  1143. // 新数据获取
  1144. $new = Customer::where([['id', 'in', $customersIdList], ['fresh', '=', 1]])->order($order)->column('id');
  1145. // 剔除不应该出现的客户
  1146. $top = array_diff($top, array_diff($top, $customersIdList));
  1147. // // 剔除不应该出现的新客户
  1148. $new = array_diff($new, array_diff($new, $customersIdList));
  1149. // 剔除置顶的客户
  1150. $notTop = array_diff($customersIdList, $top);
  1151. // 剔除新客户
  1152. $notNew = array_diff($notTop, $new);
  1153. // 将置顶客户放置到前面
  1154. $customersIdList = array_unique(array_merge($top, $new, $notNew));
  1155. } else {
  1156. $top = [];
  1157. }
  1158. //返回到特定位置
  1159. $id = input('id', 0);
  1160. if ($id) {
  1161. $ids = array_chunk($customersIdList, $param['limit']);
  1162. foreach ($ids as $k => $v) {
  1163. $a = false;
  1164. foreach ($v as $k2 => $v2) {
  1165. if ($id == $v2) {
  1166. $a = true;
  1167. $param['page'] = $k + 1;
  1168. break;
  1169. }
  1170. }
  1171. if ($a) break;
  1172. }
  1173. }
  1174. // 分页
  1175. $pageIdList = array_slice($customersIdList, ($param['page'] - 1) * $param['limit'], $param['limit']);
  1176. $id_where[] = ['id', 'in', $pageIdList];
  1177. $customers = Customer::with(['designer', 'designerOrg', 'employee', 'agent'])->where($id_where)->select();
  1178. // 总数获取
  1179. $count = count($customersIdList);
  1180. $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();
  1181. if (!empty($param['protected'])) {
  1182. if (!$setting->isEmpty()) {
  1183. $setting_content = !empty($setting['content']) ? json_decode($setting['content'], true) : [];
  1184. } else {
  1185. $setting_content = [];
  1186. }
  1187. foreach ($customers as $k => $v) {
  1188. $customers[$k]['un_protected'] = 0;
  1189. $customers[$k]['protected_tips'] = '';
  1190. if (!empty($v['protected_to']) && time() > strtotime($v['protected_to'])) {
  1191. $state_n = Customer::changeState($v['state'], 'n');
  1192. if (!empty($setting_content[$state_n]['state']) && $setting_content[$state_n]['state'] == 1) {
  1193. $customers[$k]['un_protected'] = 1;
  1194. $customers[$k]['protected_tips'] = '已过期';
  1195. }
  1196. }
  1197. if (!empty($v['protected_to']) && time() < strtotime($v['protected_to'])) {
  1198. $day = floor((strtotime($v['protected_to']) - time()) / (24 * 3600));
  1199. $customers[$k]['protected_tips'] = $day ? '保护期' . $day . '天' : '即将过期';
  1200. }
  1201. }
  1202. } else {
  1203. foreach ($customers as $k => $v) {
  1204. $customers[$k]['un_protected'] = 0;
  1205. $customers[$k]['protected_tips'] = '';
  1206. }
  1207. }
  1208. $customers = array_combine(array_column($customers, 'id'), $customers);
  1209. // 状态统计获取
  1210. $customersStateList = CustomerVisitLog::where([['customer_id', 'in', $pageIdList]])->group('state,customer_id')->field('count(state) as num, state, customer_id')->select()->toArray();
  1211. $customersState = [];
  1212. foreach ($customersStateList as $s) {
  1213. if (!isset($customersState[$s['customer_id']]))
  1214. $customersState[$s['customer_id']] = ['count' => 0, 'shop' => 0, 'measure' => 0, 'activity' => 0, 'deposit' => 0, 'signed' => 0];
  1215. $customersState[$s['customer_id']]['count'] += $s['num'];
  1216. // 到店,量房,活动,定金,签单
  1217. if ($s['state'] == '已到店') $customersState[$s['customer_id']]['shop'] += $s['num'];
  1218. elseif ($s['state'] == '已量房') $customersState[$s['customer_id']]['measure'] += $s['num'];
  1219. elseif ($s['state'] == '已到场') $customersState[$s['customer_id']]['activity'] += $s['num'];
  1220. elseif ($s['state'] == '已交定') $customersState[$s['customer_id']]['deposit'] += $s['num'];
  1221. elseif ($s['state'] == '已签单') $customersState[$s['customer_id']]['signed'] += $s['num'];
  1222. }
  1223. // 最后跟进时间获取
  1224. $lastTime = CustomerVisitLog::where([['customer_id', 'in', $pageIdList]])->group('customer_id')->column('max(addtime)', 'customer_id');
  1225. // 交定时间获取
  1226. $dingTime = CustomerVisitLog::where([['customer_id', 'in', $pageIdList], ['state', 'in', CustomerVisitLog::changeState('已交定', 'chaos')]])->group('customer_id')->column("max(confirm_date)", "customer_id");
  1227. trace(json_encode($dingTime));
  1228. // 排序(按每页id顺序取值)
  1229. $listData = [];
  1230. foreach ($pageIdList as $customerId) {
  1231. $customers[$customerId]['top'] = 0;
  1232. $customers[$customerId]['is_new'] = $customers[$customerId]['fresh'] == 1 ? 1 : 0;
  1233. $customers[$customerId]['addtoptime'] = null;
  1234. if (in_array($customerId, $top)) $customers[$customerId]['addtoptime'] = 1;
  1235. if (isset($customersState[$customerId]) && !in_array($customers[$customerId]['state'], Customer::changeState('待确认', 'chaos'), true)) {
  1236. $customers[$customerId]['stateNum'] = $customersState[$customerId];
  1237. } else {
  1238. $customers[$customerId]['stateNum'] = ['count' => 0, 'shop' => 0, 'measure' => 0, 'activity' => 0, 'deposit' => 0, 'signed' => 0];
  1239. }
  1240. $customers[$customerId]['last_visit_day'] = isset($lastTime[$customerId]) ? get_date_diff(time(), $lastTime[$customerId])->days : -1;
  1241. $customers[$customerId]['last_ding_day'] = isset($dingTime[$customerId]) ? get_date_diff(time(), $dingTime[$customerId])->days : 0;
  1242. $listData[] = $customers[$customerId];
  1243. }
  1244. //重复录入功能,添加手机号 ,自动回收库里分配去重用
  1245. if ($listData) {
  1246. $keys = array_column($listData, 'id');
  1247. $customer = Customer::where([['id', 'in', $keys]])->field('id,phone,phone1,phone2')->select();
  1248. $phones = [];
  1249. foreach ($customer as $v) {
  1250. $phones[$v->id] = $v->toArray();
  1251. }
  1252. foreach ($listData as $k2 => $v2) {
  1253. $listData[$k2] = array_merge($v2, $phones[$v2['id']]);
  1254. }
  1255. //小程序排序待回收和 后台待回收排序保持一致
  1256. if (!empty($param['protected'])) array_multisort(array_column($listData, 'id'), SORT_DESC, $listData);
  1257. }
  1258. $data = [
  1259. 'list' => $listData,
  1260. 'count' => $count,
  1261. 'ids' => Customer::where([['id', 'in', $customersIdList]])->field('id,phone,phone1,phone2')->select()
  1262. ];
  1263. return json(['code' => 0, 'data' => $data, 'page' => $param['page']]);
  1264. }
  1265. /**
  1266. * 设计师待跟进接口
  1267. */
  1268. public function confirmList()
  1269. {
  1270. $param = $this->request->only(['state' => '', 'page' => 1, 'limit' => 20, 'date' => date('Y-m-d')]);
  1271. $type = [
  1272. '到店' => 1,
  1273. '活动' => 2,
  1274. '量房' => 3
  1275. ];
  1276. if (!isset($type[$param['state']])) {
  1277. $search = ['type', 'in', [1, 2, 3]];
  1278. } else {
  1279. $search = ['type', '=', $type[$param['state']]];
  1280. }
  1281. $condition = ['designer_id|employee_id', '=', $this->request->token['employee_id']];
  1282. $date = ['subscribe_date', '=', $param['date']];
  1283. // 排除掉无效的客户
  1284. $customerIdList = CustomersSubscribe::where([$condition, $date, $search, ['state', '=', 0]])->column('customer_id');
  1285. $customerIdList = Customer::where([['id', 'in', $customerIdList], ['state', 'not in', Customer::changeState('无效', 'chaos')]])->column('id');
  1286. $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();
  1287. $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();
  1288. // 保持原接口数据一致
  1289. $customers = [];
  1290. foreach ($data as $c) {
  1291. $customers[] = [
  1292. 'id' => $c['customer_id'],
  1293. 'customer_id' => $c['customer_id'],
  1294. 'employee_id' => $c['employee_id'],
  1295. 'name' => $c['customer']['name'],
  1296. 'sex' => $c['customer']['sex'],
  1297. 'level' => $c['customer']['level'],
  1298. 'community_name' => $c['customer']['community_name'],
  1299. 'state' => $c['customer']['state'],
  1300. 'subscribe_state' => $c['type'],
  1301. 'employee' => ['name' => $c['employee']['name']],
  1302. 'employeeOrg' => ['name' => $c['org']['name']],
  1303. 'activity' => [
  1304. 'title' => empty($c['activity']) ? '' : $c['activity']['title'],
  1305. 'id' => $c['aid']
  1306. ],
  1307. 'last_contact_date' => $c['subscribe_date']
  1308. ];
  1309. }
  1310. // 状态统计获取
  1311. $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();
  1312. $customersState = [];
  1313. foreach ($customersStateList as $s) {
  1314. if (!isset($customersState[$s['customer_id']])) $customersState[$s['customer_id']] = ['count' => 0, 'shop' => 0, 'measure' => 0, 'activity' => 0, 'deposit' => 0, 'signed' => 0];
  1315. $customersState[$s['customer_id']]['count'] += $s['num'];
  1316. // 到店,量房,活动,定金,签单
  1317. if ($s['state'] == '已到店') $customersState[$s['customer_id']]['shop'] += $s['num'];
  1318. elseif ($s['state'] == '已量房') $customersState[$s['customer_id']]['measure'] += $s['num'];
  1319. elseif ($s['state'] == '已到场') $customersState[$s['customer_id']]['activity'] += $s['num'];
  1320. elseif ($s['state'] == '已交定') $customersState[$s['customer_id']]['deposit'] += $s['num'];
  1321. elseif ($s['state'] == '已签单') $customersState[$s['customer_id']]['signed'] += $s['num'];
  1322. }
  1323. foreach ($customers as &$item) {
  1324. $item['stateNum'] = $customersState[$item['customer_id']] ?? ['count' => 0, 'shop' => 0, 'measure' => 0, 'activity' => 0, 'deposit' => 0, 'signed' => 0];
  1325. }
  1326. $data = [
  1327. 'list' => $customers,
  1328. 'count' => CustomersSubscribe::where([$condition, $date, $search, ['state', '=', 0], ['customer_id', 'in', $customerIdList]])->count(),
  1329. 'allCount' => CustomersSubscribe::where([$condition, $date, ['state', '=', 0], ['customer_id', 'in', $customerIdList]])->count(),
  1330. 'visitCount' => CustomersSubscribe::where([$condition, $date, ['state', '=', 0], ['type', '=', $type['到店']], ['customer_id', 'in', $customerIdList]])->count(),
  1331. 'measureCount' => CustomersSubscribe::where([$condition, $date, ['state', '=', 0], ['type', '=', $type['量房']], ['customer_id', 'in', $customerIdList]])->count(),
  1332. 'activityCount' => CustomersSubscribe::where([$condition, $date, ['state', '=', 0], ['type', '=', $type['活动']], ['customer_id', 'in', $customerIdList]])->count()
  1333. ];
  1334. return json(['code' => 0, 'data' => $data]);
  1335. }
  1336. /*
  1337. * 客户列表点击电话图标获取电话
  1338. */
  1339. public function getCrmPhone()
  1340. {
  1341. $id = $this->request->param('id');
  1342. $token = $this->request->token;
  1343. $where = [
  1344. ['id', '=', $id],
  1345. ['state', '<>', '无效'],
  1346. ['employee_id', '=', $token['employee_id']]
  1347. ];
  1348. //指派的客户
  1349. $where_or = [['assigned_personnel', 'find in set', $token['employee_id']], ['id', '=', $id]];
  1350. $where_or1 = [['designer_id', '=', $token['employee_id']], ['id', '=', $id]];
  1351. $had = Customer::whereOr([$where, $where_or, $where_or1])->find();
  1352. // 不是共有客户,检测是否是领导领导调用
  1353. if ($had == null) {
  1354. $had = Customer::find($id);
  1355. // 检测数据是否存在
  1356. if (!$had)
  1357. return json(['code' => 1, 'msg' => '数据不存在']);
  1358. // 登陆人部门及子部门获取
  1359. $my = Org::find($token['org_id']);
  1360. $orgIdList = Org::where([['path', 'like', $my->path . '%']])->column('id');
  1361. // 不是可见部门的 返回空
  1362. // if (!in_array($had->org_id, $orgIdList)) {
  1363. // return json(['code' => 1, 'msg' => '数据不存在']);
  1364. // }
  1365. if ($token['isManager']) {
  1366. // 是管理员
  1367. if (!empty($had->employee_id)) {
  1368. $employeeIdListStr = $had->employee_id . ',' . $had->assigned_personnel . ',' . $had->designer_id;
  1369. $employeeIdListArr = explode(',', $employeeIdListStr);
  1370. $employeeIdListArr = array_filter($employeeIdListArr);
  1371. // 查找分享人是否在部门下
  1372. $exit = Employee::where([['org_id', 'in', $orgIdList], ['id', 'in', $employeeIdListArr]])->count();
  1373. if ($exit == 0)
  1374. return json(['code' => 1, 'msg' => '数据不存在']);
  1375. }
  1376. } else {
  1377. // 不是领导判断 客户是否属于自己 公海库不判断
  1378. if ($had->employee_id && ($had->employee_id != $token['employee_id'])) {
  1379. return json(['code' => 1, 'msg' => '数据不存在']);
  1380. }
  1381. }
  1382. }
  1383. if (!$had)
  1384. return json(['code' => 1, 'msg' => '数据不存在']);
  1385. //客户电话
  1386. $phone = [
  1387. 'phone' => $had->phone,
  1388. 'phone1' => $had->phone1,
  1389. 'phone2' => $had->phone2,
  1390. ];
  1391. //员工电话
  1392. $info = Employee::where('id', $token['employee_id'])->field('out_call_phone,phone')->find();
  1393. // 开启外呼的店面判断
  1394. $set = OutCallSetting::where('root_id', '=', request()->token['root_org'])->findOrEmpty();
  1395. $out_call_check = 0;
  1396. if (!$set->isEmpty()) {
  1397. $out_call_check = 1;
  1398. }
  1399. 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]);
  1400. }
  1401. /*
  1402. * 星标置顶和取消
  1403. */
  1404. public function customer_top()
  1405. {
  1406. $id = $this->request->param('id');
  1407. $CustomerTop = CustomerTop::where(['customer_id' => $id, 'employee_id' => $this->request->token['employee_id'], 'root_id' => request()->token['root_org']])->find();
  1408. if (empty($CustomerTop)) {
  1409. CustomerTop::create(['customer_id' => $id, 'employee_id' => $this->request->token['employee_id'], 'root_id' => request()->token['root_org']]);
  1410. } else {
  1411. CustomerTop::where('id', $CustomerTop['id'])->delete();
  1412. }
  1413. return json(['code' => 0, 'msg' => '操作成功']);
  1414. }
  1415. /*
  1416. * 个人在系统内客户最早的待回访时间和录入时间,最晚待回访时间和录入时间,按以上时间之内可选
  1417. */
  1418. public function time_limit()
  1419. {
  1420. $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();
  1421. $data['max_revisit_time'] = !empty($data['max_revisit_time']) ? date('Y-m-d', strtotime($data['max_revisit_time'])) : null;
  1422. $data['min_revisit_time'] = !empty($data['min_revisit_time']) ? date('Y-m-d', strtotime($data['min_revisit_time'])) : null;
  1423. $data['max_addtime'] = !empty($data['max_addtime']) ? date('Y-m-d', strtotime($data['max_addtime'])) : null;
  1424. $data['min_addtime'] = !empty($data['min_addtime']) ? date('Y-m-d', strtotime($data['min_addtime'])) : null;
  1425. return json(['code' => 0, 'data' => $data, 'msg' => '获取成功']);
  1426. }
  1427. /**
  1428. * 待回访每日具体个数
  1429. */
  1430. public function visit_schedule()
  1431. {
  1432. $date = $this->request->get('date', date('Y-m'));
  1433. $condition = [
  1434. ['state', '<>', '无效'],
  1435. ['employee_id', '=', $this->request->token['employee_id']],
  1436. ['revisit_time', '<>', 'null'],
  1437. ['revisit_time', 'like', $date . '%']
  1438. ];
  1439. $futuredates = Customer::where(function ($query) {
  1440. $query->whereOr([[['state', 'in', Customer::changeState('待确认', 'chaos')], ['crm_res_id', 'NULL', null]], [['state', 'not in', Customer::changeState('待确认', 'chaos')]]]);
  1441. })->where($condition)->field("count(id) as num,date_format(revisit_time, '%Y-%m-%d') as days")->group('days')->select();
  1442. $schedule = [];
  1443. foreach ($futuredates as $r) {
  1444. $schedule[$r['days']] = $r['num'];
  1445. }
  1446. return json(['code' => 0, 'data' => $schedule]);
  1447. }
  1448. /**
  1449. * 工作台待跟进每日具体个数
  1450. */
  1451. public function followup_schedule()
  1452. {
  1453. $date = $this->request->get('date', date('Y-m'));
  1454. // $role = $this->request->token['org_type'] == 2 ? 'designer_id' : 'employee_id';
  1455. $condition = [
  1456. ['state', '=', '0'],
  1457. ['designer_id|employee_id', '=', $this->request->token['employee_id']],
  1458. ['subscribe_date', 'like', $date . '-%']
  1459. ];
  1460. // 排除掉无效的客户
  1461. $customerIdList = CustomersSubscribe::where($condition)->column('customer_id');
  1462. $customerIdList = Customer::where([['id', 'in', $customerIdList], ['state', 'not in', Customer::changeState('无效', 'chaos')]])->column('id');
  1463. $condition[] = ['customer_id', 'in', $customerIdList];
  1464. $futuredates = CustomersSubscribe::where($condition)->field("count(id) as num,subscribe_date as days")->group('days')->select();
  1465. $schedule = [];
  1466. foreach ($futuredates as $r) {
  1467. $schedule[$r['days']] = $r['num'];
  1468. }
  1469. return json(['code' => 0, 'data' => $schedule]);
  1470. }
  1471. /**
  1472. * 待回访数据统计
  1473. */
  1474. public function visitCount()
  1475. {
  1476. $condition = [
  1477. ['employee_id', '=', $this->request->token['employee_id']]
  1478. ];
  1479. // 总数统计
  1480. $total = Customer::where($condition)->count();
  1481. setCondition(date('Y-m-d H:i:s'), 'revisit_time', '<', $condition);
  1482. $visit = Customer::where($condition)->count();
  1483. return json(['code' => 0, 'data' => ['total' => $total, 'visit' => $visit]]);
  1484. }
  1485. /**
  1486. * 公共库
  1487. */
  1488. public function common()
  1489. {
  1490. $param = $this->request->param();
  1491. $page = $param['page'];
  1492. $limit = $param['limit'];
  1493. $condition[] = ['state', 'in', Customer::changeState('无效', 'chaos')];
  1494. $condition[] = ['employee_id', '=', $this->request->token['employee_id']];
  1495. // setCondition($param, ['keyword', 'community_name'], ['like', '%VALUE%'], $condition);
  1496. if (isset($param['keyword']) && $param['keyword']) {
  1497. $condition[] = ['name|community_name', 'like', '%' . trim($param['keyword']) . '%'];
  1498. }
  1499. $customers = Customer::where($condition)->page($page, $limit)->order('addtime desc')->select();
  1500. return json(['code' => 0, 'data' => $customers]);
  1501. }
  1502. /**
  1503. * 客户追踪记录
  1504. */
  1505. public function visitlog()
  1506. {
  1507. $param = request()->param(['id']);
  1508. $token = $this->request->token;
  1509. // 判断是否是当前请求的用户
  1510. if ($this->request->token['isManager']) {
  1511. $team_orgs = orgSubIds($this->request->token['org_id']);
  1512. $empIdList = Employee::where([['org_id', 'in', $team_orgs]])->column('id');
  1513. $this_customer = Customer::find($param['id']);
  1514. if ($this_customer->isEmpty()) {
  1515. return json(['code' => 0, 'data' => [], 'count' => 0]);
  1516. }
  1517. $isMy = 0;
  1518. if (in_array($this_customer['employee_id'], $empIdList)) {
  1519. $isMy = 1;
  1520. }
  1521. if (in_array($this_customer['designer_id'], $empIdList)) {
  1522. $isMy = 1;
  1523. }
  1524. $assigned_personnel = explode(',', $this_customer['assigned_personnel']);
  1525. $assigned_personnel_arr = array_intersect($assigned_personnel, $empIdList);
  1526. if (!empty($assigned_personnel_arr)) {
  1527. $isMy = 1;
  1528. }
  1529. } else {
  1530. $isMy = Customer::where([['id', '=', $param['id']], ['employee_id|designer_id', '=', $this->request->token['employee_id']]])->count();
  1531. }
  1532. //指派人员
  1533. if ($isMy == 0) $isMy = Customer::where([['id', '=', $param['id']], ['assigned_personnel', 'find in set', $token['employee_id']]])->count();
  1534. if ($isMy == 0) return json(['code' => 0, 'data' => [], 'count' => 0]);
  1535. //查询是否设置只显示员工跟进记录不展示修改客户扩展字段
  1536. $showEmpVistlog = Setting::where([['root_id', '=', $token['root_org']], ['name', '=', 'showEmpVistlog']])->findOrEmpty();
  1537. $visit = !$showEmpVistlog->isEmpty() ? (int)$showEmpVistlog->content : 0;
  1538. $vlg_where[] = $visit ? ['save_portrait_field', 'NULL', null] : ['id', '>', 0];
  1539. $vlg_where[] = ['customer_id', '=', $param['id']];
  1540. $data = CustomerVisitLog::with(['employee' => function ($query) {
  1541. $query->field('id,name,org_id');
  1542. }, 'user' => function ($query) {
  1543. $query->field('id,headimgurl');
  1544. }])->where($vlg_where)->order('id desc')->select()->toArray();
  1545. //查询组织所属角色:销售、设计师
  1546. $column_employee_id = array_column($data, 'employee_id');
  1547. $employee = Employee::with(['org' => function ($query) {
  1548. $query->field('id,org_type');
  1549. }])->field('id,org_id')->where('id', 'in', $column_employee_id)->select()->toArray();
  1550. $column_org_type = array_column($employee, null, 'id');
  1551. //预约活动
  1552. $aids = array_column($data, 'aid');
  1553. $activity = array_filter($aids) ? Activity::where([['id', 'in', $aids]])->column('title', 'id') : [];
  1554. $state1 = CustomerVisitLog::changeState('已到店', 'chaos');
  1555. $state2 = CustomerVisitLog::changeState('已到场', 'chaos');
  1556. foreach ($data as &$v) {
  1557. $v['role'] = isset($column_org_type[$v['employee_id']]['org']['org_type']) ? $column_org_type[$v['employee_id']]['org']['org_type'] : null;
  1558. $v['is_track'] = $v['remark'] == '公海获取' ? 1 : 0;
  1559. $v['is_track'] = in_array($v['remark'], ['客户回收', '客户还原', '客户再分配', '资源库分配', '客户转移', '客戶指派', '取消客户下次回访时间']) ? 2 : $v['is_track']; //后台操作
  1560. if ($v['remark']) {
  1561. if (strpos($v['remark'], '[意向客户指派]') !== false || strpos($v['remark'], '[量房客户指派]') !== false || strpos($v['remark'], '[到店客户指派]') !== false) {
  1562. $v['is_track'] = 2;
  1563. }
  1564. }
  1565. //确认到店 的选择的内场活动
  1566. if ($v['aid'] && in_array($v['state'], $state1) && $activity && isset($activity[$v['aid']])) {
  1567. $v['remark'] = $v['remark'] . '预约活动:《' . $activity[$v['aid']] . '》;';
  1568. }
  1569. if (!empty($v['actmeet_type']) && in_array($v['state'], array_merge(CustomerVisitLog::changeState('已到场', 'chaos'), CustomerVisitLog::changeState('预约活动', 'chaos')), true)) {
  1570. if ($v['actmeet_type'] == 1) {
  1571. $v['remark'] .= ',见面方式为外场活动';
  1572. } elseif ($v['actmeet_type'] == 2) {
  1573. $v['remark'] .= ',见面方式为茶楼见面';
  1574. } elseif ($v['actmeet_type'] == 3) {
  1575. $v['remark'] .= ',见面方式为网谈登记';
  1576. }
  1577. }
  1578. if ($v['number_of_visitors'] > 0 && in_array($v['state'], $state1)) {
  1579. $v['remark'] = $v['remark'] . '到店人数:' . $v['number_of_visitors'] . '人;';
  1580. }
  1581. if ($v['talking_order_time'] && in_array($v['state'], $state1)) {
  1582. $v['remark'] = $v['remark'] . '谈单时长:' . $v['talking_order_time'] . '分钟;';
  1583. }
  1584. if ($v['number_of_visitors'] > 0 && in_array($v['state'], $state2)) {
  1585. $v['remark'] = $v['remark'] . '到场人数:' . $v['number_of_visitors'] . '人;';
  1586. }
  1587. if ($v['stay_length'] && in_array($v['state'], $state2)) {
  1588. $v['remark'] = $v['remark'] . '停留时间:' . $v['stay_length'] . '分钟;';
  1589. }
  1590. //zhihuiping
  1591. $v['wisdom_url'] = '';
  1592. $v['is_wisdom'] = 0;
  1593. if ($v['remark'] && strpos($v['remark'], '讲解智慧屏##') !== false) {
  1594. //remark = 接待了客户:张三,讲解时长21分钟@讲解智慧屏## url;
  1595. $v['is_wisdom'] = 1;
  1596. $arr = explode('##', $v['remark']);
  1597. if (count($arr) == 2) {
  1598. $ali_oss_bindurl = config('app.ali_oss_bindurl');
  1599. $v['wisdom_url'] = 'https://' . $ali_oss_bindurl . '/' . $arr[1];
  1600. $title = explode('@', $arr[0]);
  1601. $v['remark'] = $title[0];
  1602. }
  1603. }
  1604. if ($token['client_type'] != 'vL0CQQ') {
  1605. $v['remark'] = str_replace('签单', '转单', $v['remark']);
  1606. $v['remark'] = str_replace('交定', '签单', $v['remark']);
  1607. }
  1608. // 检测是否有录音
  1609. if ($v['data_type'] == 'out_call') {
  1610. $v['is_wisdom'] = 2;
  1611. $v['wisdom_url'] = OutCallLog::where(['id' => $v['data_id']])->value('url');
  1612. } elseif ($v['data_type'] == 'mobile_call' && strpos($v['remark'], '#') !== false) {
  1613. $ali_oss_bindurl = config('app.ali_oss_bindurl');
  1614. $arr = explode('#', $v['remark']);
  1615. $v['wisdom_url'] = 'https://' . $ali_oss_bindurl . '/' . $arr[1];
  1616. $v['remark'] = $arr[0];
  1617. }
  1618. //智慧屏跟进记录
  1619. if ($v['remark'] && strpos($v['remark'], '智慧屏客户图片##') !== false) {
  1620. //remark = 智慧屏客户图片## ## url
  1621. $arr = explode('##', $v['remark']);
  1622. if (count($arr) == 3) {
  1623. $ali_oss_bindurl = config('app.ali_oss_bindurl');
  1624. $imgs = explode(',', $arr[2]);
  1625. $img = [];
  1626. // $count = count($imgs)-1;
  1627. // for ($i=$count; $i >= 0; $i--) {
  1628. // $img[] = 'https://' . $ali_oss_bindurl . '/' . $imgs[$i];
  1629. // }
  1630. foreach ($imgs as $item) {
  1631. $img[] = 'https://' . $ali_oss_bindurl . '/' . $item;
  1632. }
  1633. $v['img'] = $img;
  1634. $v['remark'] = $arr[1];
  1635. }
  1636. }
  1637. //增加取消下次回访时间员工姓名
  1638. if ($v['remark'] == '取消客户下次回访时间') {
  1639. $empname = !empty($v['employee']['name']) ? $v['employee']['name'] : '';
  1640. $v['remark'] = $empname . $v['remark'];
  1641. }
  1642. //检测是否有下载文件
  1643. if (!empty($v['document_field']) && !empty($v['document_name'])) {
  1644. $str = $token['root_org'] . '#' . $token['employee_id'] . '#' . $v['id'];
  1645. $aec = new Aec(config('app.aec_key'), config('app.aec_iv'));
  1646. $value = $aec->encrypt($str);
  1647. $v['document_field'] = $this->request->domain() . '/downdocument/index.html?token=' . $value;
  1648. }
  1649. }
  1650. $count = CustomerVisitLog::where($vlg_where)->count();
  1651. return json(['code' => 0, 'data' => $data, 'count' => $count]);
  1652. }
  1653. /*
  1654. * 客户详情弹出框列表
  1655. * 确认量房、确认到店
  1656. */
  1657. public function visitlogDetails()
  1658. {
  1659. $param = request()->param(['id', 'state']);
  1660. $w[] = ['customer_id', '=', $param['id']];
  1661. if ($param['state'] == '已交定') {
  1662. $w[] = ['state', 'in', CustomerVisitLog::changeState('已交定', 'chaos')];
  1663. } else {
  1664. $w[] = CustomerVisitLog::changeState(['state', '=', '确认' . $param['state']]);
  1665. }
  1666. $root_id = request()->token['root_org'];
  1667. $subOrg = orgSubIds($root_id);
  1668. $w[] = ['org_id', 'in', $subOrg];
  1669. $data = CustomerVisitLog::with(['employee' => function ($query) {
  1670. $query->visible(['name', 'org_id', 'id']);
  1671. }])->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();
  1672. $state1 = CustomerVisitLog::changeState('已到店', 'chaos');
  1673. $state2 = CustomerVisitLog::changeState('已到场', 'chaos');
  1674. //预约活动
  1675. $aids = array_column($data->toArray(), 'aid');
  1676. $activity = array_filter($aids) ? Activity::where([['id', 'in', $aids]])->column('title', 'id') : [];
  1677. //店铺
  1678. // $shop_id = array_column($data->toArray(),'shop_id');
  1679. // $shop = array_filter($shop_id) ? Shop::where([['id','in',$shop_id]])->column('name','id') : [];
  1680. foreach ($data as $k => &$v) {
  1681. if ($v->employee) {
  1682. $v->name = $v->employee->name;
  1683. $v->identity = isset($v->employee->org->org_type) && $v->employee->org->org_type == 2 ? '设计师' : '业务员';
  1684. } else {
  1685. $v->name = '';
  1686. $v->identity = '业务员';
  1687. }
  1688. if ($v->number_of_visitors > 0 && in_array($v['state'], $state1)) {
  1689. $v->remark = $v->remark . '到店人数:' . $v->number_of_visitors . '人;';
  1690. }
  1691. if ($v->number_of_visitors > 0 && in_array($v['state'], $state2)) {
  1692. $v->remark = $v->remark . '到场人数:' . $v->number_of_visitors . '人;';
  1693. }
  1694. if ($v->talking_order_time) {
  1695. $v->remark = $v->remark . '谈单时长:' . $v->talking_order_time . '分钟;';
  1696. }
  1697. if ($v->stay_length) {
  1698. $v->remark = $v->remark . '停留时间:' . $v->stay_length . '分钟;';
  1699. }
  1700. //确认到店 的选择的内场活动
  1701. if ($v['aid'] && in_array($v['state'], $state1) && $activity && isset($activity[$v['aid']])) {
  1702. $v->remark = $v->remark . '预约活动:《' . $activity[$v['aid']] . '》;';
  1703. }
  1704. //增加馨居尚活动见面方式
  1705. if (!empty($v['actmeet_type']) && in_array($v['state'], CustomerVisitLog::changeState('已到场', 'chaos'))) {
  1706. if ($v['actmeet_type'] == 1) {
  1707. $actmeet_type = ',见面方式为外场活动';
  1708. } elseif ($v['actmeet_type'] == 2) {
  1709. $actmeet_type = ',见面方式为茶楼见面';
  1710. } elseif ($v['actmeet_type'] == 3) {
  1711. $actmeet_type = ',见面方式为网谈登记';
  1712. }
  1713. $v->remark = !empty($actmeet_type) ? $v->remark . $actmeet_type : $v->remark;
  1714. }
  1715. //到达店面
  1716. // if ($v['shop_id'] && $shop && isset($shop[$v['shop_id']])) {
  1717. // $v->remark = $v->remark . '到达店面:《' . $shop[$v['shop_id']] . '》;';
  1718. // }
  1719. }
  1720. return json(['code' => 0, 'data' => $data]);
  1721. }
  1722. /**
  1723. * 2022-10-27 逻辑修改,跟进保护优化 如果后台设置了重复客户跟进保护规则 跟进到保护状态后其他客户的此重复客户就不能在跟进了,但是可以置为无效
  1724. */
  1725. private function forbiddenState($id, $status)
  1726. {
  1727. if ($status == '无效') return false;
  1728. $token = $this->request->token;
  1729. //保护规则
  1730. $provite = Setting::where([['name', '=', 'forbiddenState'], ['root_id', '=', $token['root_org']]])->value('content');
  1731. if (!$provite) return false;
  1732. $info = Customer::where('id', $id)->column('phone,phone1,phone2');
  1733. //查询是否是重复客户
  1734. $orgs = Org::where([['path', 'like', $token['root_org'] . '-%']])->column('id');
  1735. $query[] = ['employee_id', '>', 0];
  1736. $query[] = ['org_id', 'in', $orgs];
  1737. $query[] = ['phone|phone1|phone2', 'in', array_filter($info[0])];
  1738. // $query[] = ['employee_id','<>',$token['employee_id']];
  1739. $check = Customer::where($query)->column('id,employee_id');
  1740. if (count($check) <= 1) return false;
  1741. $provite = explode(',', $provite);
  1742. $state = [];
  1743. foreach ($provite as $v) {
  1744. $state = array_merge($state, CustomerVisitLog::changeState($v, 'chaos'));
  1745. }
  1746. //查询该客户是否存在受保护的状态 只有第一个跟进的业务员可以继续跟进
  1747. $where[] = ['state', 'in', $state];
  1748. $where[] = ['customer_id', 'in', array_column($check, 'id')];
  1749. $where[] = ['employee_id|customer_employee_id', 'in', array_column($check, 'employee_id')];
  1750. $repeat = CustomerVisitLog::where($where)->order('id asc')->field('customer_id,state')->findOrEmpty();
  1751. if ($repeat->isEmpty() || (int)$repeat->customer_id == (int)$id) return false;
  1752. //该客户已被其他员工 确认到店/确认量房/确认到场/交定/签单 无法更近
  1753. $state = str_replace('已', '', $repeat->state);
  1754. $state = in_array(trim($state), ['交定', '签单']) ? trim($state) : '确认' . trim($state);
  1755. return '该客户已被其他员工“' . $state . '”无法跟进';
  1756. }
  1757. /**
  1758. * 2022-11-11 业务修改 签单之后可以编辑签单金额,跟进记录增加 业务员修改签单金额为3000元
  1759. */
  1760. private function updateMoney($param)
  1761. {
  1762. $token = $this->request->token;
  1763. $money = $param['money'] ?: 0;
  1764. $where[] = ['id', '=', $param['customer_id']];
  1765. Customer::where($where)->update(['signed_money' => $money]);
  1766. if (isset($param['vlogid']) && $param['vlogid']) CustomerVisitLog::where('id', $param['vlogid'])->update(['money' => $money]);
  1767. $token['name'] = Employee::where([['id', '=', $token['employee_id']]])->value('name');
  1768. $time = date('Y-m-d H:i:s');
  1769. //增加跟进记录
  1770. $save = [
  1771. 'customer_id' => $param['customer_id'],
  1772. 'type' => '',
  1773. 'next_contact_date' => date('Y-m-d'),
  1774. 'remark' => '业务员' . $token['name'] . '修改已签单金额为' . $money . '元',
  1775. 'addtime' => $time,
  1776. 'employee_id' => $token['employee_id'],
  1777. 'user_id' => $token['uid'],
  1778. 'state' => 1,
  1779. 'org_id' => $token['org_id'],
  1780. 'customer_employee_id' => $token['employee_id'],
  1781. 'customer_org_id' => $token['org_id'],
  1782. 'money' => $money
  1783. ];
  1784. //2022-10-28 增加交定和签单凭证 凭证为图片
  1785. $deliverySignVoucher = request()->only(['sign_media_id' => '', 'sign_weixin_media' => '', 'sign_img' => '']);
  1786. $save = $save + $deliverySignVoucher;
  1787. CustomerVisitLog::insertGetId($save);
  1788. if ($deliverySignVoucher['sign_media_id']) Console::call('download', ['sign']);
  1789. $msg = '转单金额修改成功.'; //判断文字显示
  1790. return json(['code' => 0, 'msg' => $msg, 'data' => $msg]);
  1791. }
  1792. /**
  1793. * 取消客户的下次回访时间
  1794. */
  1795. public function cancelNextContactDate()
  1796. {
  1797. $token = $this->request->token;
  1798. $param = request()->only(['id']);
  1799. $cusdata = Customer::where([['state', 'not in', Customer::changeState('无效', 'chaos')], ['id', '=', $param['id']], ['org_id', 'in', orgSubIds($token['root_org'])]])->find();
  1800. if (empty($cusdata)) return json(['code' => 1, 'msg' => '客户数据不存在']);
  1801. $cusdata->revisit_time = null;
  1802. $cusdata->save();
  1803. $add = [
  1804. 'customer_id' => $cusdata->id,
  1805. 'type' => '',
  1806. 'employee_id' => $token['employee_id'],
  1807. 'user_id' => $token['uid'],
  1808. 'remark' => '取消客户下次回访时间',
  1809. 'state' => 10,
  1810. 'confirm_date' => date('Y-m-d'),
  1811. 'org_id' => $token['org_id'],
  1812. 'customer_employee_id' => $cusdata['employee_id'],
  1813. 'customer_org_id' => $cusdata['org_id']
  1814. ];
  1815. $ms = CustomerVisitLog::create($add);
  1816. if ($ms) {
  1817. return json(['code' => 0, 'msg' => '修改成功']);
  1818. } else {
  1819. return json(['code' => 1, 'msg' => '修改失败']);
  1820. }
  1821. }
  1822. /**
  1823. * 添加客户追踪记录
  1824. * 签单、收定时记录金额,更新客户状态,记录回访时间
  1825. * number_of_visitors 到店人数
  1826. * measure_room_img_type 量房图片类型
  1827. *
  1828. * 2022-10-03 逻辑修改,预约到店和确认到店时必须要有内场活动
  1829. *
  1830. */
  1831. public function addVisitlog()
  1832. {
  1833. $token = $this->request->token;
  1834. // 防止后台切换部门
  1835. $token['org_id'] = Employee::where('id', $token['employee_id'])->value('org_id');
  1836. $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]);
  1837. $param['confirm_date'] = $param['confirm_date'] ? $param['confirm_date'] . ' ' . date('H:i:s') : date('Y-m-d H:i:s');
  1838. $employeeTypeName = $token['org_type'] == 2 ? '设计师' : '销售';
  1839. $employeeType = $token['org_type'] == 2 ? 'designer_id' : 'employee_id';
  1840. //2022-10-04 逻辑修改,无效时无效原因必传remark
  1841. // if ($param['state'] == '无效' && empty($param['remark'])) return json(['code' => 1, 'msg' => '请填写无效原因']);
  1842. // 在跟进之前,增加了设计师必填判断,得先查一下设置
  1843. $state = Customer::changeState($param['state']);
  1844. $stateCheck = ['已到店' => 'daodian', '已到场' => 'daochang', '已量房' => 'liangfang', '已交定' => 'qiandan', '已签单' => 'zhuandan'];
  1845. if (in_array($state, ['已到店', '已到场', '已量房', '已交定', '已签单'])) {
  1846. $need_designer[] = ['root_id', '=', $token['root_org']];
  1847. $need_designer[] = ['name', '=', 'add_visit_log_need_designer'];
  1848. $need_designer_setting = Setting::where($need_designer)->findOrEmpty();
  1849. if (!$need_designer_setting->isEmpty()) {
  1850. $need_state = explode(',', $need_designer_setting['content']);
  1851. $input_state = $stateCheck[$state] ?? '';
  1852. if (!empty($input_state) && in_array($input_state, $need_state)) {
  1853. // 需要验证
  1854. $customer_find = Customer::find($param['customer_id']);
  1855. if (!empty($customer_find)) {
  1856. if (empty($customer_find['assigned_personnel'])) {
  1857. return json(['code' => 1, 'msg' => '请先指派设计师']);
  1858. }
  1859. $assigned_personnel = explode(',', $customer_find['assigned_personnel']);
  1860. $assigned_personnel_employee_org = Employee::where('id', 'in', $assigned_personnel)->column('org_id');
  1861. $assigned_personnel_org_type = Org::where('id', 'in', $assigned_personnel_employee_org)->column('org_type');
  1862. if (!in_array(2, $assigned_personnel_org_type)) {
  1863. return json(['code' => 1, 'msg' => '请先指派设计师']);
  1864. }
  1865. }
  1866. }
  1867. }
  1868. }
  1869. //2022-10-27 逻辑修改,跟进保护优化 如果后台设置了重复客户跟进保护规则 跟进到保护状态后其他业务员的此重复客户就不能在跟进了,但是可以置为无效
  1870. $forbiddenState = $this->forbiddenState($param['customer_id'], $param['state']);
  1871. if ($forbiddenState != false) return json(['code' => 1, 'msg' => $forbiddenState]);
  1872. //23-03-10 共有客户列表管理层查看下级部门所有员工指派的跟被指派的客户,同时还可以跟进修改查询客户的逻辑
  1873. if (isset($token['isManager']) && $token['isManager']) {
  1874. $team_orgs = orgSubIds($token['org_id']);
  1875. $org_employee = Employee::where([['org_id', 'in', $team_orgs], ['state', '=', '在职'], ['uid', '>', 0]])->column('id');
  1876. } else {
  1877. $org_employee = [$token['employee_id']];
  1878. }
  1879. $where = [
  1880. ['id', '=', $param['customer_id']],
  1881. ['state', '<>', '无效']
  1882. ];
  1883. $had = Customer::where($where)->where(function ($query) use ($org_employee) {
  1884. foreach ($org_employee as $k => $v) {
  1885. $query->whereOr([['employee_id|designer_id|assigned_personnel', 'find in set', $v]]);
  1886. }
  1887. })->find();
  1888. // $where = [
  1889. // ['id', '=', $param['customer_id']],
  1890. // ['state', '<>', '无效'],
  1891. // ['employee_id', '=', $token['employee_id']]
  1892. // ];
  1893. // //指派的客户
  1894. // $where_or = [['assigned_personnel', 'find in set', $token['employee_id']], ['id', '=', $param['customer_id']]];
  1895. // $where_or1 = [['designer_id', '=', $token['employee_id']], ['id', '=', $param['customer_id']]];
  1896. // $had = Customer::whereOr($where, $where_or, $where_or1)->find();
  1897. if (!$had) return json(['code' => 1, 'msg' => '添加失败,数据不存在']);
  1898. if ($had['died'] == 2) {
  1899. return json(['code' => 1, 'msg' => '客户死单,暂无法跟踪']);
  1900. }
  1901. //签单之后不能置为无效
  1902. if ($param['state'] == '无效') {
  1903. $is_orders = CustomerVisitLog::where([['state', 'in', CustomerVisitLog::changeState('已签单', 'chaos')], ['customer_id', '=', $had->id]])->count();
  1904. if ($is_orders) return json(['code' => 1, 'msg' => '该客户已签单,不能置为无效']);
  1905. }
  1906. //改为有效之后不能再改为待确认
  1907. if ($param['state'] == '待确认') {
  1908. if ($had->state != '待确认') return json(['code' => 1, 'msg' => '该客户已标记为有效,不能修改为待确认']);
  1909. }
  1910. // 撞单机制 从待确认变为有效
  1911. if (in_array($state, ['未到访', '已到店', '已到场', '已量房', '已交定', '已签单', '已卖卡']) && $had->state == '待确认') {
  1912. // 同部门能否重复录入开关设置
  1913. $empcrm_repeat[] = ['root_id', '=', $token['root_org']];
  1914. $empcrm_repeat[] = ['name', '=', 'empcrm_customer_repeat'];
  1915. $repeat_setting = Setting::where($empcrm_repeat)->findOrEmpty();
  1916. //判断同部门
  1917. if (!$repeat_setting->isEmpty()) {
  1918. $repeat_org = explode(',', $repeat_setting['content']);
  1919. if (!in_array($had['org_id'], $repeat_org)) {
  1920. $repeat_org = [$had['org_id']];
  1921. }
  1922. } else {
  1923. $repeat_org = [$had['org_id']];
  1924. }
  1925. // 需要验证
  1926. $not_sure = Customer::changeState('待确认', 'chaos');
  1927. $wuxiao = Customer::changeState('无效', 'chaos');
  1928. $phones_arr = array_filter([$had['phone'], $had['phone1'], $had['phone2']]);
  1929. $repeat_where[] = ['phone|phone1|phone2', 'in', $phones_arr];
  1930. $repeat_where[] = ['org_id', 'in', $repeat_org];
  1931. $repeat_where[] = ['state', 'not in', array_merge($not_sure, $wuxiao)];
  1932. $repeat_where[] = ['id', '<>', $param['customer_id']];
  1933. $customerExist = Customer::where($repeat_where)->field('id,employee_id,source_id');
  1934. if (!empty($customerExist)) {
  1935. foreach ($customerExist as $ex) {
  1936. if ($ex['employee_id'] != $had['employee_id']) {
  1937. //查询撞单客户渠道
  1938. $source_name = '';
  1939. if ($ex['source_id']) {
  1940. $source = CustomerSource::where(['id' => $ex['source_id']])->value('source');
  1941. $source_name = $source . '渠道客户';
  1942. }
  1943. $have_emp = Employee::where('id', '=', $ex['employee_id'])->value('name');
  1944. return json(['code' => 2, 'msg' => '该客户与员工' . $have_emp . $source_name . '撞单,无法标记有效']);
  1945. }
  1946. }
  1947. }
  1948. }
  1949. if (in_array($state, ['未到访', '已到店', '已到场', '已量房', '已交定', '已签单', '已卖卡']) && $had->state == '待确认') {
  1950. $valid_time = date('Y-m-d H:i:s');
  1951. if (!empty($param['confirm_date'])) {
  1952. $valid_time = $param['confirm_date'];
  1953. }
  1954. $had->valid_time = $valid_time;
  1955. }
  1956. // 如果是预约添加预约记录
  1957. $stateType = [
  1958. 1 => '到店',
  1959. 2 => '到场',
  1960. 3 => '量房'
  1961. ];
  1962. $yylf_state = CustomerVisitLog::changeState('预约量房', 'chaos');
  1963. $lf_state = CustomerVisitLog::changeState('已量房', 'chaos');
  1964. $yydc_state = CustomerVisitLog::changeState('预约活动', 'chaos');
  1965. $dc_state = CustomerVisitLog::changeState('已到场', 'chaos');
  1966. $yydd_state = CustomerVisitLog::changeState('预约到店', 'chaos');
  1967. $dd_state = CustomerVisitLog::changeState('已到店', 'chaos');
  1968. $check_state = array_merge($yylf_state, $lf_state, $yydc_state, $dc_state, $yydd_state, $dd_state);
  1969. if (in_array($param['state'], $check_state)) {
  1970. // 保护设置
  1971. $sub_setting = Setting::where([['root_id', '=', $token['root_org']], ['name', '=', 'subscribe_protected']])->findOrEmpty();
  1972. if (!$sub_setting->isEmpty()) { // 有设置
  1973. $setting_content = json_decode($sub_setting['content'], true);
  1974. $org_ids = orgSubIds($token['root_org']);
  1975. foreach ($setting_content as $k_s => $v_s) {
  1976. if (!empty($v_s['state']) && !empty($v_s['day']) && $v_s['state'] == 1) {
  1977. $continue = false;
  1978. $sub_state = 0;
  1979. $errmsg = '该客户在保护期内,无法提交';
  1980. $check_log = false;
  1981. $check_where = [];
  1982. switch ($k_s) {
  1983. case 'liangfang':
  1984. $sub_state = 3;
  1985. $visit_state = 1;
  1986. $check_log = true;
  1987. $check_where[] = ['org_id', 'in', $org_ids];
  1988. $check_where[] = ['addtime', '>', date('Y-m-d H:i:s', time() - 24 * 3600 * $v_s['day'])];
  1989. $check_where[] = ['employee_id', '<>', $token['employee_id']];
  1990. $check_where[] = ['state', 'in', $lf_state];
  1991. break;
  1992. case 'yliangfang': //预约量房
  1993. $sub_state = 3;
  1994. $visit_state = 0;
  1995. break;
  1996. case 'daodian':
  1997. $sub_state = 1;
  1998. $visit_state = 1;
  1999. $check_log = true;
  2000. $check_where[] = ['org_id', 'in', $org_ids];
  2001. $check_where[] = ['addtime', '>', date('Y-m-d H:i:s', time() - 24 * 3600 * $v_s['day'])];
  2002. $check_where[] = ['employee_id', '<>', $token['employee_id']];
  2003. $check_where[] = ['state', 'in', $dd_state];
  2004. break;
  2005. case 'ydaodian':
  2006. $sub_state = 1;
  2007. $visit_state = 0;
  2008. break;
  2009. case 'daochang':
  2010. $sub_state = 2;
  2011. $visit_state = 1;
  2012. $check_log = true;
  2013. $check_where[] = ['org_id', 'in', $org_ids];
  2014. $check_where[] = ['addtime', '>', date('Y-m-d H:i:s', time() - 24 * 3600 * $v_s['day'])];
  2015. $check_where[] = ['employee_id', '<>', $token['employee_id']];
  2016. $check_where[] = ['state', 'in', $dc_state];
  2017. break;
  2018. case 'ydaochang':
  2019. $sub_state = 2;
  2020. $visit_state = 0;
  2021. break;
  2022. default:
  2023. $continue = true;
  2024. break;
  2025. }
  2026. if ($continue) continue;
  2027. // “确认” 不受预约的限制
  2028. if (in_array($k_s, ['yliangfang', 'ydaodian', 'ydaochang']) && in_array($param['state'], array_merge($lf_state, $dd_state, $dc_state))) {
  2029. continue;
  2030. }
  2031. if (in_array($param['state'], array_merge($lf_state, $dd_state, $dc_state))) {
  2032. $errmsg = '该客户在保护期内,无法提交确认';
  2033. } elseif (in_array($param['state'], array_merge($yylf_state, $yydd_state, $yydc_state))) {
  2034. $errmsg = '该客户在保护期内,无法预约';
  2035. }
  2036. // 查询保护时间段内添加的预约量房记录
  2037. unset($v_where);
  2038. $v_where[] = ['org_id', 'in', $org_ids];
  2039. $v_where[] = ['addtime', '>', date('Y-m-d H:i:s', time() - 24 * 3600 * $v_s['day'])];
  2040. $v_where[] = ['employee_id', '<>', $token['employee_id']];
  2041. $v_where[] = ['type', '=', $sub_state];
  2042. $v_where[] = ['state', '=', $visit_state];
  2043. $sub_list = CustomersSubscribe::where($v_where)->select()->toArray();
  2044. if (!empty($sub_list)) {
  2045. $sub_list_ids = array_column($sub_list, 'customer_id');
  2046. $sub_employee_ids = array_column($sub_list, 'employee_id');
  2047. $sub_customers = Customer::where([['id', 'in', $sub_list_ids], ['employee_id', 'in', $sub_employee_ids]])->select()->toArray();
  2048. foreach ($sub_customers as $v) {
  2049. if (in_array($had->phone, [$v['phone'], $v['phone1'], $v['phone2']]) && $v['id'] != $had['id']) {
  2050. return json(['code' => 1, 'msg' => $errmsg]);
  2051. }
  2052. if (!empty($had->phone1) && in_array($had->phone1, [$v['phone'], $v['phone1'], $v['phone2']]) && $v['id'] != $had['id']) {
  2053. return json(['code' => 1, 'msg' => $errmsg]);
  2054. }
  2055. if (!empty($had->phone2) && in_array($had->phone2, [$v['phone'], $v['phone1'], $v['phone2']]) && $v['id'] != $had['id']) {
  2056. return json(['code' => 1, 'msg' => $errmsg]);
  2057. }
  2058. }
  2059. }
  2060. if ($check_log) {
  2061. $log_list = CustomerVisitLog::where($check_where)->select()->toArray();
  2062. $log_list_ids = array_column($log_list, 'customer_id');
  2063. $log_employee_ids = array_column($log_list, 'employee_id');
  2064. $log_customers = Customer::where([['id', 'in', $log_list_ids], ['employee_id', 'in', $log_employee_ids]])->select()->toArray();
  2065. foreach ($log_customers as $v) {
  2066. if (in_array($had->phone, [$v['phone'], $v['phone1'], $v['phone2']]) && $v['id'] != $had['id']) {
  2067. return json(['code' => 1, 'msg' => $errmsg]);
  2068. }
  2069. if (!empty($had->phone1) && in_array($had->phone1, [$v['phone'], $v['phone1'], $v['phone2']]) && $v['id'] != $had['id']) {
  2070. return json(['code' => 1, 'msg' => $errmsg]);
  2071. }
  2072. if (!empty($had->phone2) && in_array($had->phone2, [$v['phone'], $v['phone1'], $v['phone2']]) && $v['id'] != $had['id']) {
  2073. return json(['code' => 1, 'msg' => $errmsg]);
  2074. }
  2075. }
  2076. }
  2077. }
  2078. }
  2079. }
  2080. }
  2081. // 更改客户信息
  2082. $state = Customer::changeState($param['state']);
  2083. $orders = false;
  2084. //签单之后不能签单交定,可以跟进
  2085. if ($state == '已签单') {
  2086. $is = CustomerVisitLog::where([['state', 'in', CustomerVisitLog::changeState('已签单', 'chaos')], ['customer_id', '=', $had->id]])->count();
  2087. if ($is) {
  2088. //2022-11-11 业务修改 签单之后可以编辑签单金额,跟进记录增加 业务员修改签单金额为3000元
  2089. return $this->updateMoney($param);
  2090. // return json(['code' => 1, 'msg' => '该客户' . $state]);
  2091. }
  2092. $orders = true;
  2093. } elseif ($state == '已交定') {
  2094. $is = CustomerVisitLog::where([['state', 'in', CustomerVisitLog::changeState('已签单', 'chaos')], ['customer_id', '=', $had->id]])->count();
  2095. if ($is) {
  2096. return json(['code' => 1, 'msg' => '该客户已签单']);
  2097. }
  2098. $orders = true;
  2099. }
  2100. // 检测确认 到店/量房/交定/签单
  2101. $stateCheck = ['已到店' => 'visitShopConfirm', '已到场' => 'visitSiteConfirm', '已量房' => 'measureConfirm', '已交定' => 'depositConfirm', '已签单' => 'signConfirm'];
  2102. if ($token['org_type'] == 1 || ($token['org_type'] == 2 && $token['employee_id'] != $had['employee_id'])) {
  2103. foreach ($stateCheck as $ss => $set) {
  2104. if ($ss != $state) continue;
  2105. $setContent = Setting::where(['name' => $set, 'root_id' => $this->request->token['root_org'], 'state' => 1])->value('content');
  2106. // 没有找到则不限制
  2107. if ($setContent == null) continue;
  2108. $setContent = json_decode($setContent, true);
  2109. if (count($setContent) == 0) continue;
  2110. if (in_array($had->designer_id, $org_employee) && in_array('designer', $setContent))
  2111. continue;
  2112. if (in_array($had->employee_id, $org_employee) && in_array('salesperson', $setContent))
  2113. continue;
  2114. // 共有客户 销售人员
  2115. $assigned_personnel = explode(',', $had['assigned_personnel']);
  2116. $designer_arr = !empty($had['designer_id']) ? [$had['designer_id']] : [];
  2117. $salesperson = array_diff($assigned_personnel, $designer_arr);
  2118. if ($token['org_type'] == 1 && array_intersect($salesperson, $org_employee) && in_array('salesperson', $setContent))
  2119. continue;
  2120. // 多设计师指派时候,多的设计师会存在$salesperson 中
  2121. if ($token['org_type'] == 2 && array_intersect($salesperson, $org_employee) && in_array('designer', $setContent)) {
  2122. continue;
  2123. }
  2124. return json(['code' => 1, 'msg' => '操作失败,无确认权限']);
  2125. }
  2126. }
  2127. Db::startTrans();
  2128. if (!empty($state)) {
  2129. $had->state = $state;
  2130. }
  2131. $had->revisit_time = $param['next_contact_date'] . ' 00:00:00';
  2132. $had->last_contact_date = date('Y-m-d', time());
  2133. $had->updatetime = date('Y-m-d H:i:s', time());
  2134. if ($param['aid'] && $param['state'] == '预约活动') $had->aid = $param['aid'];
  2135. $had->fresh = 0;
  2136. // 交定产品
  2137. $dingMsg = '';
  2138. if ($had->state == '已交定') {
  2139. empty($param['money']) ?: $had->deposit_money = $param['money'];
  2140. empty($param['estimated_sign_money']) ?: $had->estimated_sign_money = $param['estimated_sign_money'];
  2141. if (!empty($param['package'])) {
  2142. $package = CustomerPackage::where([['root_id', '=', $this->request->token['root_org']], ['id', 'in', $param['package']]])->column('name', 'id');
  2143. if (!$package) return json(['code' => 1, 'msg' => '客户产品不存在']);
  2144. $had->package_id = implode(',', array_keys($package));
  2145. $dingMsg = ',交定金额:' . $param['money'] . '元,选择产品:' . implode(',', $package);
  2146. }
  2147. }
  2148. if ($had->state == '已签单' && !empty($param['money'])) $had->signed_money = $param['money'];
  2149. $had->save();
  2150. // 更新客户保护期
  2151. if ($param['state'] !== '无效' && !empty($state)) {
  2152. $log_state = CustomerVisitLog::changeState($state, 'chaos');
  2153. $vis_where[] = ['employee_id', '=', $this->request->token['employee_id']];
  2154. $vis_where[] = ['state', 'in', $log_state];
  2155. $vis_where[] = ['customer_id', '=', $param['customer_id']];
  2156. if (!empty($had['employee_time'])) {
  2157. $vis_where[] = ['addtime', '>', $had['employee_time']];
  2158. }
  2159. $v_count = CustomerVisitLog::where($vis_where)->count();
  2160. //查看此状态的跟踪记录,如果有数据,说明此客户在此员工这里已经经历过此状态,不再更新保护期
  2161. if (!$v_count) {
  2162. Customer::changeProtectedTo($had->id, $this->request->token['root_org']);
  2163. }
  2164. }
  2165. // 添加确定消息内容
  2166. $confirmMsg = '';
  2167. if (!empty($param['confirm_date'])) {
  2168. $confirmMsg = ', 时间:' . date('Y-m-d', strtotime($param['confirm_date']));
  2169. }
  2170. // 到店消息
  2171. $state_msg = '';
  2172. if ($param['state'] == '已到店') {
  2173. if ($param['shop_id']) {
  2174. $shop_name = Shop::where('id', $param['shop_id'])->value('name');
  2175. $state_msg = ',所到店面为:' . $shop_name;
  2176. }
  2177. }
  2178. // 备注
  2179. $employeeName = Employee::where(['id' => $this->request->token['employee_id']])->value('name');
  2180. $remark = $param['remark'];
  2181. if (empty($remark)) {
  2182. if (empty($state))
  2183. $remark = $employeeTypeName . $employeeName . '对客户进行了回访';
  2184. else
  2185. $remark = $employeeTypeName . $employeeName . '更新客户状态为' . $state . $state_msg . $confirmMsg . $dingMsg;
  2186. }
  2187. //2022-10-04 逻辑修改,无效时增加无效原因
  2188. if ($param['state'] == '无效' && !empty($param['remark'])) {
  2189. // $remark = $employeeTypeName . $employeeName . '更新客户状态为' . $state . $confirmMsg . ',原因是:' . $param['remark'] . $dingMsg;
  2190. }
  2191. // 添加追踪记录
  2192. $visitLog = [
  2193. 'customer_id' => $had->id,
  2194. 'type' => $param['type'],
  2195. 'next_contact_date' => !empty($param['next_contact_date']) ? $param['next_contact_date'] : null,
  2196. 'employee_id' => $this->request->token['employee_id'],
  2197. 'user_id' => $this->request->token['uid'],
  2198. 'remark' => $remark,
  2199. 'state' => $param['state'],
  2200. 'weixin_media' => $param['weixin_media'],
  2201. 'media_id' => $param['media_id'],
  2202. 'starts' => $param['starts'],
  2203. 'money' => $param['money'],
  2204. 'confirm_date' => $param['confirm_date'],
  2205. 'org_id' => $token['org_id'],
  2206. 'aid' => $param['aid'] ?: $had->aid,
  2207. 'weixin_media1' => $param['weixin_media1'],
  2208. 'media_id1' => $param['media_id1'],
  2209. 'customer_employee_id' => $had->employee_id,
  2210. 'customer_org_id' => Employee::where('id', $had->employee_id)->value('org_id'),
  2211. 'img' => $param['img'],
  2212. 'img1' => $param['img1'],
  2213. 'number_of_visitors' => $param['number_of_visitors'],
  2214. 'measure_room_img_type' => $param['measure_room_img_type'],
  2215. 'deposit_mode' => $param['deposit_mode'],
  2216. 'stay_length' => $param['stay_length'],
  2217. 'down_payment' => $param['down_payment'],
  2218. 'shop_id' => $param['shop_id'],
  2219. 'actmeet_type' => !empty($param['actmeet_type']) && $token['client_type'] == 'vL0CQQ' ? $param['actmeet_type'] : 0, //馨居尚才可记录见面方式
  2220. 'document_field' => $param['document_field'],
  2221. 'document_name' => $param['document_name']
  2222. ];
  2223. $returnvisit = ['customer_org_id' => $visitLog['customer_org_id']];
  2224. //2022-10-28 增加交定和签单凭证 凭证为图片 谈单时长talking_order_time
  2225. $deliverySignVoucher = request()->only(['delivery_media_id' => '', 'delivery_weixin_media' => '', 'sign_media_id' => '', 'sign_weixin_media' => '', 'delivery_img' => '', 'sign_img' => '', 'talking_order_time' => '']);
  2226. $visitLog = $visitLog + $deliverySignVoucher;
  2227. empty($param['img']) ?: $visitLog['img'] = $param['img'];
  2228. if (!empty($param['aid'])) {
  2229. // 检测活动是否存在
  2230. $existActivity = Activity::where([['id', '=', $param['aid']], ['root_id', '=', $this->request->token['root_org']]])->count();
  2231. if ($existActivity == 0) {
  2232. Db::rollback();
  2233. return json(['code' => 1, 'msg' => '活动不存在']);
  2234. }
  2235. $visitLog['aid'] = $param['aid'];
  2236. }
  2237. $visitLog = CustomerVisitLog::create($visitLog);
  2238. if ($orders) $this->preformance_tasks($state, $param['customer_id'], $param['money'], $visitLog->id); //计算业绩
  2239. // 如果是预约添加预约记录
  2240. if (strpos($visitLog->state, '预约') !== false) {
  2241. //2022-11-09 增加指派客户逻辑 同一个客户可以指派多人, 但是该客户在同一天内只能有一个预约,预约之后其他人就不能预约了,,,不同日期可以继续预约
  2242. $state = str_replace('预约', '', $visitLog->state);
  2243. // 查找是否已经预约
  2244. $hadSubscribe = CustomersSubscribe::where([
  2245. ['customer_id', '=', $had['id']],
  2246. // ['employee_id|designer_id', '=', $this->request->token['employee_id']],
  2247. ['subscribe_date', '=', date('Y-m-d', strtotime($param['confirm_date']))],
  2248. ['state', '=', 0]
  2249. ])->count();
  2250. $typeSubscribe = CustomersSubscribe::where([
  2251. ['customer_id', '=', $had['id']],
  2252. // ['employee_id|designer_id', '=', $this->request->token['employee_id']],
  2253. ['type', '=', array_search($state, $stateType)],
  2254. ['state', '=', 0]
  2255. ])->find();
  2256. $typeSubscribe = false; // 不是同一天的预约,同类型还可以预约
  2257. if ($hadSubscribe) {
  2258. Db::rollback();
  2259. return json(['code' => 1, 'msg' => '该客户在当前日期已有预约']);
  2260. } elseif ($typeSubscribe) {
  2261. Db::rollback();
  2262. return json(['code' => 1, 'msg' => '该客户已有' . $state . '预约, 预约日期' . $typeSubscribe->subscribe_date]);
  2263. } else {
  2264. $subscribe = [
  2265. 'customer_id' => $had['id'],
  2266. 'subscribe_date' => $param['confirm_date'],
  2267. 'employee_id' => $had->employee_id,
  2268. 'designer_id' => $had->designer_id,
  2269. 'type' => $state,
  2270. 'aid' => $param['aid'] ?: $had->aid,
  2271. 'org_id' => $had->org_id,
  2272. 'actmeet_type' => !empty($param['actmeet_type']) && $token['client_type'] == 'vL0CQQ' ? $param['actmeet_type'] : 0 //馨居尚才可记录见面方式
  2273. ];
  2274. CustomersSubscribe::create($subscribe);
  2275. }
  2276. }
  2277. //当设为无效时,记录当前操作人跟进的最后一次状态,此处在公海列表处展示
  2278. if ($param['state'] == '无效') {
  2279. $last_cvl = CustomerVisitLog::where('customer_id', $param['customer_id'])->with('employee')->order('addtime desc')->find();
  2280. //获取"无效"并进入公海之前的那次跟进记录的信息
  2281. if ($last_cvl) {
  2282. $before_pool = [
  2283. 'name' => $last_cvl->employee->name,
  2284. 'state' => $last_cvl->state,
  2285. 'addtime' => $last_cvl->addtime
  2286. ];
  2287. } else {
  2288. $before_pool = [
  2289. 'name' => Employee::find($this->request->token['employee_id'])->value('name'),
  2290. 'state' => '待确认',
  2291. 'addtime' => $had->addtime
  2292. ];
  2293. }
  2294. // 该客户预约中的状态置为无效
  2295. CustomersSubscribe::where([['customer_id', '=', $param['customer_id']], ['state', '=', 0]])->save(['state' => -1]);
  2296. //公海内是否存在该客户信息,存在则合并客户信息(phone、phone1、phone2)
  2297. $orgids = orgSubIds($token['root_org']);
  2298. $phone_arr = [];
  2299. !empty(trim($had['phone'])) ? $phone_arr[] = cypherphone(trim($had['phone'])) : '';
  2300. !empty(trim($had['phone1'])) ? $phone_arr[] = cypherphone(trim($had['phone1'])) : '';
  2301. !empty(trim($had['phone2'])) ? $phone_arr[] = cypherphone(trim($had['phone2'])) : '';
  2302. $phone_arr = array_filter($phone_arr);
  2303. $pool_condition = [
  2304. ['employee_id', '=', NULL],
  2305. ['is_resource', '=', 0],
  2306. ['org_id', 'in', $orgids],
  2307. ['phone|phone1|phone2', 'in', $phone_arr]
  2308. ];
  2309. $pool_crm = Customer::where($pool_condition)->column('id');
  2310. if (!empty($pool_crm)) {
  2311. //公海存在则删除
  2312. Customer::where([['id', 'in', $pool_crm]])->update(['delete_time' => time()]);
  2313. //关联回访记录修改
  2314. CustomerVisitLog::where([['customer_id', 'in', $pool_crm]])->update(['is_merge' => 1, 'customer_id' => $had['id']]);
  2315. CustomersSubscribe::where([['customer_id', 'in', $pool_crm]])->update(['is_merge' => 1, 'customer_id' => $had['id']]);
  2316. }
  2317. //增加无效记录
  2318. $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();
  2319. $invalidlog = [
  2320. 'customer_id' => $param['customer_id'],
  2321. 'employee_id' => $had->employee_id,
  2322. 'designer_id' => $had->designer_id ? $had->designer_id : 0,
  2323. 'org_id' => $had->org_id,
  2324. 'root_id' => $this->request->token['root_org'],
  2325. 'cus_addtime' => $had->sign_time,
  2326. 'visitlog_id' => $visitLog->id,
  2327. 'assigned_personnel' => $had->assigned_personnel ? $had->assigned_personnel : '',
  2328. 'source_id' => $had->source_id ? $had->source_id : 0,
  2329. 'status' => !empty($vlglist) ? 1 : 2,
  2330. 'cus_employee_time' => $had->employee_time,
  2331. 'is_resource' => $had->is_resource,
  2332. 'valid_time' => $had->valid_time
  2333. ];
  2334. CustomerInvalidLog::create($invalidlog);
  2335. 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]);
  2336. // -------------------- 企业微信逻辑相关 start -----------------
  2337. // 判断是否绑定有企业微信外部联系人关系,并做解绑操作
  2338. $company_id = Company::where('root_id', '=', $this->request->token['root_org'])->value('id');
  2339. $company_setting = WeworksingleCompanySetting::where('company_id', '=', $company_id)->find();
  2340. if (!empty($company_setting)) {
  2341. $w_where['company_id'] = $company_id;
  2342. $w_where['employee_id'] = $this->request->token['employee_id'];
  2343. $w_where['customer_id'] = $param['customer_id'];
  2344. WeworksingleCustomer::where($w_where)->save(['customer_id' => 0]);
  2345. }
  2346. // -------------------- 企业微信逻辑相关 end -----------------
  2347. }
  2348. // //如果签单,默认交定
  2349. // if (strpos($param['state'], "签单") !== false) {
  2350. // trace(strpos($param['state'], "签单"));
  2351. // $lw[] = CustomerVisitLog::changeState(['state', '=', '交定']);
  2352. // $lw[] = ['customer_id', '=', $param['customer_id']];
  2353. // $check = CustomerVisitLog::where($lw)->find();
  2354. // if (!$check) {
  2355. // $l_visitlog = $visitLog->toArray();
  2356. // unset($l_visitlog['id']);
  2357. // $l_visitlog['state'] = '交定';
  2358. // $l_visitlog['remark'] = !empty($param['remark']) ? $param['remark'] : $employeeTypeName . $employeeName . '变更客户状态为交定';
  2359. // $new_visitlog = array_merge($param, $l_visitlog);
  2360. // $new_visitlog['money'] = 0; //直接签单默认交定金额为0
  2361. // $mr = CustomerVisitLog::create($new_visitlog);
  2362. // $this->preformance_tasks('已交定', $param['customer_id'], $param['money'], $mr->id); //计算业绩
  2363. // }
  2364. // }
  2365. if (in_array($param['state'], ['已到店', '已量房', '已到场'])) {
  2366. $state = str_replace('已', '', $param['state']);
  2367. $subscribe = CustomersSubscribe::where([['customer_id', '=', $had['id']], ['type', '=', array_search($state, $stateType)], ['state', '=', 0]])->find();
  2368. if (!empty($subscribe)) {
  2369. $subscribe->state = 1;
  2370. $subscribe->save();
  2371. } elseif ($param['aid'] && in_array($param['state'], ['已到场'])) { //没有预约可以直接确认到场
  2372. $this->activityState($param, $had);
  2373. }
  2374. }
  2375. if (in_array($param['state'], ['未到店', '未量房', '未到场'])) {
  2376. $state = str_replace('未', '', $param['state']);
  2377. $subscribe = CustomersSubscribe::where([['customer_id', '=', $had['id']], ['type', '=', array_search($state, $stateType)], ['state', '=', 0]])->find();
  2378. if (!empty($subscribe)) {
  2379. $subscribe->state = -1;
  2380. $subscribe->save();
  2381. }
  2382. $data = [
  2383. 'eid' => $had->employee_id,
  2384. 'org_id' => $returnvisit['customer_org_id'],
  2385. 'designer_id' => $had->designer_id,
  2386. 'confirm_date' => $param['confirm_date'],
  2387. 'customer_id' => $had->id,
  2388. 'return_visit' => $had->return_visit,
  2389. 'name' => $had->name,
  2390. 'state' => $param['state']
  2391. ];
  2392. $this->cancelReservation($data);
  2393. //取消预约后,待回访状态也要取消
  2394. $had->return_visit = 0;
  2395. $had->save();
  2396. }
  2397. //增加经纪人送积分功能
  2398. if ($had->agents_id && in_array($param['state'], ['已到店', '已交定', '已签单', '已量房'])) {
  2399. $state_type = CustomerPortraitFieldSelect::where('id', $param['state_type'])->value('name');
  2400. $this->agents_integral($had->agents_id, $param['state'], $had->id, $state_type, $param['money'], $param['state_type']);
  2401. }
  2402. // 微爆活动
  2403. if (in_array($param['state'], ['已到店', '已量房', '已到场', '已交定', '已签单'])) {
  2404. $activity_data['customer_id'] = $param['customer_id'];
  2405. $activity_data['employee_id'] = $had['employee_id'];
  2406. $activity_data['org_id'] = $had['org_id'];
  2407. switch ($param['state']) {
  2408. case '已到店':
  2409. $activity_data['type'] = 2;
  2410. break;
  2411. case '已量房':
  2412. $activity_data['type'] = 3;
  2413. break;
  2414. case '已交定':
  2415. $activity_data['type'] = 4;
  2416. break;
  2417. case '已签单':
  2418. $activity_data['type'] = 5;
  2419. break;
  2420. case '已到场':
  2421. $activity_data['type'] = 7;
  2422. break;
  2423. default:
  2424. break;
  2425. }
  2426. WechatActivityIntegral::addIntegral($activity_data, $token['root_org']);
  2427. }
  2428. Db::commit();
  2429. // $from_wework = input('from_wework', '', 'trim');
  2430. // if ($from_wework) {
  2431. // Console::call('download', ['customer', 'wework', (string)$token['root_org'], (string)$visitLog->id]);
  2432. // Console::call('download', ['customer1', 'wework', (string)$token['root_org'], (string)$visitLog->id]);
  2433. // } else {
  2434. // Console::call('download', ['customer', 'mini', (string)$token['root_org'], (string)$visitLog->id]);
  2435. // Console::call('download', ['customer1', 'mini', (string)$token['root_org'], (string)$visitLog->id]);
  2436. // }
  2437. //2022-10-28 更新交定/签单凭证
  2438. // if (in_array($param['state'], ['已交定', '已签单'])) {
  2439. // $deliveryType = $param['state'] == '已交定' ? 'delivery' : 'sign';
  2440. // // Console::call('download', [$deliveryType]);
  2441. // }
  2442. Console::call('medal', ['visit_log', (string)$this->request->token['employee_id'], (string)$this->request->token['root_org']]); //勋章
  2443. //给业务经理和设计是发送提醒消息回访
  2444. $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']];
  2445. $index = uniqid();
  2446. Cache::set($index, $data, 60);
  2447. // $this->returnVisit($data);
  2448. Customer::where('id', $had->id)->update(['return_visit' => 1]); //跟进后改为待回访状态
  2449. $data['name'] = !empty($data['name']) ? $data['name'] : '';
  2450. $data['phone'] = substr_replace($data['phone'], '******', 3, 6);
  2451. //如果开关开启才发送消息
  2452. if (in_array($param['state'], $dd_state)) {
  2453. // 发送管理层模板消息
  2454. $msg = ['first' => '行为通知', 'keyword1' => '客户确认到店', 'keyword2' => "客户" . $data['name'] . "(" . $data['phone'] . ")确认到店", 'keyword3' => date('Y/m/d'), 'remark' => '请悉知'];
  2455. TmpMsg::sendMsgToLeader($msg, $token['org_id']);
  2456. }
  2457. if ($state == '已签单') {
  2458. // 发送管理层模板消息
  2459. $msg = ['first' => '行为通知', 'keyword1' => '客户签单', 'keyword2' => "客户" . $data['name'] . "(" . $data['phone'] . ")签单", 'keyword3' => date('Y/m/d'), 'remark' => '请悉知'];
  2460. TmpMsg::sendMsgToLeader($msg, $token['org_id']);
  2461. }
  2462. return json(['code' => 0, 'msg' => '跟进成功', 'index' => $index]);
  2463. }
  2464. /**
  2465. * 取消预约 给部门管理员和设计师发送消息提醒
  2466. * 张三取消了客户李四2020年8月1日的量房/到店/到场预约
  2467. */
  2468. public function cancelReservation($data)
  2469. {
  2470. $token = $this->request->token;
  2471. if ($data['return_visit'] == 1) {
  2472. $token['name'] = Employee::where([['id', '=', $data['eid']]])->value('name');
  2473. $eids = Employee::where([['root_id', '=', $token['root_org']], ['org_id', '=', $data['org_id']], ['state', '=', '在职'], ['is_manager', '=', 1], ['uid', '>', 0]])->column('id');
  2474. if ($data['designer_id']) array_push($eids, $data['designer_id']);
  2475. $date = date('Y-m-d', strtotime($data['confirm_date']));
  2476. $date = explode('-', $date);
  2477. $state = str_replace('未', '', $data['state']);
  2478. $msg = $token['name'] . '取消了客户' . $data['name'] . ',于' . $date[0] . '年' . $date[1] . '月' . $date[2] . '日的' . $state;
  2479. $eids = array_unique($eids);
  2480. foreach ($eids as $key => $val) {
  2481. event(new Msg($val, $msg, 'returnVisit', $data['customer_id']));
  2482. }
  2483. return true;
  2484. }
  2485. return false;
  2486. }
  2487. /**
  2488. * 消息提醒
  2489. * eid 客户所属业务员id,
  2490. * org_id 业务员部门id
  2491. * state 跟进状态
  2492. * name 业务员姓名
  2493. * designer_id 设计师id
  2494. * 01、客户邀约提醒管理层和指派的设计师。没指派设计师时,不提醒设计师,提醒管理层去指派设计师。在员工客户里面需要管理层回访的客户红色标签提示。
  2495. * 02、业务员确认客户量房、到店、到场、交定、签单,提醒管理层回访客户。
  2496. * a、管理层点击提醒,进入对应客户详情页面。进行客户跟踪。
  2497. * b、在员工客户里面需要管理层回访的客户红色标签提示。
  2498. * 2022-11-14 发送消息范围修改 ,操作人员和所在部门管理员发消息,同时如果是确认操作要给客户所属业务员及其管理发消息
  2499. */
  2500. public function returnVisit($index = '')
  2501. {
  2502. $data = Cache::get($index);
  2503. if (empty($index) || empty($data)) return true;
  2504. $token = $this->request->token;
  2505. $state1 = CustomerVisitLog::changeState('确认到店', 'chaos');
  2506. $state2 = CustomerVisitLog::changeState('确认量房', 'chaos');
  2507. $state3 = CustomerVisitLog::changeState('确认到场', 'chaos');
  2508. $state4 = CustomerVisitLog::changeState('交定', 'chaos');
  2509. $state5 = CustomerVisitLog::changeState('签单', 'chaos');
  2510. $make_state1 = array_merge($state1, $state2, $state3, $state4, $state5);
  2511. $make_state3 = array_merge($state1, $state2, $state3);
  2512. $state6 = CustomerVisitLog::changeState('预约到店', 'chaos');
  2513. $state7 = CustomerVisitLog::changeState('预约量房', 'chaos');
  2514. $state8 = CustomerVisitLog::changeState('预约活动', 'chaos');
  2515. $make_state2 = array_merge($state6, $state7, $state8);
  2516. //增加馨居尚预约活动见面方式
  2517. $actmeet_type = null;
  2518. //if($token['client_type'] == 'vL0CQQ' && !empty($data['actmeet_type'])){
  2519. if ($token['client_type'] == 'uwlxOU' && !empty($data['actmeet_type'])) {
  2520. if ($data['actmeet_type'] == 1) {
  2521. $actmeet_type = ',见面方式为外场活动';
  2522. } elseif ($data['actmeet_type'] == 2) {
  2523. $actmeet_type = ',见面方式为茶楼见面';
  2524. } elseif ($data['actmeet_type'] == 3) {
  2525. $actmeet_type = ',见面方式为网谈登记';
  2526. }
  2527. }
  2528. if (in_array($data['state'], $make_state2)) {
  2529. // $date = $office_date = date('Y-m-d', strtotime($data['confirm_date']));
  2530. $date = $office_date = date('Y-m-d');
  2531. $state = str_replace('预约', '', $data['state']);
  2532. $msg = $token['name'] . '预约了客户' . $data['name'] . ',预计于' . date('Y-m-d', strtotime($data['confirm_date'])) . $state;
  2533. $msg = !empty($actmeet_type) ? $msg . $actmeet_type : $msg;
  2534. $msg = $data['designer_id'] ? $msg : $msg . ',该客户暂未指派设计师,请及时指派!!!';
  2535. $type = '预约';
  2536. //预约状态发送消息范围 预约状态只给操作人员,操作人员部门经理,(设计师/业务员)发送消息
  2537. $eid_where1[] = ['org_id', '=', $token['org_id']];
  2538. } elseif (in_array($data['state'], $make_state1)) {
  2539. $date = $office_date = date('Y-m-d');
  2540. $state = str_replace('已', '', $data['state']);
  2541. $msg = $token['name'] . '确认客户' . $data['name'] . ',于' . $data['confirm_date'] . $state;
  2542. $msg = !empty($actmeet_type) ? $msg . $actmeet_type : $msg;
  2543. $type = '确认';
  2544. //确认状态发送消息范围 操作业务员和设计师及双方部门经理都要发送
  2545. $org_ids = Employee::where([['id', 'in', [$token['employee_id'], $data['designer_id']]]])->column('org_id');
  2546. $eid_where1[] = ['org_id', 'in', $org_ids];
  2547. } else {
  2548. return false;
  2549. }
  2550. $eid_where1[] = ['is_manager', '=', 1];
  2551. $eid_where1[] = ['state', '=', '在职'];
  2552. $eid_where1[] = ['uid', '>', 0];
  2553. $eid_where1[] = ['root_id', '=', $token['root_org']];
  2554. $eid_where2[] = ['id', 'in', [$data['eid'], $data['designer_id']]];
  2555. $eids = Employee::whereOr([$eid_where1, $eid_where2])->column('id,official_openid');
  2556. $official = array_column($eids, 'official_openid', 'id');
  2557. $eids = array_column($eids, 'id');
  2558. $new_actmeet_type = !empty($actmeet_type) ? trim($actmeet_type, ',') . ',' : '';
  2559. $param = ['name' => $data['name'], 'sale_name' => $token['name'], 'type' => $type, 'state' => $state, 'phone' => $data['phone'], 'date' => $office_date, 'actmeet_type' => $new_actmeet_type];
  2560. //查询公众号信息
  2561. $client_type = Miniprogram::where('root_id', $token['root_org'])->value('notify');
  2562. $param['client_type'] = $client_type;
  2563. $param['make_state2'] = $make_state2;
  2564. $param['eids'] = Employee::where([['root_id', '=', $token['root_org']]])->column('id');
  2565. //
  2566. $count_type = ($type == '确认') ? $make_state3 : $make_state2;
  2567. $param['count'] = CustomerVisitLog::where([['addtime', 'like', '%' . date('Y-m-d') . '%'], ['state', 'in', $count_type], ['employee_id', 'in', $param['eids']]])->count();
  2568. //公众号appid
  2569. $miniAppid = Miniprogram::where('root_id', $token['root_org'])->find()->appid;
  2570. foreach ($eids as $key => $val) {
  2571. event(new Msg($val, $msg, 'returnVisit', $data['customer_id']));
  2572. $param['count'] += 1;
  2573. if (!empty($official[$val])) {
  2574. //公众号消息
  2575. $param['employee_id'] = $val;
  2576. $param['cid'] = $data['customer_id'];
  2577. $param['official_openid'] = $official[$val];
  2578. $param['miniAppid'] = $miniAppid;
  2579. $this->sendOfficialAccount($param);
  2580. }
  2581. }
  2582. return true;
  2583. }
  2584. /**
  2585. * 发送公众号消息
  2586. * $data['name'] 客户姓名
  2587. * $data['type'] 预约/确认
  2588. * $data['state'] 到店,量房,到场
  2589. * $data['phone'] 客户电话
  2590. * $data['sale_name'] 业务员姓名
  2591. * $data['employee_id] 业务员id
  2592. * $data['date'] 日期
  2593. */
  2594. public function sendOfficialAccount($data)
  2595. {
  2596. if (in_array($data['state'], ['交定', '签单'])) return true;
  2597. $token = $this->request->token;
  2598. $dates = date('Ymd', strtotime($data['date']));
  2599. // $client_type = Miniprogram::where('root_id', $token['root_org'])->value('notify');
  2600. $client_type = $data['client_type'];
  2601. $number = $dates . $data['count'];
  2602. $data['page'] = "/pages/index/index?office_type=cread&cid=" . $data['cid'] . '&clientype=' . $client_type;
  2603. if ($data['type'] == '预约') {
  2604. $data['param'] = [
  2605. 'first' => '预约提醒', //标题
  2606. 'keyword1' => $number, //预约编号
  2607. 'keyword2' => $data['type'] . $data['name'] . $data['state'], //预约项目
  2608. 'keyword3' => $data['date'], //预约时间
  2609. 'keyword4' => substr_replace($data['phone'], '******', 3, 6),
  2610. 'keyword5' => $data['name'], //预约姓名
  2611. 'remark' => '您好,业务员' . $data['sale_name'] . '新增一次预约记录,' . $data['actmeet_type'] . '请及时回访' //电话
  2612. ];
  2613. } elseif ($data['type'] == '确认') {
  2614. $data['param'] = [
  2615. 'first' => '确认提醒', //标题
  2616. 'keyword1' => $number, //预约编号
  2617. 'keyword2' => $data['type'] . $data['name'] . $data['state'], //预约项目
  2618. 'keyword3' => $data['date'], //预约时间
  2619. 'keyword4' => substr_replace($data['phone'], '******', 3, 6), //预约电话
  2620. 'keyword5' => $data['name'], //预约姓名
  2621. 'remark' => '您好,业务员' . $data['sale_name'] . '确认' . $data['name'] . $data['state'] . ',' . $data['actmeet_type'] . '请及时回访' //电话
  2622. ];
  2623. }
  2624. $msg = [
  2625. 'type' => 'returnVisit',
  2626. 'employee_id' => $data['employee_id'],
  2627. 'official_openid' => $data['official_openid'],
  2628. 'root_id' => $token['root_org'],
  2629. 'miniAppid' => $data['miniAppid']
  2630. ];
  2631. EmployeeMsg::temploateMsg($msg, $data);
  2632. return true;
  2633. }
  2634. /**
  2635. * 计算业绩任务
  2636. * 2023/8/7 业绩算在客户所属人身上
  2637. */
  2638. public function preformance_tasks($state, $customer_id, $money = 0, $vislog_id)
  2639. {
  2640. $token = request()->token;
  2641. $customer = Customer::find($customer_id);
  2642. $org_id = Employee::where('id', $customer['employee_id'])->value('org_id');
  2643. if ($state == '已交定') {
  2644. $w2[] = ['customer_id', '=', $customer_id];
  2645. $w2[] = ['state', 'in', CustomerVisitLog::changeState('已交定', 'chaos')];
  2646. $w2[] = ['customer_employee_id', '=', $customer['employee_id']];
  2647. $w2[] = ['customer_org_id', '=', $org_id];
  2648. //切换部门重复交定仍然算业绩
  2649. $check = CustomerVisitLog::where($w2)->count(); //没有交定过计算业绩
  2650. if ($check == 1) {
  2651. $time = date('Y-m-d H:i:s');
  2652. //查询进行中的指派到所属部门的所有进度
  2653. // $w[] = ['org_id','=',$token['org_id']];
  2654. $w[] = ['root_id', '=', $token['root_org']];
  2655. $w[] = ['start_date', '<=', $time];
  2656. $w[] = ['end_date', '>=', $time];
  2657. $w[] = ['is_deposit', '=', 1];
  2658. $preformance_tasks = PreformanceTasksModel::where($w)->column('id');
  2659. $w1[] = ['root_id', '=', $token['root_org']];
  2660. $w1[] = ['org_id', '=', $org_id];
  2661. $w1[] = ['performance_tasks_id', 'in', $preformance_tasks];
  2662. $w1[] = ['is_deposit', '=', 1];
  2663. //指派到自己部门
  2664. $pid = PreformanceTasksOrg::where($w1)->group('performance_tasks_id')->column('*');
  2665. $w4[] = ['id', 'in', array_column($pid, 'performance_tasks_id')];
  2666. $model = PreformanceTasksModel::where($w4)->column('*');
  2667. foreach ($model as $k => $v) {
  2668. $u = [];
  2669. $u['ok_deposit'] = $v['ok_deposit'] + 1;
  2670. $u['customer_visit_log_id'] = $v['customer_visit_log_id'] ? $v['customer_visit_log_id'] . ',' . $vislog_id : $vislog_id;
  2671. PreformanceTasksModel::where('id', $v['id'])->update($u);
  2672. unset($u);
  2673. }
  2674. PreformanceTasksOrg::where($w1)->inc('ok_deposit')->update();
  2675. }
  2676. } elseif ($state == '已签单') {
  2677. $w2[] = ['customer_id', '=', $customer_id];
  2678. $w2[] = ['state', 'in', CustomerVisitLog::changeState('已签单', 'chaos')];
  2679. $w2[] = ['customer_employee_id', '=', $customer['employee_id']];
  2680. $check = CustomerVisitLog::where($w2)->count(); //没有交定过计算业绩
  2681. if ($check == 1) {
  2682. $time = date('Y-m-d H:i:s');
  2683. //查询进行中的指派到所属部门的所有进度
  2684. // $w[] = ['org_id','=',$token['org_id']];
  2685. $w[] = ['root_id', '=', $token['root_org']];
  2686. $w[] = ['start_date', '<=', $time];
  2687. $w[] = ['end_date', '>=', $time];
  2688. $w[] = ['is_money', '=', 1];
  2689. $preformance_tasks = PreformanceTasksModel::where($w)->column('id');
  2690. $w1[] = ['root_id', '=', $token['root_org']];
  2691. $w1[] = ['org_id', '=', $org_id];
  2692. $w1[] = ['performance_tasks_id', 'in', $preformance_tasks];
  2693. $w1[] = ['is_money', '=', 1];
  2694. //指派到自己部门
  2695. $pid = PreformanceTasksOrg::where($w1)->group('performance_tasks_id')->column('*');
  2696. $w4[] = ['id', 'in', array_column($pid, 'performance_tasks_id')];
  2697. $model = PreformanceTasksModel::where($w4)->column('*');
  2698. foreach ($model as $k => $v) {
  2699. $u = [];
  2700. $u['ok_money'] = $v['ok_money'] + $money;
  2701. $u['customer_visit_log_id'] = $v['customer_visit_log_id'] ? $v['customer_visit_log_id'] . ',' . $vislog_id : $vislog_id;
  2702. PreformanceTasksModel::where('id', $v['id'])->update($u);
  2703. unset($u);
  2704. }
  2705. PreformanceTasksOrg::where($w1)->inc('ok_money', (int) $money)->update();
  2706. }
  2707. }
  2708. return 1;
  2709. }
  2710. /**
  2711. * 没有预约活动,跟进时传了aid和state='预约活动'
  2712. * 没有预约可以直接确认到场
  2713. * 补全数据添加预约和的追踪记录
  2714. */
  2715. public function activityState($param, $had)
  2716. {
  2717. $employeeTypeName = $this->request->token['org_type'] == 2 ? '设计师' : '销售';
  2718. // 备注
  2719. $employeeName = Employee::where(['id' => $this->request->token['employee_id']])->value('name');
  2720. $remark = $param['remark'];
  2721. if (empty($remark)) {
  2722. $remark = $employeeTypeName . $employeeName . '对客户进行了回访';
  2723. }
  2724. //预约记录
  2725. $visitLog = [
  2726. 'customer_id' => $had->id,
  2727. 'type' => $param['type'],
  2728. 'next_contact_date' => !empty($param['next_contact_date']) ? $param['next_contact_date'] : date('Y-m-d'),
  2729. 'employee_id' => $this->request->token['employee_id'],
  2730. 'user_id' => $this->request->token['uid'],
  2731. 'remark' => $remark,
  2732. 'state' => 6,
  2733. 'weixin_media' => '',
  2734. 'media_id' => '',
  2735. 'starts' => $param['starts'],
  2736. 'money' => $param['money'],
  2737. 'confirm_date' => $param['confirm_date'],
  2738. 'org_id' => $this->request->token['org_id'],
  2739. 'aid' => $param['aid'],
  2740. 'weixin_media1' => '',
  2741. 'media_id1' => '',
  2742. 'customer_employee_id' => $had->employee_id,
  2743. 'customer_org_id' => Employee::where('id', $had->employee_id)->value('org_id')
  2744. ];
  2745. CustomerVisitLog::create($visitLog);
  2746. //
  2747. $subscribe = [
  2748. 'customer_id' => $had['id'],
  2749. 'subscribe_date' => $param['confirm_date'],
  2750. 'employee_id' => $had->employee_id,
  2751. 'designer_id' => $had->designer_id,
  2752. 'type' => 2,
  2753. 'aid' => $param['aid'],
  2754. 'org_id' => $visitLog['customer_org_id'],
  2755. 'state' => 1
  2756. ];
  2757. CustomersSubscribe::create($subscribe);
  2758. return 1;
  2759. }
  2760. /**
  2761. * 客户意向折线图
  2762. */
  2763. public function line_chart()
  2764. {
  2765. $customerId = $this->request->param('customer_id');
  2766. $token = $this->request->token;
  2767. $w[] = ['id', '=', $customerId];
  2768. $w[] = ['employee_id', '=', $token['employee_id']];
  2769. $check = Customer::where($w)->findOrEmpty();
  2770. if ($check->isEmpty()) return json(['code' => 0, 'data' => [], 'msg' => '操作成功']);
  2771. $w1[] = ['customer_id', '=', $customerId];
  2772. $w1[] = ['starts', '>', 0];
  2773. $ids = CustomerVisitLog::where($w1)->order('id desc')->limit(30)->column('id');
  2774. $w1[] = ['id', 'in', $ids];
  2775. $row = CustomerVisitLog::where($w1)->order('id asc')->column('starts');
  2776. return json(['code' => 0, 'data' => $row, 'msg' => '操作成功']);
  2777. }
  2778. /**
  2779. * 重新跟踪
  2780. */
  2781. public function transfer()
  2782. {
  2783. $customerId = $this->request->param('customer_id');
  2784. $condition = [
  2785. ['id', '=', $customerId],
  2786. ['state', 'in', Customer::changeState('无效', 'chaos')]
  2787. ];
  2788. $had = Customer::where($condition)->find();
  2789. if (!$had)
  2790. return json(['code' => 0, 'msg' => '添加失败,数据不存在或已被分配,请刷新后再试']);
  2791. $had->state = '未到访';
  2792. // 原客服获取
  2793. $oldEmployeeName = Employee::where([['id', '=', $had->employee_id]])->value('name');
  2794. $param = [
  2795. 'customer_id' => $customerId,
  2796. 'type' => '重新跟踪',
  2797. 'remark' => '公共库提取,重新跟踪, 原客服为:' . $oldEmployeeName,
  2798. 'employee_id' => $this->request->token['employee_id'],
  2799. 'user_id' => $this->request->token['uid'],
  2800. 'state' => '未到访',
  2801. ];
  2802. CustomerVisitLog::create($param);
  2803. $had->employee_id = $this->request->token['employee_id'];
  2804. $had->employee_time = date('Y-m-d H:i:s', time()); //更新员工获取此客户时间
  2805. $had->save();
  2806. // 更新客户保护期
  2807. Customer::changeProtectedTo($customerId, $this->request->token['root_org']);
  2808. return json(['code' => 0, 'msg' => '重新跟踪成功']);
  2809. }
  2810. /**
  2811. * 客户详情
  2812. */
  2813. public function detail()
  2814. {
  2815. $id = $this->request->param('id');
  2816. $share = input('share');
  2817. $token = $this->request->token;
  2818. // 查询自己的客户
  2819. $condition1 = [
  2820. ['employee_id', '=', $this->request->token['employee_id']],
  2821. ['id', '=', $id]
  2822. ];
  2823. $condition2 = [
  2824. ['designer_id', '=', $this->request->token['employee_id']],
  2825. ['id', '=', $id]
  2826. ];
  2827. // 或者查询公司内,无效的客户
  2828. // 公司部门列表获取
  2829. $orgIdsList = Org::where([['path', 'like', $this->request->token['root_org'] . '-%']])->column('id');
  2830. $condition3 = [
  2831. ['id', '=', $id],
  2832. ['org_id', 'in', $orgIdsList],
  2833. ['state', 'in', Customer::changeState('无效', 'chaos')]
  2834. ];
  2835. // 或者是公司领导看员工的客户
  2836. if (isset($this->request->token['isManager']) && $this->request->token['isManager']) {
  2837. $team_orgs = (new Org())->getChildOrg($this->request->token['org_id']);
  2838. if ($this->request->token['org_type'] == 1) {
  2839. $condition4 = [
  2840. ['org_id', 'in', $team_orgs],
  2841. ['id', '=', $id]
  2842. ];
  2843. $orCondition = [$condition1, $condition2, $condition3, $condition4];
  2844. } else {
  2845. $empIdList = Employee::where([['org_id', 'in', $team_orgs]])->column('id');
  2846. $condition4 = [
  2847. ['designer_id', 'in', $empIdList],
  2848. ['id', '=', $id]
  2849. ];
  2850. $condition5 = [
  2851. ['employee_id', 'in', $empIdList],
  2852. ['id', '=', $id]
  2853. ];
  2854. $orCondition = [$condition1, $condition2, $condition3, $condition4, $condition5];
  2855. }
  2856. } else {
  2857. $orCondition = [$condition1, $condition2, $condition3];
  2858. }
  2859. //指派给自己的员工
  2860. $where_or = [['assigned_personnel', 'find in set', $token['employee_id']], ['id', '=', $id]];
  2861. $orCondition[] = $where_or;
  2862. //共有客户管理层查看其他部门的客户
  2863. if ($share && isset($this->request->token['isManager']) && $this->request->token['isManager']) $orCondition[] = [['org_id', 'in', $orgIdsList], ['id', '=', $id]];
  2864. $data = Customer::with(['source', 'designer' => function ($query) {
  2865. $query->field('id,name,headimgurl,org_id,uid');
  2866. }, 'employee' => function ($query) {
  2867. $query->withField(['uid', 'id', 'headimgurl', 'is_manager', 'image_photo', 'is_newbie', 'name', 'nickname', 'org_id', 'position', 'role', 'root_id']);
  2868. }])->whereOr($orCondition)->find();
  2869. if (empty($data)) return json(['code' => 1, 'msg' => '数据权限发生变化,无法查看']);
  2870. // if ($data->aid) {
  2871. // $data->date = CustomerVisitLog::where([['aid', '=', $data->aid], ['customer_id', '=', $id], ['state', '=', $data->state]])->value('next_contact_date') ?: '';
  2872. // } else {
  2873. // $data->date = '';
  2874. // }
  2875. // 获取设计师部门
  2876. if (!empty($data->designer))
  2877. $data->designer->orgName = Org::where(['id' => $data->designer->org_id])->value('name');
  2878. if ($data->employee_id == $this->request->token['employee_id'] && $data->fresh == 1) {
  2879. $data->fresh = 2;
  2880. $data->save();
  2881. }
  2882. $count = CustomerVisitLog::where('customer_id', $id)->count();
  2883. $data['visit_count'] = $count;
  2884. // 首付款
  2885. $data['down_payment'] = CustomerVisitLog::where([['customer_id', '=', $id], CustomerVisitLog::changeState(['state', '=', '签单'])])->order('addtime desc')->value('down_payment');
  2886. $data['deposit'] = CustomerVisitLog::where([['customer_id', '=', $id], CustomerVisitLog::changeState(['state', '=', '交定'])])->order('addtime desc')->value('confirm_date');
  2887. $data['sign'] = CustomerVisitLog::where([['customer_id', '=', $id], CustomerVisitLog::changeState(['state', '=', '签单'])])->order('addtime desc')->value('addtime');
  2888. $data['deposit_mode'] = CustomerVisitLog::where([['customer_id', '=', $id], CustomerVisitLog::changeState(['state', '=', '交定'])])->order('addtime desc')->value('deposit_mode');
  2889. // 量房、活动、到店次数统计
  2890. $data['liangfangNum'] = CustomerVisitLog::where([['customer_id', '=', $id], CustomerVisitLog::changeState(['state', '=', '确认量房'])])->count();
  2891. $data['activityNum'] = CustomerVisitLog::where([['customer_id', '=', $id], CustomerVisitLog::changeState(['state', '=', '确认到场'])])->count();
  2892. $data['daodianNum'] = CustomerVisitLog::where([['customer_id', '=', $id], CustomerVisitLog::changeState(['state', '=', '确认到店'])])->count();
  2893. $data['deposit_count'] = CustomerVisitLog::where([['customer_id', '=', $id], ['state', 'in', CustomerVisitLog::changeState('已交定', 'chaos')]])->count();
  2894. $data['square'] = floatval($data['square']);
  2895. if ($data['employee_id'] != $this->request->token['employee_id'] && (empty($data['designer']) || $data['designer']['id'] != $this->request->token['employee_id'])) $data['editAble'] = false;
  2896. else $data['editAble'] = true;
  2897. // 设计师头像
  2898. if ($data['designer'])
  2899. $data['designer']['headimgurl'] = User::where('id', $data['designer']['uid'])->value('headimgurl');
  2900. // 查询客户是否标星
  2901. $data['addtoptime'] = CustomerTop::where(['customer_id' => $id, 'employee_id' => $this->request->token['employee_id'], 'root_id' => request()->token['root_org']])->value('addtoptime');
  2902. // 查询客户是否有预约
  2903. $data['subscirbe'] = CustomersSubscribe::with(['activity' => function ($query) {
  2904. $query->field('id,title');
  2905. }])->where([['customer_id', '=', $id], ['state', '=', 0]])->field('id,state,type,subscribe_date,aid')->select()->toArray();
  2906. //查询我最近一次的签单和交定金额
  2907. $state = CustomerVisitLog::changeState('已交定', 'chaos');
  2908. $data['deposit_money1'] = CustomerVisitLog::where([['customer_id', '=', $id], ['state', 'in', $state]])->order('id desc')->value('money') ?: 0;
  2909. $data['money'] = $data->getData('signed_money');
  2910. //查询最近一次签单的记录id
  2911. $state = CustomerVisitLog::changeState('已签单', 'chaos');
  2912. $data['vlogid'] = CustomerVisitLog::where([['customer_id', '=', $id], ['state', 'in', $state]])->order('id desc')->value('id') ?: 0;
  2913. // 查询今日发送短信数量
  2914. $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();
  2915. // 如果线索值为空,查询线索表跟本用户手机号一样并员工id一样,进行线索绑定
  2916. if (empty($data['clue_id']) && $data->employee_id == $this->request->token['employee_id']) {
  2917. $clue_data = CustomerClue::where([['employee_id', '=', $this->request->token['employee_id']], ['phone', '=', $data['phone']]])->find();
  2918. if (!empty($clue_data)) {
  2919. $data['clue_id'] = $clue_data['id'];
  2920. $data->clue_id = $clue_data['id'];
  2921. $data->save();
  2922. $clue_data->state = 1;
  2923. $clue_data->save();
  2924. }
  2925. }
  2926. // 企业微信外部联系人
  2927. $external_customer = WeworksingleCustomer::where('customer_id', '=', $id)->findOrEmpty();
  2928. if (!$external_customer->isEmpty()) {
  2929. $data['external_userid'] = $external_customer['external_userid'];
  2930. $data['external_username'] = $external_customer['name'];
  2931. } else {
  2932. $data['external_userid'] = '';
  2933. $data['external_username'] = '';
  2934. }
  2935. //业务员头像
  2936. if (!empty($data['employee']) && !$data['employee']['headimgurl'])
  2937. $data['employee']['headimgurl'] = User::where('id', $data['employee']['uid'])->value('headimgurl');
  2938. //指派人员头像
  2939. if ($data->assigned_personnel) {
  2940. $assigned_personnel = explode(',', $data->assigned_personnel);
  2941. $assigned_business = array_diff($assigned_personnel, [$data['designer_id']]);
  2942. $assigned_employee = Employee::with(['org', 'user'])->where('id', 'in', $assigned_business)->select()->toArray();
  2943. $assigned_employee_list = [];
  2944. foreach ($assigned_employee as $ass) {
  2945. $assigned_employee_list[] = [
  2946. 'name' => $ass['name'],
  2947. 'headimgurl' => !empty($ass['user']) ? $ass['user']['headimgurl'] : '',
  2948. 'orgName' => !empty($ass['org']) ? $ass['org']['name'] : ''
  2949. ];
  2950. }
  2951. $data['assigned_personnel_list'] = $assigned_employee_list;
  2952. $uids = Employee::where([['id', 'in', $data->assigned_personnel]])->column('uid');
  2953. $data['assigned_personnel_imgs'] = User::where([['id', 'in', $uids]])->column('headimgurl');
  2954. } else {
  2955. $data['assigned_personnel_imgs'] = [];
  2956. $data['assigned_personnel_list'] = [];
  2957. }
  2958. //2022-11-09 增加业务逻辑 在团队客户中高层和中高层领导不可以回访和跟进 ,只有基层领导可以
  2959. if (!$token['isManager']) {
  2960. $data['is_manager'] = 0;
  2961. } else {
  2962. //判断是否是基层领导 , 最底层部门的管理员
  2963. $child = Org::where('pid', $token['org_id'])->field('id')->findOrEmpty();
  2964. $data['is_manager'] = $child->isEmpty() ? 1 : 0;
  2965. }
  2966. // 有效申请
  2967. // 申请配置
  2968. $settingObj = Setting::where(['root_id' => $this->request->token['root_org'], 'name' => 'valid_check_person'])->find();
  2969. if ($settingObj) {
  2970. $setting = explode(',', $settingObj['content']);
  2971. if (in_array('xiaoshou', $setting) && $data['employee_id'] == $this->request->token['employee_id']) {
  2972. $data['valid_check'] = true;
  2973. } elseif (in_array('sheji', $setting) && $data['designer_id'] == $this->request->token['employee_id']) {
  2974. $data['valid_check'] = true;
  2975. } else {
  2976. $data['valid_check'] = false;
  2977. }
  2978. // 检测是否已经提交
  2979. $check = CustomerStateCheck::where(['customer_id' => $id, 'root_id' => $this->request->token['root_org']])->find();
  2980. if ($check) $data['check_state'] = $check->check_state;
  2981. else $data['check_state'] = -1;
  2982. } else {
  2983. $data['valid_check'] = false;
  2984. }
  2985. return json(['code' => 0, 'data' => $data]);
  2986. }
  2987. /**
  2988. * 判断客户业务员是否重复
  2989. *
  2990. */
  2991. public function checkRepeat()
  2992. {
  2993. $param = $this->request->param(['customer_id' => 0, 'employee_id' => 0]);
  2994. $phone = Customer::where('employee_id', $param['employee_id'])->column('phone,phone1,phone2');
  2995. $c_phone = Customer::where('id', $param['customer_id'])->column('phone,phone1,phone2');
  2996. if (empty($phone) || empty($c_phone)) return json(['code' => 0, 'data' => 1]);
  2997. $phones = [];
  2998. foreach ($phone as $v) {
  2999. $phones = array_merge($phones, array_values($v));
  3000. }
  3001. $phones = array_filter($phones);
  3002. $res = array_intersect($phones, array_filter($c_phone[0]));
  3003. return json(['code' => 0, 'data' => $res ? 0 : 1]);
  3004. }
  3005. /**
  3006. * 房源信息
  3007. */
  3008. public function house()
  3009. {
  3010. $id = $this->request->param('id');
  3011. $condition = [
  3012. ['id', '=', $id],
  3013. ['employee_id', '=', $this->request->token['employee_id']]
  3014. ];
  3015. Db::startTrans();
  3016. try {
  3017. $customer = Customer::where($condition)->lock(true)->find();
  3018. if (empty($customer)) return json(['code' => 1, 'msg' => '数据不存在']);
  3019. $param = request()->only(['community', 'area', 'house_type', 'delivery_time', 'estimate_date', 'budget', 'style', 'house_status']);
  3020. $data = [
  3021. 'community_name' => $param['community'],
  3022. 'square' => $param['area'],
  3023. 'house_type' => $param['house_type'],
  3024. 'house_status' => $param['house_status'],
  3025. 'house_delivery_time' => $param['delivery_time'],
  3026. 'plan_deco_time' => $param['estimate_date'],
  3027. 'budget' => $param['budget'],
  3028. 'deco_style' => $param['style']
  3029. ];
  3030. $data = array_filter($data);
  3031. if (empty($data))
  3032. return json(['code' => 1, 'msg' => '请输入要保存的信息']);
  3033. $customer->save($data);
  3034. Db::commit();
  3035. } catch (Exception $e) {
  3036. // 回滚事务
  3037. Db::rollback();
  3038. return json(['code' => 1, 'msg' => $e->getMessage()]);
  3039. }
  3040. return json(['code' => 0, 'msg' => '保存成功']);
  3041. }
  3042. public function forhouseinfo()
  3043. {
  3044. $communities = Community::field('id,name')->where([['root_id', '=', request()->token['root_org']], ['type', '=', 0]])->select();
  3045. $decostyles = Decostyle::field('id,name')->where([['root_id', '=', request()->token['root_org']], ['type', '=', 0]])->select();
  3046. $data = [
  3047. 'communities' => $communities,
  3048. 'decostyles' => $decostyles
  3049. ];
  3050. return json(['code' => 0, 'msg' => '获取成功', 'data' => $data]);
  3051. }
  3052. public function invalidCustomer()
  3053. {
  3054. $request = request();
  3055. $param = $request->param();
  3056. $customer_id = $param['customer_id'];
  3057. $employee_id = $this->request->token['employee_id'];
  3058. $tracking = new CustomerVisitLog();
  3059. $data = [
  3060. 'customer_id' => $customer_id,
  3061. 'employee_id' => $employee_id,
  3062. 'state' => '无效'
  3063. ];
  3064. $tracking->save($data);
  3065. //
  3066. if (Customer::where('id', $customer_id)->update(['state' => 7, 'employee_id' => NULL, 'is_resource' => 0])) {
  3067. return json(['code' => 0, 'msg' => '无效成功']);
  3068. } else {
  3069. return json(['code' => 1, 'msg' => '无效失败']);
  3070. }
  3071. }
  3072. ////////////
  3073. /// 资源库
  3074. ////////////
  3075. public function resource_log_list()
  3076. {
  3077. $request = request();
  3078. $root_id = request()->token['root_org'];
  3079. $subOrg = orgSubIds($root_id);
  3080. $param = $request->only(['page', 'limit', 'org_id']);
  3081. if (!in_array($param['org_id'], $subOrg)) {
  3082. return json(['code' => 0, 'data' => [], 'count' => 0]);
  3083. }
  3084. $data = CrmImportLog::where('org_id', $param['org_id'])->with('employee')->page($param['page'])->limit($param['limit'])->order('addtime', 'desc')->select();
  3085. $count = CrmImportLog::where('org_id', $param['org_id'])->count();
  3086. return json(['code' => 0, 'data' => $data, 'count' => $count]);
  3087. }
  3088. public function resourcepool()
  3089. {
  3090. $request = request();
  3091. $param = $request->only(['page', 'limit', 'order', 'cilid']);
  3092. $condition = [];
  3093. $order = isset($param['order']) ? $param['order'] : 'id desc';
  3094. $condition[] = ['employee_id', '=', NULL];
  3095. $condition[] = ['is_resource', '=', 1];
  3096. $condition[] = ['crm_res_id', '=', $param['cilid']];
  3097. $condition[] = ['bad_phone', '=', 0];
  3098. $root_id = request()->token['root_org'];
  3099. $subOrg = orgSubIds($root_id);
  3100. $condition[] = ['org_id', 'in', $subOrg];
  3101. $data = CustomerLogic::resourcelist($condition, $param['page'], $param['limit'], $order);
  3102. $count = CustomerLogic::count($condition);
  3103. return json(['code' => 0, 'data' => $data, 'count' => $count]);
  3104. }
  3105. public function employee4resource($org)
  3106. {
  3107. $param['page'] = input('page', 1);
  3108. $param['limit'] = input('limit', 1000000);
  3109. $employee = EmployeeLogic::employeelist4resource($org, [], $param['page'], $param['limit']);
  3110. return json(['code' => 0, 'data' => $employee]);
  3111. }
  3112. public function subnodes()
  3113. {
  3114. $request = request();
  3115. $param = $request->param();
  3116. //$nodes = OrgLogic::subnodes($param['org']);
  3117. $nodes = OrgLogic::subfirstlevelnodes($param['org']);
  3118. return json(['code' => 0, 'data' => $nodes, 'msg' => '获取成功']);
  3119. }
  3120. ///
  3121. public function subnodeswithempnum()
  3122. {
  3123. $request = request();
  3124. $param = $request->param();
  3125. $nodes = OrgLogic::subfirstlevelnodeswithempnum($param['org']);
  3126. return json(['code' => 0, 'data' => $nodes, 'msg' => '获取成功']);
  3127. }
  3128. public function resdistributing()
  3129. {
  3130. $request = request();
  3131. $param = $request->param();
  3132. $token = $this->request->token;
  3133. $target_customer_ids_arr = explode(',', $param['targets']);
  3134. $root_id = request()->token['root_org'];
  3135. $subOrg = orgSubIds($root_id);
  3136. $target_customer_ids_arr = Customer::where([['id', 'in', $target_customer_ids_arr], ['org_id', 'in', $subOrg]])->column('id');
  3137. $using_num = count($target_customer_ids_arr);
  3138. Db::startTrans();
  3139. $repeat = 0; //重复phone
  3140. if ($param['type'] == 'toemp' && isset($param['emp_id'])) {
  3141. $employee_id = $param['emp_id'];
  3142. $emp_obj = Employee::find($employee_id);
  3143. $org_id = $emp_obj->org_id;
  3144. // 设计师能否报备、获取客户
  3145. $de_where[] = ['root_id', '=', $root_id];
  3146. $de_where[] = ['name', '=', 'designer_get_customer'];
  3147. $info_de_where = Setting::where($de_where)->findOrEmpty();
  3148. $org_type = Org::where('id', '=', $org_id)->value('org_type');
  3149. if (!$info_de_where->isEmpty() && $org_type == 2) {
  3150. if ((int)$info_de_where['content'] != 1) {
  3151. return json(['code' => 1, 'msg' => '无法分配给设计师']);
  3152. }
  3153. }
  3154. $is_source = 0;
  3155. //2022-10-16 逻辑修改重复录入客户表有重复手机号,手动分配需要去重
  3156. $customers = Customer::where([['id', 'in', $target_customer_ids_arr]])->column('id,phone,phone1,phone2');
  3157. $phone = Customer::where('employee_id', $employee_id)->column('phone,phone1,phone2');
  3158. $phones = [];
  3159. foreach ($phone as $v) {
  3160. $phones = array_merge($phones, array_values($v));
  3161. }
  3162. $phones = array_filter($phones);
  3163. $cids = [];
  3164. foreach ($customers as $v2) {
  3165. $l_phone = array_filter([$v2['phone'], $v2['phone1'], $v2['phone2']]);
  3166. if (empty(array_intersect($l_phone, $phones))) {
  3167. $cids[] = $v2['id'];
  3168. } else {
  3169. $repeat += 1;
  3170. }
  3171. }
  3172. $using_num -= $repeat;
  3173. if ($cids) {
  3174. Customer::where([['id', 'in', $cids]])->update([
  3175. 'employee_id' => $employee_id,
  3176. 'org_id' => $org_id,
  3177. 'is_resource' => $is_source,
  3178. 'ext->ext6' => '',
  3179. 'designer_id' => NULL,
  3180. 'employee_time' => date('Y-m-d H:i:s', time()),
  3181. 'is_distribution' => 1
  3182. ]);
  3183. Customer::changeProtectedTo($cids, $this->request->token['root_org']);
  3184. // $this->sendOfficialAccount([$employee_id => count($cids)]);
  3185. //添加一条跟进记录
  3186. $visitlog = [];
  3187. foreach ($cids as $val) {
  3188. $visitlog[] = [
  3189. 'customer_id' => $val,
  3190. 'type' => 1,
  3191. 'remark' => '资源库分配',
  3192. 'employee_id' => $token['employee_id'],
  3193. 'user_id' => $token['uid'],
  3194. 'state' => '待确认'
  3195. ];
  3196. }
  3197. CustomerVisitLog::insertAll($visitlog);
  3198. }
  3199. // $employee_id = $param['emp_id'];
  3200. // $emp_obj = Employee::find($employee_id);
  3201. // $org_id = $emp_obj->org_id;
  3202. // $is_source = 0;
  3203. // foreach ($target_customer_ids_arr as $item_id) {
  3204. // Customer::where(['id' => (int)$item_id])->update([
  3205. // 'employee_id' => $employee_id,
  3206. // 'org_id' => $org_id,
  3207. // 'is_resource' => $is_source,
  3208. // 'ext->ext6' => '',
  3209. // 'designer_id' => null,
  3210. // 'employee_time' => date('Y-m-d H:i:s', time()) //更新员工获取客户时间
  3211. // ]);
  3212. // }
  3213. // // 更新客户保护期
  3214. // Customer::changeProtectedTo($target_customer_ids_arr, $this->request->token['root_org']);
  3215. } else {
  3216. $employee_id = null;
  3217. $aimed_org = Org::find($param['org_pool']);
  3218. $org_id = $aimed_org->id;
  3219. $is_source = 1;
  3220. foreach ($target_customer_ids_arr as $item_id) {
  3221. Customer::where(['id' => (int)$item_id])->update([
  3222. 'employee_id' => $employee_id,
  3223. 'org_id' => $org_id,
  3224. 'is_resource' => $is_source
  3225. ]);
  3226. }
  3227. //build log
  3228. $metaLog = CrmImportLog::find($param['cilid']);
  3229. $newlog = new CrmImportLog();
  3230. $newdata = [
  3231. 'pid' => $metaLog->id,
  3232. 'employee_id' => $metaLog->employee_id,
  3233. 'org_id' => $org_id,
  3234. 'name' => $metaLog->name,
  3235. 'count' => $using_num,
  3236. 'state' => 0,
  3237. 'left_num' => $using_num
  3238. ];
  3239. $newlog->save($newdata);
  3240. ///
  3241. Customer::where(['crm_res_id' => $param['cilid'], 'org_id' => $org_id])->update(['crm_res_id' => $newlog->id]);
  3242. }
  3243. ///
  3244. $leftNum = CrmImportLog::where('id', $param['cilid'])->column('left_num');
  3245. $newleftNum = ($leftNum[0] - $using_num) > 0 ? $leftNum[0] - $using_num : 0;
  3246. if (CrmImportLog::where('id', $param['cilid'])->update(['state' => 1, 'left_num' => $newleftNum]) !== false) {
  3247. Db::commit();
  3248. $result = $repeat ? ['code' => 1, 'msg' => '有' . $repeat . '条客户手机号是重复数据,无法分配'] : ['code' => 0, 'msg' => '操作成功'];
  3249. return json($result);
  3250. } else {
  3251. Db::rollback();
  3252. return json(['code' => 1, 'msg' => '操作失败']);
  3253. }
  3254. }
  3255. public function patchdistributing()
  3256. {
  3257. $token = $this->request->token;
  3258. $request = request();
  3259. $param = $request->param();
  3260. //$target_ids_arr = json_decode($param['targets'],true);
  3261. $target_ids_arr = explode(',', $param['targets']);
  3262. $resource = Customer::where(['crm_res_id' => $param['cilid'], 'bad_phone' => 0])->select()->toArray();
  3263. $timesNum = floor(count($resource) / count($target_ids_arr));
  3264. $leftNum = count($resource) % count($target_ids_arr);
  3265. $root_id = $request->token['root_org'];
  3266. $repeat = [];
  3267. Db::startTrans();
  3268. if ($param['type'] == 'topool') {
  3269. $customer_data = [];
  3270. for ($i = 0; $i < count($target_ids_arr); $i++) {
  3271. for ($t = 0; $t < $timesNum; $t++) {
  3272. unset($customer_data_once);
  3273. $customer_data_once['id'] = $resource[$i + $t * count($target_ids_arr)]['id'];
  3274. $customer_data_once['employee_id'] = NULL;
  3275. $customer_data_once['org_id'] = $target_ids_arr[$i];
  3276. $customer_data_once['is_resource'] = 1;
  3277. $customer_data[] = $customer_data_once;
  3278. }
  3279. }
  3280. (new Customer())->saveAll($customer_data);
  3281. ///build log
  3282. $metaLog = CrmImportLog::find($param['cilid']);
  3283. foreach ($target_ids_arr as $item) {
  3284. $newlog = new CrmImportLog();
  3285. $newdata = [
  3286. 'pid' => $metaLog->id,
  3287. 'employee_id' => $metaLog->employee_id,
  3288. 'org_id' => $item,
  3289. 'name' => $metaLog->name,
  3290. 'count' => $timesNum,
  3291. 'state' => 0,
  3292. 'left_num' => $timesNum
  3293. ];
  3294. $newlog->save($newdata);
  3295. ///
  3296. Customer::where(['crm_res_id' => $param['cilid'], 'org_id' => $item])->update(['crm_res_id' => $newlog->id, 'is_distribution' => 1]);
  3297. }
  3298. }
  3299. if ($param['type'] == 'toemp') {
  3300. // 设计师能否报备、获取客户
  3301. $de_where[] = ['root_id', '=', $root_id];
  3302. $de_where[] = ['name', '=', 'designer_get_customer'];
  3303. $info_de_where = Setting::where($de_where)->findOrEmpty();
  3304. $employee_org_ids = Employee::where('id', 'in', $target_ids_arr)->column('org_id');
  3305. $org_type = Org::where('id', 'in', $employee_org_ids)->column('org_type');
  3306. if (!$info_de_where->isEmpty() && in_array(2, $org_type)) {
  3307. if ((int)$info_de_where['content'] != 1) {
  3308. return json(['code' => 1, 'msg' => '无法分配给设计师']);
  3309. }
  3310. }
  3311. //2023-02-18 待分配的业务员
  3312. $employees = Employee::where([['id', 'in', $target_ids_arr]])->column('org_id', 'id');
  3313. //待分配的客户 //只分配,后台分配到我部门下的客户资源
  3314. $customers = Customer::where([['crm_res_id', '=', $param['cilid']], ['bad_phone', '=', 0], ['employee_id', '=', NULL], ['org_id', '=', $token['org_id']], ['is_distribution', '=', 1]])->column('id'); //要分配的所有客户
  3315. //每人分得客户数量
  3316. $count = ceil(count($customers) / count($employees));
  3317. $arr = [];
  3318. foreach ($employees as $kx => $vx) {
  3319. $where = [];
  3320. $where = [
  3321. ['crm_res_id', '=', $param['cilid']],
  3322. ['bad_phone', '=', 0],
  3323. ['employee_id', '=', NULL],
  3324. ['org_id', '=', $token['org_id']],
  3325. ['is_distribution', '=', 1]
  3326. ];
  3327. //已有手机号列表
  3328. $phone = Customer::where([['employee_id', '=', $kx]])->column('phone,phone1,phone2');
  3329. $phones = [];
  3330. foreach ($phone as $kx1 => $vx2) {
  3331. $lxs_phone = array_filter([$vx2['phone'], $vx2['phone1'], $vx2['phone2']]);
  3332. $phones = array_merge($phones, $lxs_phone);
  3333. }
  3334. //手机号去重
  3335. if ($phones) $where[] = ['phone&phone1&phone2', 'not in', $phones];
  3336. $cids = Customer::where($where)->limit($count)->column('id');
  3337. Customer::where([['id', 'in', $cids]])->update([
  3338. 'employee_id' => $kx,
  3339. 'org_id' => $vx,
  3340. 'is_resource' => 0,
  3341. 'ext->ext6' => '',
  3342. 'designer_id' => NULL,
  3343. 'employee_time' => date('Y-m-d H:i:s', time()),
  3344. 'is_distribution' => 1
  3345. ]);
  3346. $arr[$kx] = $cids;
  3347. }
  3348. if ($arr) {
  3349. $visitlog = [];
  3350. //分配客户
  3351. $send = []; //发送公众号消息数组
  3352. foreach ($arr as $k4 => $v4) {
  3353. // 更新客户保护期
  3354. Customer::changeProtectedTo($v4, $token['root_org']);
  3355. $send[$k4] = count($v4);
  3356. //添加一条跟进记录
  3357. foreach ($v4 as $val) {
  3358. $visitlog[] = [
  3359. 'customer_id' => $val,
  3360. 'type' => 1,
  3361. 'remark' => '资源库分配',
  3362. 'employee_id' => $token['employee_id'],
  3363. 'user_id' => $token['uid'],
  3364. 'state' => '待确认'
  3365. ];
  3366. }
  3367. }
  3368. if ($visitlog) CustomerVisitLog::insertAll($visitlog);
  3369. // $this->sendOfficialAccount($send);
  3370. }
  3371. //剩余没有分配的人员
  3372. $repeat = Customer::where([['crm_res_id', '=', $param['cilid']], ['bad_phone', '=', 0], ['employee_id', '=', NULL]])->column('id');
  3373. $leftNum = count($repeat);
  3374. }
  3375. if ($param['type'] == 'toinstitue') {
  3376. $resource = Customer::where(['crm_res_id' => $param['cilid'], 'bad_phone' => 0])->select()->toArray();
  3377. $resourceNum = count($resource);
  3378. $leftNum = count($resource);
  3379. $sumedempnum = 0;
  3380. $empnumarr = [];
  3381. foreach ($target_ids_arr as $targtid) {
  3382. $orgids = orgSubIds($targtid);
  3383. $allempnum = Employee::where([['org_id', 'in', $orgids]])->count();
  3384. if ($allempnum == 0) {
  3385. return json(['code' => 1, 'msg' => '有机构人员为0,操作失败']);
  3386. }
  3387. $sumedempnum += $allempnum;
  3388. $empnumarr[$targtid] = $allempnum;
  3389. }
  3390. if ($sumedempnum == 0) {
  3391. return json(['code' => 1, 'msg' => '人员为0,操作失败']);
  3392. }
  3393. $data_arr = [];
  3394. foreach ($target_ids_arr as $targtid) {
  3395. unset($data_arr_once);
  3396. $data_arr_once['key'] = $targtid;
  3397. $data_arr_once['val'] = floor($resourceNum * ($empnumarr[$targtid] / $sumedempnum));
  3398. $data_arr[] = $data_arr_once;
  3399. }
  3400. /*foreach ($target_ids_arr as $targtid) {
  3401. $target_arr['_keys'][] = $targtid;
  3402. $target_arr['_vals'][] = floor($resourceNum * ($empnumarr[$targtid] / $sumedempnum));
  3403. }
  3404. //var_dump($target_arr['_keys']);
  3405. //var_dump($target_arr['_vals']);
  3406. $data_arr = [];
  3407. for ($i = 0; $i < count($target_arr['_keys']); $i++) {
  3408. $data_arr[$i] = [
  3409. 'key' => $target_arr['_keys'][$i],
  3410. 'val' => $target_arr['_vals'][$i]
  3411. ];
  3412. }*/
  3413. //
  3414. $starter = 0;
  3415. $customer_data = [];
  3416. for ($k = 0; $k < count($data_arr); $k++) {
  3417. $leftNum -= $data_arr[$k]['val'];
  3418. if ($k > 0) {
  3419. $starter += $k * $data_arr[$k - 1]['val'];
  3420. }
  3421. for ($n = $starter; $n < $starter + $data_arr[$k]['val']; $n++) {
  3422. unset($customer_data_once);
  3423. $customer_data_once['id'] = $resource[$n]['id'];
  3424. $customer_data_once['employee_id'] = NULL;
  3425. $customer_data_once['org_id'] = $data_arr[$k]['key'];
  3426. $customer_data_once['is_resource'] = 1;
  3427. $customer_data[] = $customer_data_once;
  3428. /*$updatedata = [
  3429. 'employee_id' => null,
  3430. 'org_id' => $data_arr[$k]['key'],
  3431. 'is_resource' => 1
  3432. ];
  3433. Customer::where('id', $resource[$n]['id'])->update($updatedata);*/
  3434. }
  3435. }
  3436. (new Customer())->saveAll($customer_data);
  3437. ///build log
  3438. $metaLog = CrmImportLog::find($param['cilid']);
  3439. foreach ($data_arr as $item) {
  3440. $newlog = new CrmImportLog();
  3441. $newdata = [
  3442. 'pid' => $metaLog->id,
  3443. 'employee_id' => $metaLog->employee_id,
  3444. 'org_id' => $item['key'],
  3445. 'name' => $metaLog->name,
  3446. 'count' => $item['val'],
  3447. 'state' => 0,
  3448. 'left_num' => $item['val']
  3449. ];
  3450. $newlog->save($newdata);
  3451. ///
  3452. Customer::where(['crm_res_id' => $param['cilid'], 'org_id' => $item['key']])->update(['crm_res_id' => $newlog->id, 'is_distribution' => 1]);
  3453. }
  3454. }
  3455. if (CrmImportLog::where('id', '=', $param['cilid'])->update(['state' => 1, 'left_num' => $leftNum > 0 ? $leftNum : 0]) !== false) {
  3456. Db::commit();
  3457. $result = $repeat ? ['code' => 1, 'msg' => '有' . count($repeat) . '条客户手机号是重复数据,无法分配'] : ['code' => 0, 'msg' => '操作成功'];
  3458. return json($result);
  3459. } else {
  3460. Db::rollback();
  3461. return json(['code' => 1, 'msg' => '操作失败']);
  3462. }
  3463. }
  3464. public function cil_detail()
  3465. {
  3466. $request = request();
  3467. $param = $request->param();
  3468. $emparr = [];
  3469. $resource = Customer::where([
  3470. ['crm_res_id', '=', $param['cilid']],
  3471. ['employee_id', 'not null', '']
  3472. ])->select()->toArray();
  3473. $eids = array_unique(array_column($resource, 'employee_id'));
  3474. $emps = Employee::with(['user' => function ($query) {
  3475. $query->field('headimgurl,id')->bind(['headimgurl' => 'headimgurl']);
  3476. }])->where([['id', 'in', $eids]])->field('id,name,uid')->select()->toArray();
  3477. $name = array_column($emps, 'name', 'id');
  3478. $headimgurl = array_column($emps, 'headimgurl', 'id');
  3479. $count = Customer::where([['crm_res_id', '=', $param['cilid']], ['employee_id', 'not null', '']])->group('employee_id')->column('count(id)', 'employee_id');
  3480. foreach ($resource as $customer) {
  3481. // $emp = Employee::with('user')->find($customer['employee_id']);
  3482. // $count = Customer::where([['crm_res_id', '=', $param['cilid']], ['employee_id', '=', $customer['employee_id']]])->count();
  3483. $id = $customer['employee_id'];
  3484. $emparr[$id] = [
  3485. 'name' => isset($name[$id]) ? $name[$id] : '',
  3486. 'headimgurl' => isset($headimgurl[$id]) ? $headimgurl[$id] : '',
  3487. 'count' => isset($count[$id]) ? $count[$id] : 0,
  3488. 'employee_id' => $id
  3489. ];
  3490. }
  3491. $emparrval = array_values($emparr);
  3492. ////
  3493. $logs = CrmImportLog::where('pid', $param['cilid'])->select();
  3494. $resourcePoolNodes = [];
  3495. foreach ($logs as $item) {
  3496. $orgob = Org::find($item['org_id']);
  3497. $resourcePoolNodes[] = ['name' => $orgob->info, 'count' => $item['count'], 'org_id' => $item['org_id']];
  3498. }
  3499. $data = [
  3500. 'respool' => $resourcePoolNodes,
  3501. 'emp' => $emparrval
  3502. ];
  3503. return json(['code' => 0, 'data' => $data, 'msg' => '操作成功', 'crm_res_id' => $param['cilid']]);
  3504. }
  3505. ///////////
  3506. /// 公海
  3507. ///////////
  3508. public function pool()
  3509. {
  3510. $request = request();
  3511. $param = $request->only(['page' => 1, 'limit' => 20, 'order', 'org', 'keyword', 'state', 'date' => '']);
  3512. $condition = [];
  3513. $order = isset($param['order']) ? $param['order'] : 'id desc';
  3514. $condition[] = ['employee_id', '=', NULL];
  3515. $condition[] = ['is_resource', '=', 0];
  3516. $org_id = $request->token['org_id'];
  3517. $subOrg = orgSubIds($org_id);
  3518. if (isset($param['org']) && in_array($param['org'], $subOrg)) {
  3519. $condition[] = ['org_id', '=', $param['org']];
  3520. } else {
  3521. $condition[] = ['org_id', 'in', $subOrg];
  3522. }
  3523. if (isset($param['keyword']) && $param['keyword']) {
  3524. $condition[] = ['name|community_name', 'like', '%' . trim($param['keyword']) . '%'];
  3525. }
  3526. // 查询id列表
  3527. $customerIdList = Customer::where($condition)->column('id');
  3528. if (isset($param['state']) && $param['state']) {
  3529. // 筛查状态
  3530. $customerIdList = CustomerVisitLog::where([['state', 'in', CustomerVisitLog::changeState($param['state'])], ['customer_id', 'in', $customerIdList]])->group('customer_id')->column('customer_id');
  3531. }
  3532. $pageIdList = array_slice($customerIdList, ($param['page'] - 1) * $param['limit'], $param['limit']);
  3533. $condition[] = ['id', 'in', $pageIdList];
  3534. $customersStateList = CustomerVisitLog::where([['customer_id', 'in', $pageIdList]])->group('state,customer_id')->field('count(state) as num, state, customer_id')->select()->toArray();
  3535. $customersState = [];
  3536. foreach ($customersStateList as $s) {
  3537. if (!isset($customersState[$s['customer_id']]))
  3538. $customersState[$s['customer_id']] = ['count' => 0, 'shop' => 0, 'measure' => 0, 'activity' => 0, 'deposit' => 0, 'signed' => 0];
  3539. $customersState[$s['customer_id']]['count'] += $s['num'];
  3540. // 到店,量房,活动,定金,签单
  3541. if ($s['state'] == '已到店') $customersState[$s['customer_id']]['shop'] += $s['num'];
  3542. elseif ($s['state'] == '已量房') $customersState[$s['customer_id']]['measure'] += $s['num'];
  3543. elseif ($s['state'] == '已到场') $customersState[$s['customer_id']]['activity'] += $s['num'];
  3544. elseif ($s['state'] == '已交定') $customersState[$s['customer_id']]['deposit'] += $s['num'];
  3545. elseif ($s['state'] == '已签单') $customersState[$s['customer_id']]['signed'] += $s['num'];
  3546. }
  3547. // 上方id已分页,此处分页参数传固定1
  3548. $data = CustomerLogic::poollist($condition, 1, $param['limit'], $order);
  3549. $customer_id = array_column($data, 'id');
  3550. $visitLogNum = CustomerVisitLog::where([['customer_id', 'in', $customer_id], CustomerVisitLog::changeState(['state', '=', '无效'])])->group('customer_id')->column('count(customer_id) as num', 'customer_id');
  3551. $visitLogDate = CustomerVisitLog::where([['customer_id', 'in', $customer_id], CustomerVisitLog::changeState(['state', '=', '无效'])])->order('addtime')->column('addtime', 'customer_id');
  3552. foreach ($data as &$value) {
  3553. //回收次数
  3554. $value['recoverNum'] = isset($visitLogNum[$value['id']]) ? $visitLogNum[$value['id']] : 0;
  3555. //最近的回收时间
  3556. $value['recoverLatelyDate'] = isset($visitLogDate[$value['id']]) ? $visitLogDate[$value['id']] : null;
  3557. //上次跟进人信息
  3558. $value['before_pool'] = !empty($value['before_pool']) ? json_decode($value['before_pool'], true) : null;
  3559. $value[$value['id']]['stateNum'] = $customersState[$value['id']] ?? ['count' => 0, 'shop' => 0, 'measure' => 0, 'activity' => 0, 'deposit' => 0, 'signed' => 0];
  3560. }
  3561. foreach ($condition as $k => $v) {
  3562. if ($v[0] == 'id') {
  3563. if (isset($v[2])) {
  3564. $condition[$k][2] = $customerIdList;
  3565. }
  3566. }
  3567. }
  3568. $count = CustomerLogic::count($condition);
  3569. return json(['code' => 0, 'data' => $data, 'count' => $count]);
  3570. }
  3571. /**
  3572. * 资源分配
  3573. */
  3574. public function resourceAllocation()
  3575. {
  3576. $param = Request()->only(['cids' => '', 'eid' => 0]);
  3577. $token = $this->request->token;
  3578. $info = Employee::where([['state', '=', '在职'], ['id', '=', $param['eid']], ['root_id', '=', $token['root_org']]])->findOrEmpty();
  3579. if ($info->isEmpty()) return json(['code' => 1, 'msg' => '指派失败']);
  3580. $cids = explode(',', $param['cids']);
  3581. $cids = Customer::where([['id', 'in', $cids], ['employee_id', '=', null]])->column('id');
  3582. if (empty($cids)) return json(['code' => 1, 'msg' => '指派失败']);
  3583. foreach ($cids as $v) {
  3584. 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])) {
  3585. CustomerVisitLog::create([
  3586. 'customer_id' => $v,
  3587. 'type' => 1,
  3588. 'remark' => '管理员指派',
  3589. 'employee_id' => $param['eid'],
  3590. 'user_id' => $info->uid,
  3591. 'state' => '待确认'
  3592. ]);
  3593. }
  3594. }
  3595. return json(['code' => 0, 'msg' => '指派成功']);
  3596. }
  3597. public function distributing()
  3598. {
  3599. $request = request();
  3600. $param = $request->param();
  3601. $target_customer_ids_arr = explode(',', $param['targets']);
  3602. $root_id = request()->token['root_org'];
  3603. $subOrg = orgSubIds($root_id);
  3604. $target_customer_ids_arr = Customer::where([['id', 'in', $target_customer_ids_arr], ['org_id', 'in', $subOrg]])->column('id');
  3605. if ($param['type'] == 'toemp' && isset($param['emp_id'])) {
  3606. $employee_id = $param['emp_id'];
  3607. $emp_obj = Employee::find($employee_id);
  3608. $org_id = $emp_obj->org_id;
  3609. } else {
  3610. $employee_id = null;
  3611. $org_id = $param['org_pool'];
  3612. }
  3613. foreach ($target_customer_ids_arr as $item_id) {
  3614. $update = [
  3615. 'employee_id' => $employee_id,
  3616. 'org_id' => $org_id,
  3617. ];
  3618. if ($employee_id) {
  3619. $update['ext->ext6'] = '';
  3620. $update['designer_id'] = null;
  3621. }
  3622. Customer::where(['id' => (int)$item_id])->update($update);
  3623. }
  3624. return json(['code' => 0, 'msg' => '操作成功']);
  3625. }
  3626. /**
  3627. * 公海获取客户
  3628. * customer_id来源:业务员获取(int)、报备录入时查询公海存在自动获取(逗号分隔字符串)
  3629. */
  3630. public function fetchpoolitem()
  3631. {
  3632. $param = request()->param();
  3633. $customer_id = explode(',', $param['customer_id']);
  3634. $employee_id = $this->request->token['employee_id'];
  3635. $root_id = request()->token['root_org'];
  3636. $subOrg = orgSubIds($root_id);
  3637. $otheremp = Customer::where([['id', 'in', $customer_id], ['employee_id', '=', NULL], ['org_id', 'in', $subOrg]])->field('employee_id,phone,phone1,phone2')->select();
  3638. if (empty($otheremp)) {
  3639. return json(['code' => 1, 'msg' => '客户已被人抢先获取。记得下次抓住机会。']);
  3640. }
  3641. //判断名下是否存在该客户手机号,存在则不可获取
  3642. foreach ($otheremp as $item) {
  3643. $phone_arr = [];
  3644. !empty($item['phone']) ? $phone_arr[] = cypherphone($item['phone']) : '';
  3645. !empty($item['phone1']) ? $phone_arr[] = cypherphone($item['phone1']) : '';
  3646. !empty($item['phone2']) ? $phone_arr[] = cypherphone($item['phone2']) : '';
  3647. $phone_arr = array_filter($phone_arr);
  3648. $haveCrm = Customer::where([['employee_id', '=', $employee_id], ['phone|phone1|phone2', 'in', $phone_arr]])->count();
  3649. if ($haveCrm) {
  3650. return json(['code' => 1, 'msg' => '您名下已存在该客户信息。']);
  3651. }
  3652. }
  3653. 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')])) {
  3654. $saveAll = [];
  3655. foreach ($customer_id as $ids) {
  3656. $saveAll[] = [
  3657. 'customer_id' => $ids,
  3658. 'type' => 1,
  3659. 'remark' => '公海获取',
  3660. 'employee_id' => $employee_id,
  3661. 'user_id' => $this->request->token['uid'],
  3662. 'state' => 1
  3663. ];
  3664. }
  3665. if (CustomerVisitLog::insertAll($saveAll)) {
  3666. return json(['code' => 0, 'msg' => '跟进成功']);
  3667. } else {
  3668. return json(['code' => 1, 'msg' => '跟进失败']);
  3669. }
  3670. } else {
  3671. return json(['code' => 1, 'msg' => '跟进失败']);
  3672. }
  3673. }
  3674. // /**
  3675. // * 预约确认
  3676. // */
  3677. // public function subscribeConfirm($id, $type)
  3678. // {
  3679. // if ($this->request->token['org_type'] == 2) {
  3680. // $column = 'designer_id';
  3681. // $employeeType = '设计师';
  3682. // } else {
  3683. // $column = 'employee_id';
  3684. // $employeeType = '销售';
  3685. // }
  3686. // $customer = Customer::where([[$column, '=', $this->request->token['employee_id']], ['id', '=', $id]])->find();
  3687. // $subscribe = CustomersSubscribe::where([['customer_id', '=', $id], ['type', '=', $type], ['state', '=', 0], [$column, '=', $this->request->token['employee_id']]])->find();
  3688. // if (!empty($subscribe)) {
  3689. // $subscribe->state = 1;
  3690. // $subscribe->save();
  3691. // }
  3692. // $employeeName = Employee::find($this->request->token['employee_id'])->name;
  3693. // $state = [
  3694. // 1 => '已到店',
  3695. // 2 => '已到场',
  3696. // 3 => '已量房'
  3697. // ];
  3698. // $customer->state = $state[$type];
  3699. // $customer->save();
  3700. // // 跟进记录添加
  3701. // $visitLog = [
  3702. // 'customer_id' => $id,
  3703. // 'type' => 4,
  3704. // 'remark' => $employeeType . $employeeName . '确认客户' . $customer->name . $state[$type],
  3705. // 'employee_id' => $this->request->token['employee_id'],
  3706. // 'user_id' => $this->request->token['uid'],
  3707. // 'state' => $state[$type]
  3708. // ];
  3709. // CustomerVisitLog::create($visitLog);
  3710. // return json(['code' => 0, 'msg' => '确认成功']);
  3711. // }
  3712. // /**
  3713. // * 确认到店
  3714. // */
  3715. // public function visitConfirm($id)
  3716. // {
  3717. // return $this->subscribeConfirm($id, 1);
  3718. // }
  3719. // /**
  3720. // * 确认到场
  3721. // */
  3722. // public function activityConfirm($id)
  3723. // {
  3724. // return $this->subscribeConfirm($id, 2);
  3725. // }
  3726. // /**
  3727. // * 确认量房
  3728. // */
  3729. // public function measureConfirm($id, array $img)
  3730. // {
  3731. // return $this->subscribeConfirm($id, 3);
  3732. // }
  3733. // /**
  3734. // * 取消到店/量房
  3735. // */
  3736. // public function cancelSubscribe($id)
  3737. // {
  3738. // $customer = Customer::where([['id', '=', $id], ['employee_id|designer_id', '=', $this->request->token['employee_id']]])->find();
  3739. // if (empty($customer)) return json(['code' => 1, 'msg' => '客户不存在']);
  3740. // $subscribe = CustomersSubscribe::where([['customer_id', '=', $id], ['type', '=', $type], ['state', '=', 0], ['subscribe_date', '=', date('Y-m-d')], [$column, '=', $this->request->token['employee_id']]])->find();
  3741. // if (!empty($subscribe)) {
  3742. // $subscribe->state = 1;
  3743. // $subscribe->save();
  3744. // }
  3745. // // 跟进记录添加
  3746. // $employeeName = Employee::where(['id' => $this->request->token['employee_id']])->value('name');
  3747. // $visitLog = [
  3748. // 'customer_id' => $customer->id,
  3749. // 'type' => 4,
  3750. // 'remark' => "${employeeName}取消了客户的" . $customer->state,
  3751. // 'employee_id' => $this->request->token['employee_id'],
  3752. // 'user_id' => $this->request->token['uid'],
  3753. // 'state' => $customer->state
  3754. // ];
  3755. // $customer->state = $customer->state == '预约活动' ? '未到场' : str_replace('预约', '未', $customer->state);
  3756. // // $customer->state = str_replace('预约', '未', $customer->state);
  3757. // // 数据保存
  3758. // Db::startTrans();
  3759. // try {
  3760. // CustomerVisitLog::create($visitLog);
  3761. // $customer->save();
  3762. // Db::commit();
  3763. // } catch (\Exception $e) {
  3764. // Db::rollback();
  3765. // return json(['code' => 1, 'msg' => $e->getMessage()]);
  3766. // }
  3767. // return json(['code' => 0, 'msg' => '取消成功']);
  3768. // }
  3769. /**
  3770. * 共有客户头部统计
  3771. */
  3772. public function shareStatistics()
  3773. {
  3774. $token = $this->request->token;
  3775. $is_manager = $token['isManager'];
  3776. $param = $this->request->only(['org_id', 'start_time' => '', 'end_time' => '']);
  3777. if ($is_manager == 1) {
  3778. $team_orgs = orgSubIds($token['org_id']);
  3779. $org_employee = Employee::where([['org_id', 'in', $team_orgs], ['state', '=', '在职'], ['uid', '>', 0]])->column('id');
  3780. } else {
  3781. $org_employee = [$token['employee_id']];
  3782. }
  3783. $condition = [
  3784. ['state', 'not in', Customer::changeState('无效', 'chaos')],
  3785. //['employee_id|designer_id|assigned_personnel', 'find in set', $token['employee_id']],
  3786. ['designer_id|assigned_personnel', 'not null', ""],
  3787. ['employee_id', '>', 0]
  3788. ];
  3789. $condition[] = ['died', '<>', 2]; // 死单客户过滤
  3790. if ($param['start_time'] && $param['end_time']) {
  3791. $condition[] = ['assign_time', 'between', [$param['start_time'] . ' 00:00:00', $param['end_time'] . ' 23:59:59']];
  3792. }
  3793. $customerIdList = Customer::where($condition)->where(function ($query) use ($org_employee) {
  3794. foreach ($org_employee as $v) {
  3795. $query->whereOr([['employee_id|designer_id|assigned_personnel', 'find in set', $v]]);
  3796. }
  3797. })->column('id');
  3798. $asg_num = count($customerIdList);
  3799. $measure_num = $toshop_num = $deposit_num = $sing_num = 0;
  3800. $cusvislog = CustomerVisitLog::where([['customer_id', 'in', $customerIdList]])->group('state,customer_id')->field('id,state,customer_id')->select()->toArray();
  3801. foreach ($cusvislog as $key => $val) {
  3802. if ($val['state'] == '已量房') $measure_num++;
  3803. if ($val['state'] == '已到店') $toshop_num++;
  3804. if ($val['state'] == '已交定') $deposit_num++;
  3805. if ($val['state'] == '已签单') $sing_num++;
  3806. }
  3807. $data = ['asg_num' => $asg_num, 'measure_num' => $measure_num, 'toshop_num' => $toshop_num, 'deposit_num' => $deposit_num, 'sing_num' => $sing_num];
  3808. return json(['code' => 0, 'data' => $data, 'msg' => '获取成功']);
  3809. }
  3810. /**
  3811. * 共有客户列表
  3812. */
  3813. public function shareList()
  3814. {
  3815. $token = $this->request->token;
  3816. $is_manager = $token['isManager'];
  3817. $team_orgs = orgSubIds($token['org_id']);
  3818. $param = $this->request->only([
  3819. 'page' => 1,
  3820. 'limit' => 20,
  3821. 'keyword' => "",
  3822. "state" => "",
  3823. 'assign_start_time' => '',
  3824. 'assign_end_time' => '',
  3825. 'employee_name' => ''
  3826. ]);
  3827. $employee_where[] = ['org_id', 'in', $team_orgs];
  3828. $employee_where[] = ['state', '=', '在职'];
  3829. $employee_where[] = ['uid', '>', 0];
  3830. if (!empty($param['employee_name'])) {
  3831. $employee_where[] = ['name', 'like', '%' . $param['employee_name'] . '%'];
  3832. }
  3833. if ($is_manager == 1) {
  3834. $org_employee = Employee::where($employee_where)->column('id');
  3835. } else {
  3836. $org_employee = [$token['employee_id']];
  3837. }
  3838. //2022-11-15 逻辑修改 销售/设计师已经指派的客户 在自己的共有客户中都能看到
  3839. $condition = [
  3840. ['state', 'not in', Customer::changeState('无效', 'chaos')],
  3841. //['employee_id|designer_id|assigned_personnel', 'find in set', $token['employee_id']],
  3842. ['designer_id|assigned_personnel', 'not null', ""],
  3843. ['employee_id', '>', 0]
  3844. ];
  3845. $condition[] = ['died', '<>', 2]; // 死单客户过滤
  3846. // $cids = Customer::where($condition)->select();
  3847. // if ($token['org_type'] == 2) {
  3848. // $condition[] = ['designer_id', '=', $token['employee_id']];
  3849. // } else {
  3850. // $condition[] = ['designer_id', 'not null', ""];
  3851. // $condition[] = ['employee_id', '=', $token['employee_id']];
  3852. // }
  3853. if (!empty($param['keyword'])) {
  3854. $list = Customer::where($condition)->where(function ($query) use ($org_employee) {
  3855. foreach ($org_employee as $v) {
  3856. $query->whereOr([['employee_id|designer_id|assigned_personnel', 'find in set', $v]]);
  3857. }
  3858. })->order('addtime desc')->field('id,name,community_name,phone')->select()->toArray();
  3859. $customerIdList = [];
  3860. foreach ($list as $v) {
  3861. $str = $v['name'] . $v['community_name'] . $v['phone'];
  3862. if (strpos($str, trim($param['keyword'])) !== false) $customerIdList[] = $v['id'];
  3863. }
  3864. } else {
  3865. $customerIdList = Customer::where($condition)->where(function ($query) use ($org_employee) {
  3866. foreach ($org_employee as $v) {
  3867. $query->whereOr([['employee_id|designer_id|assigned_personnel', 'find in set', $v]]);
  3868. }
  3869. })->column('id');
  3870. }
  3871. if (!empty($param['state'])) {
  3872. if ($param['state'] == '待确认') {
  3873. // 筛查状态
  3874. /* $customerIdList1 = CustomerVisitLog::where([['customer_id', 'in', $customerIdList], ['state', 'not in', CustomerVisitLog::changeState('待确认', 'chaos')]])->group('customer_id')->column('customer_id');
  3875. $customerIdList = array_diff($customerIdList, $customerIdList1); */
  3876. $customerIdList = Customer::where([['id', 'in', $customerIdList], ['state', 'in', Customer::changeState($param['state'], 'chaos')], ['crm_res_id', 'NULL', null]])->column('id');
  3877. } elseif (CustomerVisitLog::changeState($param['state']) == '回访' || $param['state'] == '有效') {
  3878. //有效状态 未到访,已到访,确定到场,已量房,交定,签单
  3879. $visit_status = ['未到访', '已到访', '已量房', '已到场', '已到店', '交定', '签单'];
  3880. $now_status = [];
  3881. foreach ($visit_status as $v) {
  3882. $now_status = array_merge(CustomerVisitLog::changeState($v, 'chaos'), $now_status);
  3883. }
  3884. $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');
  3885. } else {
  3886. // 筛查状态
  3887. $customerIdList = CustomerVisitLog::where([['customer_id', 'in', $customerIdList], ['state', 'in', CustomerVisitLog::changeState($param['state'], 'chaos')]])->group('customer_id')->column('customer_id');
  3888. }
  3889. }
  3890. //2022-11-14 增加 查询共有客户当天待到店,待量房列表
  3891. if (input('search_type', 0)) {
  3892. $search_where = [
  3893. ['subscribe_date', '=', date('Y-m-d')],
  3894. ['customer_id', 'in', $customerIdList],
  3895. ['state', '=', 0],
  3896. ['type', 'in', [1, 3]] //1到店,3量房
  3897. ];
  3898. $arr = CustomersSubscribe::where($search_where)->column('type', 'customer_id');
  3899. $customerIdList = array_keys($arr);
  3900. }
  3901. //增加按指派时间查询
  3902. if (!empty($param['assign_start_time']) && !empty($param['assign_end_time'])) {
  3903. $assign_where[] = ['assign_time', 'between', [$param['assign_start_time'] . ' 00:00:00', $param['assign_end_time'] . ' 23:59:59']];
  3904. $assign_where[] = ['id', 'in', $customerIdList];
  3905. $assign_where[] = ['assigned_personnel', 'not null', null];
  3906. $customerIdList = Customer::where($assign_where)->column('id');
  3907. }
  3908. $customers = Customer::where([['id', 'in', $customerIdList]])->order('assign_time desc')->page($param['page'], $param['limit'])->select();
  3909. //2022-11-08 增加指派人员
  3910. // $query1 = [['employee_id', '>', 0], ['assigned_personnel', 'find in set', $token['employee_id']]];
  3911. // if (input('search_type', 0)) $query1[] = ['id', 'in', $customerIdList]; //当天待到店,量房的客户
  3912. // $assigned_personnel = Customer::where($query1)->column('id');
  3913. // $where_or[] = ['id', 'in', $assigned_personnel];
  3914. // $customers = Customer::whereOr([$condition, $where_or])->page($param['page'], $param['limit'])->select();
  3915. $count = Customer::where([['id', 'in', $customerIdList]])->count();
  3916. $data = $customers->toArray();
  3917. $pageIdList = array_column($data, 'id');
  3918. $employeeList = array_column($data, 'employee_id');
  3919. $designerList = array_column($data, 'designer_id');
  3920. $empIdList = array_merge($employeeList, $designerList, [$token['employee_id']]);
  3921. $empList = Employee::where([['id', 'in', $empIdList]])->column('name,org_id', 'id');
  3922. $orgList = Org::where([['id', 'in', array_column($empList, 'org_id')]])->column('name', 'id');
  3923. // $customers = $customers->visible(['id', 'name', 'sex', 'level', 'community_name', 'state'])->toArray();
  3924. // 查询跟踪记录
  3925. $depositVisitLog = CustomerVisitLog::where([CustomerVisitLog::changeState(['state', '=', '已交定']), ['customer_id', 'in', $pageIdList]])->group('customer_id')->column('count(id) as num', 'customer_id');
  3926. $signVisitLog = CustomerVisitLog::where([CustomerVisitLog::changeState(['state', '=', '已签单']), ['customer_id', 'in', $pageIdList]])->group('customer_id')->column('count(id) as num', 'customer_id');
  3927. // 状态统计获取
  3928. $customersStateList = CustomerVisitLog::where([['customer_id', 'in', $customerIdList]])->group('state,customer_id')->field('count(state) as num, state, customer_id')->select()->toArray();
  3929. $customersState = [];
  3930. foreach ($customersStateList as $s) {
  3931. if (!isset($customersState[$s['customer_id']]))
  3932. $customersState[$s['customer_id']] = ['count' => 0, 'shop' => 0, 'measure' => 0, 'activity' => 0, 'deposit' => 0, 'signed' => 0];
  3933. $customersState[$s['customer_id']]['count'] += $s['num'];
  3934. // 到店,量房,活动,定金,签单
  3935. if ($s['state'] == '已到店') $customersState[$s['customer_id']]['shop'] += $s['num'];
  3936. elseif ($s['state'] == '已量房') $customersState[$s['customer_id']]['measure'] += $s['num'];
  3937. elseif ($s['state'] == '已到场') $customersState[$s['customer_id']]['activity'] += $s['num'];
  3938. elseif ($s['state'] == '已交定') $customersState[$s['customer_id']]['deposit'] += $s['num'];
  3939. elseif ($s['state'] == '已签单') $customersState[$s['customer_id']]['signed'] += $s['num'];
  3940. }
  3941. $data = [];
  3942. // 最后跟进时间获取
  3943. $lastTime = CustomerVisitLog::where([['customer_id', 'in', $customerIdList]])->group('customer_id')->column('max(addtime)', 'customer_id');
  3944. // 交定时间获取
  3945. $dingTime = CustomerVisitLog::where([['customer_id', 'in', $customerIdList], ['state', 'in', CustomerVisitLog::changeState('已交定', 'chaos')]])->group('customer_id')->column("max(confirm_date)", "customer_id");
  3946. // 指派类型
  3947. $assign_type_default['yixiang'] = '意向客户指派';
  3948. $assign_type_default['liangfang'] = '量房客户指派';
  3949. $assign_type_default['daodian'] = '到店客户指派';
  3950. foreach ($customers as $item) {
  3951. $assignIdList = !empty($item['assigned_personnel']) ? explode(',', $item['assigned_personnel']) : [];
  3952. if (!empty($assignIdList) && !empty($item['designer_id'])) {
  3953. $assignIdList = array_diff($assignIdList, [$item['designer_id']]);
  3954. }
  3955. $assignIdList[] = $item['employee_id']; // 所属销售
  3956. $assignIdList = array_unique($assignIdList);
  3957. //$assignIdList[] = $item['designer_id']; // 指派的设计师
  3958. $assign_list = Employee::where('id', 'in', $assignIdList)->column('name');
  3959. $is_follow = 0;
  3960. if (!in_array($item['org_id'], $team_orgs) && !in_array($token['employee_id'], $assignIdList) && $token['org_type'] != 2) $is_follow = 1;
  3961. $assign_type_name = '';
  3962. if ($item['assign_type']) {
  3963. if (isset($assign_type_default[$item['assign_type']])) {
  3964. $assign_type_name = $assign_type_default[$item['assign_type']];
  3965. }
  3966. }
  3967. $data[] = [
  3968. 'id' => $item['id'],
  3969. 'name' => $item['name'],
  3970. 'sex' => $item['sex'],
  3971. 'level' => $item['level'],
  3972. 'community_name' => $item['community_name'],
  3973. 'state' => $item['state'],
  3974. 'deposit_num' => isset($depositVisitLog[$item['id']]) ? $depositVisitLog[$item['id']] : 0,
  3975. 'sign_num' => isset($signVisitLog[$item['id']]) ? $signVisitLog[$item['id']] : 0,
  3976. 'employee' => [
  3977. 'name' => $empList[$item['employee_id']]['name']
  3978. ],
  3979. 'employeeOrg' => [
  3980. 'name' => $orgList[$empList[$item['employee_id']]['org_id']]
  3981. ],
  3982. 'designer' => empty($item['designer_id']) ? null : [
  3983. 'name' => $empList[$item['designer_id']]['name']
  3984. ],
  3985. 'designerOrg' => empty($item['designer_id']) ? null : [
  3986. 'name' => $orgList[$empList[$item['designer_id']]['org_id']]
  3987. ],
  3988. 'btn_type' => !empty($arr[$item['id']]) ? $arr[$item['id']] : 0, ////1到店,3量房
  3989. 'square' => $item['square'], //房屋面积
  3990. 'agents' => !empty($item['agents_id']) ? $item['agents_id'] : '', //是否是经纪人推荐的
  3991. 'stateNum' => !empty($customersState[$item['id']]) ? $customersState[$item['id']] : ['count' => 0, 'shop' => 0, 'measure' => 0, 'activity' => 0, 'deposit' => 0, 'signed' => 0],
  3992. //'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')) : '' : '',
  3993. 'assign_time' => !empty($item['assign_time']) ? $item['assign_time'] : '',
  3994. 'assign_list' => $assign_list,
  3995. 'assign_type' => $item['assign_type'],
  3996. 'assigned_personnel' => $item['assigned_personnel'],
  3997. 'assign_type_name' => $assign_type_name,
  3998. 'is_follow' => $is_follow,
  3999. 'last_visit_day' => isset($lastTime[$item['id']]) ? get_date_diff(time(), $lastTime[$item['id']])->days : -1,
  4000. 'last_ding_day' => isset($dingTime[$item['id']]) ? get_date_diff(time(), $dingTime[$item['id']])->days : 0
  4001. ];
  4002. }
  4003. return json(['code' => 0, 'data' => $data, 'count' => $count]);
  4004. }
  4005. /**
  4006. * 获取客户画像展示字段
  4007. */
  4008. public function show_fields()
  4009. {
  4010. $token = $this->request->token;
  4011. $w[] = ['root_id', '=', $token['root_org']];
  4012. $info = CustomerPortrait::where($w)->findOrEmpty();
  4013. $data = $info->fields;
  4014. return json(['code' => 0, 'data' => $data]);
  4015. }
  4016. /**
  4017. * 获取加微类型
  4018. * wechat_type 加微类型
  4019. * img_type 跟进图片类型
  4020. * employees 直播人员列表
  4021. * next_visit_time_is_ok 回访时间是否必传 默认必传
  4022. *
  4023. */
  4024. public function get_setting()
  4025. {
  4026. $token = $this->request->token;
  4027. //wechat_type 加微类型
  4028. $where[] = ['root_id', '=', $token['root_org']];
  4029. $where[] = ['name', '=', 'customerWechatSetting'];
  4030. $info = Setting::where($where)->value('content');
  4031. $data['wechat_type'] = $info ? explode(',', $info) : ['常规加微'];
  4032. //img_type 跟进图片类型
  4033. $where1[] = ['root_id', '=', $token['root_org']];
  4034. $where1[] = ['name', '=', 'customerLfSetting'];
  4035. $info = Setting::where($where1)->value('content');
  4036. $data['img_type'] = $info ? explode(',', $info) : ['量房图片'];
  4037. //employees 直播人员列表
  4038. $data['employees'] = $this->live_broadcast_personnel(1);
  4039. //next_visit_time_is_ok 回访时间是否必传 默认必传
  4040. $where2[] = ['root_id', '=', $token['root_org']];
  4041. $where2[] = ['name', '=', 'nextVisitTimeIsOk'];
  4042. $info = Setting::where($where2)->value('content');
  4043. $data['next_visit_time_is_ok'] = $info == 1 ? 1 : 0;
  4044. $where3[] = ['root_id', '=', $token['root_org']];
  4045. $where3[] = ['name', '=', 'addWechatDay'];
  4046. $visit = Setting::where($where3)->findOrEmpty();
  4047. $res = !$visit->isEmpty() ? explode('@', $visit->content) : [1, 0];
  4048. $data['add_wechat_day'] = $res[0];
  4049. $data['add_wechat_day_switch'] = isset($res[1]) ? $res[1] : 0;
  4050. $company = Company::where('root_id', $token['root_org'])->find();
  4051. $data['city'] = $company->city;
  4052. $data['province_city'] = $company->province_city;
  4053. $data['province_city_code'] = $company->province_city_code;
  4054. return json(['code' => 0, 'data' => $data]);
  4055. }
  4056. /**
  4057. * 获取直播人员
  4058. */
  4059. public function live_broadcast_personnel($type = 0)
  4060. {
  4061. $token = $this->request->token;
  4062. $param = Request()->only(['org_id' => 0, 'name']);
  4063. $root_id = $token['root_org'];
  4064. $subOrg = orgSubIds($root_id);
  4065. if (in_array($param['org_id'], $subOrg)) {
  4066. $path = Org::where('id', $param['org_id'])->value('path');
  4067. } else {
  4068. $path = $token['root_org'] . '-';
  4069. }
  4070. $where[] = ['path', 'like', $path . '%'];
  4071. $empwhere[] = ['e.state', '=', '在职'];
  4072. if (!empty($param['name'])) {
  4073. $empwhere[] = ['e.name', 'like', '%' . $param['name'] . '%'];
  4074. }
  4075. $orgs = Org::with(['employee' => function ($query) use ($empwhere) {
  4076. $query->field('e.id,e.name,user.headimgurl,e.org_id')
  4077. ->alias('e')
  4078. ->where($empwhere)
  4079. ->join('user', 'user.id=e.uid');
  4080. }])->where($where)->order('level asc, id desc')->field('id,name,pid')->select()->toArray();
  4081. $data = [];
  4082. while (!empty($orgs)) {
  4083. $org = array_pop($orgs);
  4084. // $data[$org['pid']]['designer_num'] = isset($data[$org['pid']]) ? $data[$org['pid']]['designer_num'] + count($org['employee']) : 0;
  4085. $childOrg = [
  4086. 'id' => $org['id'],
  4087. 'name' => $org['name'],
  4088. 'pid' => $org['pid'],
  4089. 'designer' => $org['employee'],
  4090. 'designer_num' => count($org['employee'])
  4091. ];
  4092. if (isset($data[$org['id']])) {
  4093. $childOrg['child_org'] = $data[$org['id']]['child_org'];
  4094. $childOrg['designer_num'] += $data[$org['id']]['designer_num'];
  4095. unset($data[$org['id']]);
  4096. }
  4097. $data[$org['pid']]['child_org'][] = $childOrg;
  4098. $data[$org['pid']]['designer_num'] = isset($data[$org['pid']]['designer_num']) ? $data[$org['pid']]['designer_num'] + $childOrg['designer_num'] : $childOrg['designer_num'];
  4099. }
  4100. $data = array_pop($data);
  4101. $result = [
  4102. 'designer' => isset($data['designer']) ? $data['designer'] : [],
  4103. 'child_org' => isset($data['child_org']) ? $data['child_org'] : []
  4104. ];
  4105. if ($type) {
  4106. return $result;
  4107. } else {
  4108. return json(['code' => 0, 'data' => $result]);
  4109. }
  4110. }
  4111. /**
  4112. * 新客户列表
  4113. */
  4114. public function newList()
  4115. {
  4116. $param = $this->request->only([
  4117. 'page' => 1,
  4118. 'limit' => 20
  4119. ]);
  4120. // 剔除掉关注过的客户
  4121. $customerTopIdList = CustomerTop::where(['employee_id' => $this->request->token['employee_id'], 'root_id' => request()->token['root_org']])->column('customer_id');
  4122. $condition = [
  4123. ['fresh', '>', 0],
  4124. ['employee_id', '=', $this->request->token['employee_id']],
  4125. ['id', 'not in', $customerTopIdList]
  4126. ];
  4127. $data = Customer::where($condition)->page($param['page'], $param['limit'])->order('addtime desc')->select();
  4128. $count = Customer::where($condition)->count();
  4129. foreach ($data as &$item) {
  4130. if (1 == $item->crm_res_id) $item->new = 1;
  4131. }
  4132. $data = $data->visible(['id', 'name', 'sex', 'community_name', 'square', 'new'])->toArray();
  4133. return json(['code' => 0, 'data' => $data, 'count' => $count]);
  4134. }
  4135. /**
  4136. * 自动回收列表
  4137. */
  4138. public function drop_pool()
  4139. {
  4140. $param = $this->request->only(['page' => 1, 'limit' => 20, 'order', 'org', 'emp_id', 'state', 'keyword']);
  4141. $orgids = orgSubIds($this->request->token['org_id']);
  4142. $org_employee = Employee::where('org_id', 'in', $orgids)->column('id');
  4143. $condition[] = ['employee_id', 'in', $org_employee];
  4144. $order = isset($param['order']) ? $param['order'] : 'id desc';
  4145. setCondition($param, ['emp_id', 'employee_id'], '=', $condition);
  4146. empty($param['state']) ?: setCondition(['state' => Customer::changeState($param['state'], 'chaos')], 'state', 'in', $condition);
  4147. //关键词搜索
  4148. if (!empty($param['keyword'])) {
  4149. $list = CustomerDropPool::where($condition)->order($order)->field('customer_id,name,community_name,phone,employee_id,designer_id')->select()->toArray();
  4150. $search_employee = Employee::where([['id', 'in', $org_employee], ['name', 'like', '%' . $param['keyword'] . '%']])->column('id');
  4151. $search_designer = Employee::where([['root_id', '=', $this->request->token['root_org']], ['name', 'like', '%' . $param['keyword'] . '%']])->column('id');
  4152. $employee_customer = [];
  4153. $customersIdList = [];
  4154. foreach ($list as $k => $v) {
  4155. $str = $v['name'] . $v['community_name'];
  4156. if (strpos($str, trim($param['keyword'])) !== false) $customersIdList[] = $v['customer_id'];
  4157. if (in_array($v['employee_id'], $search_employee)) {
  4158. $employee_customer[] = $v['customer_id'];
  4159. }
  4160. if (in_array($v['designer_id'], $search_designer)) {
  4161. $employee_customer[] = $v['customer_id'];
  4162. }
  4163. $employee_customer = array_values(array_filter(array_unique($employee_customer)));
  4164. }
  4165. $customersIdList = array_values(array_filter(array_unique(array_merge($customersIdList, $employee_customer))));
  4166. } else {
  4167. $customersIdList = CustomerDropPool::where($condition)->order($order)->column('customer_id');
  4168. }
  4169. $data = CustomerDropPool::with(['employee', 'org', 'designer'])->withCount(['visitLog' => function ($query) {
  4170. $query->whereOr([[CustomerVisitLog::changeState(['state', '=', '预约量房'])], [CustomerVisitLog::changeState(['state', '=', '预约到店'])], [CustomerVisitLog::changeState(['state', '=', '预约活动'])]]);
  4171. }])->withCount(['activityFrequency' => function ($query) {
  4172. $query->where([CustomerVisitLog::changeState(['state', '=', '确认到场'])]);
  4173. }])
  4174. ->where([['customer_id', 'in', $customersIdList]])
  4175. ->page($param['page'], $param['limit'])->order($order)->select();
  4176. $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();
  4177. $ids = CustomerDropPool::where([['customer_id', 'in', $customersIdList]])->field('id,phone,phone1,phone2')->select();
  4178. foreach ($data as &$item) {
  4179. $item['protected'] = false;
  4180. if (isset($item['protected_to']) && time() < strtotime($item['protected_to'])) {
  4181. $item['protected'] = true;
  4182. }
  4183. $item['square'] = floatval($item['square']);
  4184. $item['mobile'] = $item['phone'];
  4185. $item['mobile1'] = $item['phone1'];
  4186. $item['mobile2'] = $item['phone2'];
  4187. $item['phone'] = substr_replace($item['phone'], '******', 3, 6);
  4188. $record_list = CustomerDropRecord::where('customer_id', '=', $item['customer_id'])->order('droptime desc')->select();
  4189. $item['recoverNum'] = $record_list->count();
  4190. $item['recoverLatelyDate'] = isset($record_list[0]) ? $record_list[0]['droptime'] : '';
  4191. $latest_visit_log = CustomerVisitLog::where('customer_id', '=', $item['customer_id'])->order('id desc')->find();
  4192. if (empty($latest_visit_log)) {
  4193. $item['latest_visit_employee'] = '';
  4194. $item['latest_visit_time'] = '';
  4195. } else {
  4196. $latest_visit_employee = Employee::find($latest_visit_log['customer_id']);
  4197. if (!empty($latest_visit_employee)) {
  4198. $item['latest_visit_employee'] = $latest_visit_employee['name'];
  4199. $item['latest_visit_time'] = $latest_visit_log['addtime'];
  4200. } else {
  4201. $item['latest_visit_employee'] = '';
  4202. $item['latest_visit_time'] = '';
  4203. }
  4204. }
  4205. }
  4206. $count = CustomerDropPool::where($condition)->count();
  4207. return json(['code' => 0, 'data' => $data, 'count' => $count, 'ids' => $ids]);
  4208. }
  4209. /**
  4210. * 自动回收还原
  4211. */
  4212. public function undrop()
  4213. {
  4214. $id = input('id', '', 'trim');
  4215. if (!$id) {
  4216. return json(['code' => 1, 'msg' => '参数错误']);
  4217. }
  4218. $list = CustomerDropPool::where([['id', 'in', $id]])->select();
  4219. $root_id = $this->request->token['root_org'];
  4220. $setting = Setting::where([['root_id', '=', $root_id], ['name', '=', 'pubpool']])->findOrEmpty();
  4221. $error = 0;
  4222. $repeat = 0;
  4223. foreach ($list as $k => $v) {
  4224. //查询重复
  4225. $l_phone = array_filter([$v->getData('phone'), $v->getData('phone1'), $v->getData('phone2')]);
  4226. $query = [];
  4227. $query[] = ['phone|phone1|phone2', 'in', $l_phone];
  4228. $query[] = ['employee_id', '=', $v->employee_id];
  4229. $check = Customer::where($query)->findOrEmpty();
  4230. if (!$check->isEmpty()) {
  4231. $repeat += 1;
  4232. continue;
  4233. }
  4234. $customer_state = Customer::changeState($v['state'], 'n');
  4235. $info = $v->toArray();
  4236. $info['protected_to'] = null;
  4237. if (!empty($setting)) {
  4238. $setting_content = json_decode($setting['content'], true);
  4239. } else {
  4240. $setting_content = [];
  4241. }
  4242. if (!empty($setting_content[$customer_state]['state']) && $setting_content[$customer_state]['state'] != 0 && !empty($setting_content[$customer_state]['day'])) {
  4243. $day = $setting_content[$customer_state]['day'];
  4244. $info['protected_to'] = $day > 0 ? date('Y-m-d H:i:s', time() + $day * 24 * 3600) : null;
  4245. }
  4246. $info['deposit_money'] = $v->getData('deposit_money');
  4247. $info['signed_money'] = $v->getData('signed_money');
  4248. $info['id'] = $info['customer_id'];
  4249. unset($info['customer_id']);
  4250. unset($info['droptime']);
  4251. unset($info['add_wechat_time']);
  4252. unset($info['group_building_date']);
  4253. unset($info['live_broadcast_date']);
  4254. unset($info['subscribe_meet_outside']);
  4255. unset($info['meet_outside']);
  4256. unset($info['sign_time']);
  4257. unset($info['reputation_gather']);
  4258. unset($info['into_owner_group']);
  4259. Db::startTrans();
  4260. $result = Customer::create($info);
  4261. $d_result = $v->delete();
  4262. if ($result && $d_result) {
  4263. Db::commit();
  4264. $param = [
  4265. 'customer_id' => $info['id'],
  4266. 'type' => 1,
  4267. 'remark' => '客户还原',
  4268. 'employee_id' => $this->request->token['employee_id'],
  4269. 'user_id' => $this->request->token['uid'],
  4270. 'state' => ''
  4271. ];
  4272. CustomerVisitLog::create($param);
  4273. } else {
  4274. Db::rollback();
  4275. $error++;
  4276. }
  4277. }
  4278. if ($repeat) return json(['code' => 1, 'msg' => '有' . $repeat . '条客户手机号已经属于业务员,无法还原']);
  4279. if ($error == 0) {
  4280. return json(['code' => 0, 'msg' => '操作成功']);
  4281. } else {
  4282. return json(['code' => 0, 'msg' => '操作成功,部分数据失败']);
  4283. }
  4284. }
  4285. /**
  4286. * 自动回收再分配
  4287. */
  4288. public function drop_pool_resdistribute()
  4289. {
  4290. $id = input('id', '', 'trim');
  4291. $employee_id = input('employee_id', '', 'intval');
  4292. $from = input('from', '', 'trim');
  4293. $target_ids_arr = explode(',', $id);
  4294. if (!empty($employee_id)) {
  4295. $emp_obj = Employee::find($employee_id);
  4296. $org_id = $emp_obj->org_id;
  4297. } else {
  4298. return json(['code' => 1, 'msg' => '操作失败']);
  4299. }
  4300. $root_id = request()->token['root_org'];
  4301. $subOrg = orgSubIds($root_id);
  4302. $target_ids_arr = Customer::where([['id', 'in', $target_ids_arr], ['org_id', 'in', $subOrg]])->column('id');
  4303. //2022-10-21 19:25:59-----------------
  4304. //2022-10-21 重复录入 重复验证 check=1,2&3,4 表示ID=2和3的客户手机号重复 1,4不重复
  4305. $repeat_customer = [];
  4306. $vislog_id = []; //跟进记录合并数组
  4307. $z_type = $from;
  4308. if (input('check', '')) {
  4309. $target_ids_arr = [];
  4310. $check_arr = explode(',', input('check', ''));
  4311. //先已第一个位置 以后可能会已保护期排序
  4312. foreach ($check_arr as $check_arr_key => $check_arr_val) {
  4313. //默认第一个ID 为准
  4314. $temporary_arr = explode('@', $check_arr_val);
  4315. $vislog_id[$temporary_arr[0]] = $temporary_arr;
  4316. }
  4317. foreach ($vislog_id as $vislog_id_key => $vislog_id_val) {
  4318. $temporary_customer = ($from == 'index') ? Customer::where('id', $vislog_id_key)->find() : CustomerDropPool::where('id', $vislog_id_key)->find();
  4319. $query = [];
  4320. $query[] = ['employee_id', '=', $employee_id];
  4321. $l_phone = array_filter([$temporary_customer->getData('phone'), $temporary_customer->getData('phone1'), $temporary_customer->getData('phone2')]);
  4322. $query[] = ['phone|phone1|phone2', 'in', $l_phone];
  4323. $check = Customer::where($query)->findOrEmpty();
  4324. if ($check->isEmpty()) {
  4325. $target_ids_arr[] = $vislog_id_key;
  4326. } else {
  4327. $repeat_customer[] = $temporary_customer->name;
  4328. }
  4329. }
  4330. }
  4331. if ($repeat_customer) {
  4332. return json(['code' => 1, 'msg' => '您选择的客户“' . implode('”,“', $repeat_customer) . '”手机号已经属于业务员' . $emp_obj->name . '请重新选择']);
  4333. }
  4334. if ($z_type != 'index') {
  4335. $drop = $vislog_id;
  4336. $vislog_ids = [];
  4337. foreach ($vislog_id as $k => $v) {
  4338. $ls_id = CustomerDropPool::where('id', $k)->value('customer_id');
  4339. $vislog_ids[$ls_id] = CustomerDropPool::where([['id', 'in', $v]])->column('customer_id');
  4340. }
  4341. $vislog_id = $vislog_ids;
  4342. }
  4343. //2022-10-21 19:25:59-----------------
  4344. $root_id = $this->request->token['root_org'];
  4345. $setting = Setting::where([['root_id', '=', $root_id], ['name', '=', 'pubpool']])->findOrEmpty();
  4346. $error = 0;
  4347. $repeat = [];
  4348. if (!empty($target_ids_arr)) {
  4349. if ($from == 'index') {
  4350. $list = Customer::where([['id', 'in', $target_ids_arr]])->select();
  4351. if (!$list->isEmpty()) {
  4352. foreach ($list as $k => $v) {
  4353. //如果该客户已经属于业务员则不需要分配 ,提示分配人
  4354. if ($v->employee_id == $employee_id) {
  4355. $repeat[] = [$v->name, $v->phone];
  4356. continue;
  4357. }
  4358. $customer_state = Customer::changeState($v['state'], 'n');
  4359. $v_data['protected_to'] = null;
  4360. if (!$setting->isEmpty()) {
  4361. $setting_content = !empty($setting['content']) ? json_decode($setting['content'], true) : [];
  4362. if (!empty($setting_content[$customer_state]['state']) && $setting_content[$customer_state]['state'] != 0 && !empty($setting_content[$customer_state]['day'])) {
  4363. $day = $setting_content[$customer_state]['day'];
  4364. $v_data['protected_to'] = date('Y-m-d H:i:s', time() + $day * 24 * 3600);
  4365. }
  4366. }
  4367. // //重复手机号验证 ,如果重复则合并客户信息和跟进记录
  4368. // $query = [];
  4369. // $l_phone = array_filter([$v->getData('phone'),$v->getData('phone1'),$v->getData('phone2')]);
  4370. // $query[] = ['phone|phone1|phone2','in',$l_phone];
  4371. // $query[] = ['employee_id','=',$employee_id];
  4372. // $check = Customer::where($query)->column('*');
  4373. // if ($check) {
  4374. // $this->customerMerge($v->id,$check,'emp',$v_data['protected_to']);
  4375. // continue;
  4376. // }
  4377. $v_data['employee_id'] = $employee_id;
  4378. $v_data['org_id'] = $org_id;
  4379. $v_data['ext->ext6'] = '';
  4380. $v_data['designer_id'] = NULL;
  4381. $v_data['revisit_time'] = NULL;
  4382. $result = Customer::where('id', $v['id'])->update($v_data);
  4383. if ($result === false) {
  4384. $error++;
  4385. } else {
  4386. $param = [
  4387. 'customer_id' => $v->id,
  4388. 'type' => 1,
  4389. 'remark' => '客户再分配',
  4390. 'employee_id' => $this->request->token['employee_id'],
  4391. 'user_id' => $this->request->token['uid'],
  4392. 'state' => ''
  4393. ];
  4394. CustomerVisitLog::create($param);
  4395. }
  4396. }
  4397. }
  4398. } elseif ($from == 'drop') {
  4399. $list = CustomerDropPool::where([['id', 'in', $target_ids_arr]])->select();
  4400. if (!$list->isEmpty()) {
  4401. foreach ($list as $k => $v) {
  4402. $customer_state = Customer::changeState($v['state'], 'n');
  4403. $info = $v->toArray();
  4404. $info['protected_to'] = null;
  4405. if (!$setting->isEmpty()) {
  4406. $setting_content = !empty($setting['content']) ? json_decode($setting['content'], true) : [];
  4407. if (!empty($setting_content[$customer_state]['state']) && $setting_content[$customer_state]['state'] != 0 && !empty($setting_content[$customer_state]['day'])) {
  4408. $day = $setting_content[$customer_state]['day'];
  4409. $info['protected_to'] = date('Y-m-d H:i:s', time() + $day * 24 * 3600);
  4410. }
  4411. }
  4412. // //重复手机号验证 ,如果重复则合并客户信息和跟进记录
  4413. // $query = [];
  4414. // $l_phone = array_filter([$v->getData('phone'),$v->getData('phone1'),$v->getData('phone2')]);
  4415. // $query[] = ['phone|phone1|phone2','in',$l_phone];
  4416. // $query[] = ['employee_id','=',$employee_id];
  4417. // $check = Customer::where($query)->column('*');
  4418. // if ($check) {
  4419. // $this->customerMerge($v->id,$check,'drop',$info['protected_to']);
  4420. // continue;
  4421. // }
  4422. Customer::where('id', $info['customer_id'])->delete(); //删除错误数据
  4423. $info['employee_id'] = $employee_id;
  4424. $info['org_id'] = $org_id;
  4425. $info['id'] = $info['customer_id'];
  4426. $info['signed_money'] = $v->getData('signed_money');
  4427. $info['deposit_money'] = $v->getData('deposit_money');
  4428. $info['designer_id'] = NULL;
  4429. $info['revisit_time'] = NULL;
  4430. unset($info['customer_id']);
  4431. unset($info['droptime']);
  4432. unset($info['add_wechat_time']);
  4433. unset($info['group_building_date']);
  4434. unset($info['live_broadcast_date']);
  4435. unset($info['subscribe_meet_outside']);
  4436. unset($info['meet_outside']);
  4437. unset($info['sign_time']);
  4438. unset($info['reputation_gather']);
  4439. unset($info['into_owner_group']);
  4440. Db::startTrans();
  4441. $result = Customer::create($info);
  4442. $d_result = $v->delete();
  4443. if (!empty($drop[$v->id])) CustomerDropPool::where([['id', 'in', $drop[$v->id]]])->delete();
  4444. if ($result && $d_result) {
  4445. $result['ext->ext6'] = '';
  4446. $result->save();
  4447. Db::commit();
  4448. $param = [
  4449. 'customer_id' => $v->customer_id,
  4450. 'type' => 1,
  4451. 'remark' => '客户再分配',
  4452. 'employee_id' => $this->request->token['employee_id'],
  4453. 'user_id' => $this->request->token['uid'],
  4454. 'state' => ''
  4455. ];
  4456. CustomerVisitLog::create($param);
  4457. } else {
  4458. Db::rollback();
  4459. $error++;
  4460. }
  4461. }
  4462. }
  4463. }
  4464. }
  4465. // if($repeat) return json(['code' => 1, 'msg' => '有'.count($repeat).'条客户已经属于所选业务员,无法分配']);
  4466. if ($error == 0) {
  4467. //2022-10-21 19:25:59-----------------
  4468. $this->customerMerge($vislog_id, $z_type);
  4469. //2022-10-21 19:25:59-----------------
  4470. return json(['code' => 0, 'msg' => '操作成功']);
  4471. } else {
  4472. return json(['code' => 0, 'msg' => '操作成功,部分数据失败']);
  4473. }
  4474. }
  4475. /**
  4476. * 合并跟进数据
  4477. */
  4478. private function customerMerge($array, $type)
  4479. {
  4480. foreach ($array as $array_key => $array_val) {
  4481. foreach ($array_val as $item) {
  4482. if ($array_key != $item) Customer::destroy($item);
  4483. }
  4484. $query = [];
  4485. $query[] = ['customer_id', 'in', $array_val];
  4486. $query[] = ['customer_id', '<>', $array_key];
  4487. CustomerVisitLog::where($query)->update(['customer_id' => $array_key, 'is_merge' => 1]);
  4488. CustomersSubscribe::where($query)->update(['customer_id' => $array_key, 'is_merge' => 1]);
  4489. }
  4490. return true;
  4491. }
  4492. /**
  4493. * 主动回收
  4494. */
  4495. public function drop_to_pool()
  4496. {
  4497. $ids = input('id', '', 'trim');
  4498. $orgIds = orgSubIds($this->request->token['root_org']);
  4499. $data = Customer::where([['org_id', 'in', $orgIds], ['id', 'in', $ids]])->select();
  4500. foreach ($data as $item) {
  4501. Db::startTrans();
  4502. $drop_data = $item->toArray();
  4503. $drop_data['customer_id'] = $drop_data['id'];
  4504. $drop_data['deposit_money'] = $item->getData('deposit_money');
  4505. $drop_data['signed_money'] = $item->getData('signed_money');
  4506. unset($drop_data['id']);
  4507. unset($drop_data['add_wechat_time']);
  4508. unset($drop_data['group_building_date']);
  4509. unset($drop_data['live_broadcast_date']);
  4510. unset($drop_data['subscribe_meet_outside']);
  4511. unset($drop_data['meet_outside']);
  4512. unset($drop_data['sign_time']);
  4513. unset($drop_data['reputation_gather']);
  4514. unset($drop_data['into_owner_group']);
  4515. $save_result = CustomerDropPool::create($drop_data);
  4516. $delete_result = $item->force()->delete();
  4517. $record_data['customer_id'] = $item->id;
  4518. CustomerDropRecord::create($record_data);
  4519. // 客户预约中改为无效
  4520. CustomersSubscribe::where([['customer_id', '=', $item->id], ['state', '=', 0]])->save(['state' => -1]);
  4521. if ($save_result && $delete_result) {
  4522. Db::commit();
  4523. $param = [
  4524. 'customer_id' => $item->id,
  4525. 'type' => 1,
  4526. 'remark' => '客户回收',
  4527. 'employee_id' => $this->request->token['employee_id'],
  4528. 'user_id' => $this->request->token['uid'],
  4529. 'state' => ''
  4530. ];
  4531. CustomerVisitLog::create($param);
  4532. } else {
  4533. Db::rollback();
  4534. }
  4535. }
  4536. return json(['code' => self::success, 'msg' => '回收成功']);
  4537. }
  4538. public function drop_to_pool_check()
  4539. {
  4540. $ids = input('id', '', 'trim');
  4541. $customer_list = Customer::where([['id', 'in', $ids]])->select();
  4542. $state_list = $customer_list->column('state');
  4543. $sign_state = Customer::changeState('签单', 'chaos');
  4544. $sign_count = 0;
  4545. foreach ($state_list as $k => $v) {
  4546. if (in_array($v, $sign_state)) {
  4547. $sign_count++;
  4548. }
  4549. }
  4550. $protected = 0;
  4551. $setting = Setting::where([['name', '=', 'pubpool'], ['root_id', '=', $this->request->token['root_org']]])->find();
  4552. if (!empty($setting)) {
  4553. $content = !empty($setting['content']) ? json_decode($setting['content'], true) : [];
  4554. if (!empty($content)) {
  4555. $empty = false; //判断是否是正常数据,因为之前可能有垃圾数据
  4556. foreach ($content as $k => $v) {
  4557. if (!isset($v['day']) || !isset($v['state'])) {
  4558. $empty = true;
  4559. }
  4560. }
  4561. if (!$empty) {
  4562. foreach ($customer_list as $k => $v) {
  4563. $n = Customer::changeState($v['state'], 'n');
  4564. foreach ($content as $kk => $vv) {
  4565. 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())) {
  4566. $protected++;
  4567. }
  4568. }
  4569. }
  4570. }
  4571. }
  4572. }
  4573. $msg = '';
  4574. if ($sign_count && $protected) {
  4575. $msg = '包含已签单及未到保护期客户';
  4576. } elseif ($sign_count) {
  4577. $msg = '包含已签单客户';
  4578. } elseif ($protected) {
  4579. $msg = '包含未到保护期客户';
  4580. }
  4581. if ($msg == '') {
  4582. return json(['code' => self::success, 'msg' => '']);
  4583. } else {
  4584. return json(['code' => self::error_msg, 'msg' => $msg]);
  4585. }
  4586. }
  4587. /**
  4588. * 客户互动 短信
  4589. */
  4590. public function sms($customerid, $type)
  4591. {
  4592. $num = CustomerSmsLog::where([['sendTime', 'between', [date('Ymd') . '000000', date('Ymd', strtotime('+1 day')) . '000000']], ['employee_id', '=', $this->request->token['employee_id']], ['state', '=', 0]])->count();
  4593. if ($num >= 3) return json(['code' => 1, 'msg' => '今日短信条数已用尽']);
  4594. $customer = Customer::where([['id', '=', $customerid]])->find();
  4595. if (empty($customer)) return json(['code' => 1, 'msg' => '客户不存在']);
  4596. if ($customer->employee_id != $this->request->token['employee_id'] && $customer->designer_id != $this->request->token['employee_id']) {
  4597. if (isset($this->request->token['isManager']) && $this->request->token['isManager']) {
  4598. $orgidList = orgSubIds($this->request->token['org_id']);
  4599. $checkOrg = -1;
  4600. if ($this->request->token['org_type'] == 2 && !empty($customer->designer_id)) {
  4601. $checkOrg = Employee::where(['id' => $customer->designer_id])->value('org_id');
  4602. } elseif ($this->request->token['org_type'] == 1) {
  4603. $checkOrg = Employee::where(['id' => $customer->employee_id])->value('org_id');
  4604. }
  4605. if (!in_array($checkOrg, $orgidList))
  4606. return json(['code' => 1, 'msg' => '客户不存在']);
  4607. }
  4608. }
  4609. $param = $this->request->param();
  4610. // 存储参数
  4611. $data = [
  4612. 'content' => json_encode($param),
  4613. 'type' => 'share'
  4614. ];
  4615. $shortUrl = ShortUrl::create($data);
  4616. // 将ID进行
  4617. $uri = dec52($shortUrl->id);
  4618. $shortUrl->uri = $uri;
  4619. $shortUrl->save();
  4620. $typeContentList = [
  4621. 'employeeCard' => '我的个人名片',
  4622. 'screen' => '我推荐的内容',
  4623. 'materialCase' => '我推荐的装修案例',
  4624. 'evidenceCate' => '我推荐的公司口碑',
  4625. ];
  4626. $typeContent = $typeContentList[$type];
  4627. $companyName = Org::where([['id', '=', $this->request->token['root_org']]])->value('name');
  4628. $employee_name = Employee::where([['id', '=', $this->request->token['employee_id']]])->value('name');
  4629. $domain = request()->domain();
  4630. $content = '【装修宝】老师您好, 我是{$var}的{$var},这是{$var}, 请您查看' . $domain . '/{$var}';
  4631. $param = "{$customer->phone},{$companyName},{$employee_name},{$typeContent},{$uri}";
  4632. $smsObj = new ChuanglanSmsApi();
  4633. $result = $smsObj->sendVariableSMS($content, $param);
  4634. $rs = json_decode($result, true);
  4635. if ($rs['code'] != 0) {
  4636. return json(['code' => 1, 'msg' => $rs['errorMsg']]);
  4637. }
  4638. // 创建发送记录
  4639. $log = [
  4640. 'customer_id' => $customerid,
  4641. 'employee_id' => $this->request->token['employee_id'],
  4642. 'org_type' => $this->request->token['org_type'],
  4643. 'type' => $type,
  4644. 'phone' => $customer->phone,
  4645. 'sendTime' => $rs['time'],
  4646. 'msgId' => $rs['msgId']
  4647. ];
  4648. CustomerSmsLog::create($log);
  4649. return json(['code' => 0, 'msg' => '发送成功']);
  4650. }
  4651. /**
  4652. * 短信发送记录
  4653. */
  4654. public function smslog($id)
  4655. {
  4656. $customer = Customer::where(['id' => $id])->find();
  4657. if (empty($customer)) return json(['code' => 0, 'data' => []]);
  4658. // 检测客户所属(部门领导查看,设计师查看,销售查看,销售的部门领导)
  4659. if ($customer->employee_id != $this->request->token['employee_id'] && $customer->designer_id != $this->request->token['employee_id']) {
  4660. if (isset($this->request->token['isManager']) && $this->request->token['isManager']) {
  4661. $orgidList = orgSubIds($this->request->token['org_id']);
  4662. $checkOrg = -1;
  4663. if ($this->request->token['org_type'] == 2 && !empty($customer->designer_id)) {
  4664. $checkOrg = Employee::where(['id' => $customer->designer_id])->value('org_id');
  4665. } elseif ($this->request->token['org_type'] == 1) {
  4666. $checkOrg = Employee::where(['id' => $customer->employee_id])->value('org_id');
  4667. }
  4668. if (!in_array($checkOrg, $orgidList))
  4669. return json(['code' => 0, 'data' => []]);
  4670. }
  4671. }
  4672. // 查询记录
  4673. // $page = $this->request->only(['page', 'limit']);
  4674. // $log = CustomerSmsLog::with('employee')->field('id,type,errorMsg')->where(['customer_id' => $id])->page($page['page'], $page['limit'])->order('id desc')->select();
  4675. $log = CustomerSmsLog::with('employee')->field('id,type,errorMsg,state,sendTime,employee_id,org_type')->where(['customer_id' => $id])->order('id desc')->select();
  4676. return json(['code' => 0, 'data' => $log]);
  4677. }
  4678. /**
  4679. * 获取提醒和跟进最新时间
  4680. */
  4681. public function get_date()
  4682. {
  4683. $token = $this->request->token;
  4684. $w[] = ['employee_id', '=', $token['employee_id']];
  4685. //我的客户
  4686. $cids = Customer::where($w)->column('id');
  4687. $state1 = CustomerVisitLog::changeState('预约量房', 'chaos');
  4688. $state2 = CustomerVisitLog::changeState('预约到店', 'chaos');
  4689. $state3 = CustomerVisitLog::changeState('预约活动', 'chaos');
  4690. // //提醒的最新时间
  4691. // $w1[] = ['customer_id', 'in', $cids];
  4692. // $w1[] = ['state', 'in', array_merge($state1, $state2, $state3)];
  4693. // $date = CustomerVisitLog::where($w1)->order('next_contact_date desc')->value('next_contact_date');
  4694. // $date = $date ? (strtotime($date) >= strtotime(date('Y-m')) ? date('Y-m', strtotime($date)) : date('Y-m')) : '';
  4695. //跟进的最新时间
  4696. $state4 = CustomerVisitLog::changeState('无效', 'chaos');
  4697. //$state5 = CustomerVisitLog::changeState('预约回访', 'chaos');
  4698. $state = array_merge($state1, $state2, $state3, $state4);
  4699. $w2[] = ['customer_id', 'in', $cids];
  4700. $w2[] = ['state', 'not in', $state];
  4701. $date1 = CustomerVisitLog::where($w2)->order('next_contact_date desc')->value('next_contact_date');
  4702. $date1 = $date1 ? (strtotime($date1) >= strtotime(date('Y-m')) ? date('Y-m', strtotime($date1)) : date('Y-m')) : '';
  4703. $date = CustomersSubscribe::where([
  4704. ['employee_id|designer_id', '=', $token['employee_id']],
  4705. ['state', '=', 0]
  4706. ])->order('subscribe_date desc')->value('subscribe_date');
  4707. $date = $date ? (strtotime($date) >= strtotime(date('Y-m')) ? date('Y-m', strtotime($date)) : date('Y-m')) : '';
  4708. $res['remind'] = $date;
  4709. $res['followup'] = $date1;
  4710. return json(['code' => 0, 'data' => $res]);
  4711. }
  4712. /**
  4713. * 客户预约记录
  4714. */
  4715. public function subscribe($id)
  4716. {
  4717. // 检测是否是我的客户
  4718. $customer = Customer::where(['id' => $id])->find();
  4719. if (empty($customer)) return json(['code' => 0, 'data' => []]);
  4720. // 检测客户所属(部门领导查看,设计师查看,销售查看,销售的部门领导)
  4721. if ($customer->employee_id != $this->request->token['employee_id'] && $customer->designer_id != $this->request->token['employee_id']) {
  4722. if (isset($this->request->token['isManager']) && $this->request->token['isManager']) {
  4723. $orgidList = orgSubIds($this->request->token['org_id']);
  4724. $checkOrg = -1;
  4725. if ($this->request->token['org_type'] == 2 && !empty($customer->designer_id)) {
  4726. $checkOrg = Employee::where(['id' => $customer->designer_id])->value('org_id');
  4727. } elseif ($this->request->token['org_type'] == 1) {
  4728. $checkOrg = Employee::where(['id' => $customer->employee_id])->value('org_id');
  4729. }
  4730. if (!in_array($checkOrg, $orgidList))
  4731. return json(['code' => 0, 'data' => []]);
  4732. } else {
  4733. return json(['code' => 0, 'data' => []]);
  4734. }
  4735. }
  4736. // 查询记录
  4737. $data = CustomersSubscribe::withoutField('org_id')->with(['employee' => function ($query) {
  4738. $query->withfield(['id', 'name']);
  4739. }, 'designer' => function ($query) {
  4740. $query->withfield(['id', 'name']);
  4741. }])->where([['customer_id', '=', $customer->id]])->order('addtime desc')->select();
  4742. return json(['code' => 0, 'data' => $data]);
  4743. }
  4744. /**
  4745. * 未回访记录
  4746. */
  4747. public function notVisitLog($page = 1, $date = null, $keyword = null)
  4748. {
  4749. // 判断当前登陆人是不是领导
  4750. if (!$this->request->token['isManager']) return json(['code' => 0, 'data' => []]);
  4751. $cOrgId = (new Org())->getChildOrg($this->request->token['org_id']);
  4752. $condition = [
  4753. ['org_id', 'in', $cOrgId]
  4754. ];
  4755. $orCondition = [];
  4756. if ($date) $condition[] = ['appoint_date', '=', $date];
  4757. if (!empty($keyword)) {
  4758. $guodu = CustomerNotVisit::where($condition)->column('customer_id,employee_id,designer_id,org_id');
  4759. if (empty($guodu)) return json(['code' => 0, 'data' => []]);
  4760. $customerIdLIst = Customer::where([['id', 'in', array_column($guodu, 'customer_id')], ['name', 'like', '%' . $keyword . '%']])->column('id');
  4761. $employeeIdList = Employee::where([
  4762. ['name', 'like', '%' . $keyword . '%'],
  4763. ['id', 'in', array_column($guodu, 'employee_id')]
  4764. ])->column('id');
  4765. $designerIdList = Employee::where([
  4766. ['name', 'like', '%' . $keyword . '%'],
  4767. ['id', 'in', array_column($guodu, 'designer_id')]
  4768. ])->column('id');
  4769. $orgIdList = Org::where([
  4770. ['name', 'like', '%' . $keyword . '%'],
  4771. ['id', 'in', array_column($guodu, 'org_id')]
  4772. ])->column('id');
  4773. $orCondition = [
  4774. ['employee_id', 'in', $employeeIdList],
  4775. ['designer_id', 'in', $designerIdList],
  4776. ['org_id', 'in', $orgIdList],
  4777. ['customer_id', 'in', $customerIdLIst]
  4778. ];
  4779. }
  4780. $data = CustomerNotVisit::with([
  4781. 'customer' => function ($query) {
  4782. $query->withField(['id', 'name', 'sex', 'level', 'community_name']);
  4783. },
  4784. 'employee' => function ($query) {
  4785. $query->withField(['id', 'name']);
  4786. },
  4787. 'designer' => function ($query) {
  4788. $query->withField(['id', 'name']);
  4789. },
  4790. 'org' => function ($query) {
  4791. $query->withField(['id', 'name']);
  4792. }
  4793. ])->where(function ($query) use ($orCondition) {
  4794. $query->whereOr($orCondition);
  4795. })->where($condition)
  4796. ->page($page, 30)
  4797. ->order('addtime desc')
  4798. ->select();
  4799. return json(['code' => 0, 'data' => $data]);
  4800. }
  4801. /**
  4802. * 客户报备自定义
  4803. * type:add根据后台勾选展示,edit展示全部
  4804. */
  4805. public function get_portrait_field()
  4806. {
  4807. $id = input('id', '', 'trim');
  4808. $type = input('type');
  4809. $token = $this->request->token;
  4810. $where = [
  4811. ['root_id', '=', $token['root_org']],
  4812. ['pid', '>', 0],
  4813. ['status', '=', 0]
  4814. ];
  4815. if ($type == 'add') {
  4816. $setting = Setting::where([['name', '=', 'settingCustomerReportField'], ['root_id', '=', $token['root_org']]])->find();
  4817. if ($setting && !empty($setting['content'])) {
  4818. $all_content = json_decode($setting['content'], true);
  4819. $field_id = array_column($all_content, 'id');
  4820. $where[] = ['id', 'in', $field_id];
  4821. } else {
  4822. //默认值
  4823. $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']];
  4824. }
  4825. }
  4826. //获取第二层
  4827. $all = CustomerPortraitField::with(['select'])->where($where)->orderRaw('if(isnull(sort),1,0),sort asc')->select()->toArray();
  4828. if ($type == 'add' && $setting && !empty($setting['content'])) {
  4829. //如果是设置自定义展示,则循序按照勾选的排序进行组装
  4830. $all_new = [];
  4831. foreach ($all_content as $c) {
  4832. foreach ($all as $vals) {
  4833. if ($c['id'] == $vals['id']) {
  4834. $all_new[] = $vals;
  4835. }
  4836. }
  4837. }
  4838. $all = $all_new;
  4839. }
  4840. $city = Company::where('root_id', $token['root_org'])->value('city');
  4841. foreach ($all as &$val) {
  4842. if ($val['keyname'] == 'current_region') {
  4843. $val['select'][] = ['id' => $token['root_org'], 'name' => $city, 'pid' => $val['id']];
  4844. }
  4845. if ($val['keyname'] == 'source_id') {
  4846. $val['select'] = CustomerSource::field('id,source as name')->where('root_id', $token['root_org'])->select()->toArray();
  4847. }
  4848. if ($val['keyname'] == 'deco_style') {
  4849. $val['select'] = Decostyle::field('id,name')->where([['root_id', '=', $token['root_org']], ['type', '=', 0]])->select()->toArray();
  4850. }
  4851. }
  4852. //获取第一层
  4853. $pid = array_column($all, 'pid');
  4854. $list = CustomerPortraitField::where([['id', 'in', $pid], ['status', '=', 0], ['pid', '=', 0]]);
  4855. if ($type == 'add' && $setting && !empty($setting['content'])) {
  4856. //如果是添加页面,把自定义字段追加到基本信息child下
  4857. $list = $list->order('id')->limit(1)->select()->toArray();
  4858. } else {
  4859. $list = $list->orderRaw('if(isnull(sort),1,0),sort asc')->select()->toArray();
  4860. }
  4861. //组装数组
  4862. foreach ($list as &$p) {
  4863. foreach ($all as &$item) {
  4864. $item['value'] = '';
  4865. $item['valname'] = '';
  4866. if ($type == 'add' && $setting && !empty($setting['content'])) {
  4867. $p['child'][] = $item;
  4868. } else {
  4869. if ($p['id'] == $item['pid']) $p['child'][] = $item;
  4870. }
  4871. }
  4872. }
  4873. $cuslog = new CustomerLogic;
  4874. if (isset($id) && !empty($id)) {
  4875. $cusdata = Customer::where([['id', '=', $id]])->find()->toArray();
  4876. if (!empty($cusdata['ext']) && $cusdata['ext'] != 'null') {
  4877. $extdata = json_decode($cusdata['ext'], true);
  4878. if (isset($extdata['ext1'])) {
  4879. $list = $cuslog->old_data_save($cusdata, $list);
  4880. } else {
  4881. $list = $cuslog->new_data_save($cusdata, $extdata, $list);
  4882. }
  4883. } else {
  4884. $list = $cuslog->no_ext_save($cusdata, $list);
  4885. }
  4886. }
  4887. return json(['code' => 0, 'msg' => '获取成功', 'data' => $list]);
  4888. }
  4889. /**
  4890. * 手机端验证报名客户必填字段
  4891. */
  4892. public function check_must_field($ext)
  4893. {
  4894. $token = $this->request->token;
  4895. $house_type_value = '';
  4896. $live_broadcast_value = [];
  4897. foreach ($ext as $key => $val) {
  4898. if ($val['keyname'] == 'house_type' && !empty($val['value'])) {
  4899. $house_type_value = CustomerPortraitFieldSelect::where([['pid', '=', $val['id']], ['id', '=', $val['value']]])->value('name');
  4900. }
  4901. if ($val['keyname'] == 'live_broadcast' && !empty($val['value'])) {
  4902. $live_broadcast_value = CustomerPortraitFieldSelect::where([['pid', '=', $val['id']], ['id', 'in', explode(',', $val['value'])]])->column('name');
  4903. }
  4904. }
  4905. //判断必填项
  4906. $must_list = CustomerPortraitField::where([['root_id', '=', $token['root_org']], ['pid', '<>', 0], ['is_must', '=', 0]])->column('name', 'keyname');
  4907. foreach ($ext as $key => $val) {
  4908. if ($house_type_value != '期房' && $val['keyname'] == 'house_delivery_time' && in_array($val['keyname'], array_keys($must_list))) continue;
  4909. if (!in_array('1对1业务直播', $live_broadcast_value) && $val['keyname'] == 'live_broadcast_business' && in_array($val['keyname'], array_keys($must_list))) continue;
  4910. if (!in_array('1对1设计直播', $live_broadcast_value) && $val['keyname'] == 'live_broadcast_design' && in_array($val['keyname'], array_keys($must_list))) continue;
  4911. if (!in_array('一对多直播', $live_broadcast_value) && $val['keyname'] == 'live_broadcast_personnel' && in_array($val['keyname'], array_keys($must_list))) continue;
  4912. if (in_array($val['keyname'], array_keys($must_list)) && empty($val['value'])) {
  4913. return json(['code' => 1, 'msg' => $must_list[$val['keyname']] . '为必填项']);
  4914. }
  4915. }
  4916. }
  4917. //新添加客户扩展字段
  4918. public function add_customer_extfield()
  4919. {
  4920. $token = $this->request->token;
  4921. $ext = input('ext', '', 'trim');
  4922. $id = input('id');
  4923. $subOrg = orgSubIds($token['root_org']);
  4924. $cda = Customer::find($id);
  4925. if (empty($cda) || !in_array($cda['org_id'], $subOrg)) {
  4926. return json(['code' => 1, 'msg' => '客户数据为空']);
  4927. }
  4928. if (empty($ext)) return json(['code' => 1, 'msg' => '暂未设置数据']);
  4929. $seldata = CustomerPortraitField::with(['select'])->where([['root_id', '=', $token['root_org']], ['type', 'in', [3, 4]]])->select()->toArray();
  4930. $allselid = [];
  4931. foreach ($seldata as $key => $val) {
  4932. foreach ($val['select'] as $k => $v) {
  4933. $allselid[] = ['id' => $v['id'], 'name' => $v['name']];
  4934. }
  4935. }
  4936. foreach ($ext as $key => $val) {
  4937. $selval = '';
  4938. if ($val['keyname'] == 'community_name') {
  4939. $house_data['community_name'] = $val['value'];
  4940. }
  4941. if ($val['keyname'] == 'square') {
  4942. $house_data['square'] = $val['value'];
  4943. }
  4944. if ($val['keyname'] == 'house_type') {
  4945. foreach ($allselid as $k => $v) {
  4946. if ($val['value'] == $v['id']) {
  4947. $selval = $v['name'];
  4948. }
  4949. }
  4950. $house_data['house_type'] = $selval;
  4951. }
  4952. if ($val['keyname'] == 'house_status') {
  4953. foreach ($allselid as $k => $v) {
  4954. if ($val['value'] == $v['id']) {
  4955. $selval = $v['name'];
  4956. }
  4957. }
  4958. $house_data['house_status'] = $selval;
  4959. }
  4960. if ($val['keyname'] == 'house_delivery_time') {
  4961. $house_data['house_delivery_time'] = $val['value'];
  4962. }
  4963. if ($val['keyname'] == 'plan_deco_time') {
  4964. $house_data['plan_deco_time'] = $val['value'];
  4965. }
  4966. if ($val['keyname'] == 'budget') {
  4967. $house_data['budget'] = $val['value'];
  4968. }
  4969. if ($val['keyname'] == 'deco_style') {
  4970. foreach ($allselid as $k => $v) {
  4971. if ($val['value'] == $v['id']) {
  4972. $selval = $v['name'];
  4973. }
  4974. }
  4975. $house_data['deco_style'] = $selval;
  4976. }
  4977. if ($val['keyname'] == 'follow') {
  4978. if (!empty($val['value'])) {
  4979. $gza = explode(',', $val['value']);
  4980. foreach ($allselid as $k => $v) {
  4981. if (in_array($v['id'], $gza)) {
  4982. $selval .= $v['name'] . ',';
  4983. }
  4984. }
  4985. }
  4986. $house_data['product'] = trim($selval, ',');
  4987. }
  4988. if ($val['type'] == 6 && !empty($val['value'])) {
  4989. //上传图片类型
  4990. $file_media_id = [];
  4991. foreach ($val['value'] as $k => $img) {
  4992. $file_media_id[$k] = [
  4993. 'serverId' => !empty($img['serverId']) ? $img['serverId'] : '',
  4994. 'img' => !empty($img['img']) ? str_replace('https://' . config('app.ali_oss_bindurl') . '/', '', $img['img']) : ''
  4995. ];
  4996. }
  4997. $house_data['ext_down_status'] = 1;
  4998. $ext[$key]['value'] = json_encode($file_media_id);
  4999. } else {
  5000. //清除type类型
  5001. unset($ext[$key]['type']);
  5002. }
  5003. }
  5004. $c_logic = new CustomerLogic();
  5005. if (!empty($cda['ext']) && $cda['ext'] != 'null') {
  5006. $extdata = json_decode($cda['ext'], true);
  5007. if (isset($extdata['ext1'])) {
  5008. $new_ext = CustomerPortraitField::where([['root_id', '=', $token['root_org']], ['pid', '<>', 0]])->select()->toArray();
  5009. $c_logic->check_old_updatefield($cda, $ext, $new_ext, $token);
  5010. $ext = $c_logic->old_ext_edit($cda, $ext, $new_ext);
  5011. } else {
  5012. $c_logic->check_new_updatefield($cda, $ext, $token);
  5013. $ext = $c_logic->new_ext_edit($cda, $ext);
  5014. }
  5015. }
  5016. if (empty($cda['ext'])) $c_logic->check_not_updatefield($cda, $ext, $token);
  5017. $house_data['ext'] = json_encode($ext);
  5018. $ms = $cda->save($house_data);
  5019. // 微爆加微监听
  5020. $new_info = Customer::find($id);
  5021. if ($new_info['add_wechat_time'] && empty($cda['add_wechat_time'])) {
  5022. $i_data['add_wechat_time'] = $new_info['add_wechat_time'];
  5023. $i_data['customer_id'] = $id;
  5024. $i_data['employee_id'] = $new_info['employee_id'];
  5025. $i_data['type'] = 1;
  5026. $i_data['org_id'] = $new_info['org_id'];
  5027. WechatActivityIntegral::addIntegral($i_data, $token['root_org']);
  5028. }
  5029. Console::call('download', ['crm_ext_field']);
  5030. Console::call('download', ['save_portrait_field']);
  5031. if ($ms) {
  5032. return json(['code' => 0, 'msg' => '设置成功']);
  5033. } else {
  5034. return json(['code' => 1, 'msg' => '设置失败']);
  5035. }
  5036. }
  5037. /**
  5038. * 客户迁移
  5039. */
  5040. public function customerTransfer()
  5041. {
  5042. $param = $this->request->only(['customer_ids' => '', 'employee_id']);
  5043. $root_id = request()->token['root_org'];
  5044. $subOrg = orgSubIds($root_id);
  5045. $arr = explode(',', $param['customer_ids']);
  5046. $customers = Customer::where([['id', 'in', $arr], ['org_id', 'in', $subOrg]])->column('id,name,phone,phone1,phone2,employee_id');
  5047. $employee = Employee::find($param['employee_id']);
  5048. if (empty($customers) || empty($employee) || !in_array($employee['org_id'], $subOrg)) {
  5049. return json(['code' => 0, 'msg' => '迁移完成']);
  5050. }
  5051. // 要转移的客户电话合集 这个电话属于谁
  5052. $transfer_phones = [];
  5053. $phone_employee = [];
  5054. foreach ($customers as $k => $v) {
  5055. $v_phone = array_filter([$v['phone'], $v['phone1'], $v['phone2']]);
  5056. $transfer_phones = array_merge($transfer_phones, $v_phone);
  5057. if (empty($phone_employee[$v['employee_id']])) {
  5058. $phone_employee[$v['employee_id']] = $v_phone;
  5059. } else {
  5060. $phone_employee[$v['employee_id']] = array_merge($phone_employee[$v['employee_id']], $v_phone);
  5061. }
  5062. }
  5063. $all_ids = array_column($customers, 'id');
  5064. // 先判断撞单
  5065. // 同部门能否重复录入开关设置
  5066. $empcrm_repeat[] = ['root_id', '=', $root_id];
  5067. $empcrm_repeat[] = ['name', '=', 'empcrm_customer_repeat'];
  5068. $repeat_setting = Setting::where($empcrm_repeat)->findOrEmpty();
  5069. // 默认本部门不能撞单
  5070. if (!$repeat_setting->isEmpty()) {
  5071. $repeat_org = explode(',', $repeat_setting['content']);
  5072. if (!in_array($employee['org_id'], $repeat_org)) {
  5073. $repeat_org = [$employee['org_id']];
  5074. }
  5075. } else {
  5076. $repeat_org = [$employee['org_id']];
  5077. }
  5078. $ex_where[] = ['phone', 'in', $transfer_phones];
  5079. $ex_where[] = ['org_id', 'in', $repeat_org];
  5080. $ex_where[] = ['employee_id', '>', 0];
  5081. $ex_where[] = ['id', 'not in', $all_ids];
  5082. $customerExist = Customer::where($ex_where)->where(
  5083. function ($query) {
  5084. $not_sure = Customer::changeState('待确认', 'chaos');
  5085. $or1[] = ['crm_res_id', 'null', null];
  5086. $or2[] = ['crm_res_id', '>', 0];
  5087. $or2[] = ['state', 'not in', $not_sure];
  5088. $query->whereOr([$or1, $or2]);
  5089. }
  5090. )->column('id,name,phone,employee_id');
  5091. $repeat_ids = $repeat = $no_repeat = [];
  5092. if (!empty($customerExist)) {
  5093. foreach ($customerExist as $ex) {
  5094. $repeat[] = $ex['name'];
  5095. $repeat_ids[] = $ex['id'];
  5096. }
  5097. }
  5098. $no_repeat = array_diff($all_ids, $repeat_ids);
  5099. if ($no_repeat) {
  5100. $org_id = Employee::where('id', $param['employee_id'])->value('org_id');
  5101. Customer::where([['id', 'in', $no_repeat]])->update(['employee_id' => $param['employee_id'], 'org_id' => $org_id]);
  5102. //记录操作人信息PC端需要用到
  5103. 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']])]);
  5104. //修改转移的客户的跟进记录的customer_employee_id为新员工的id
  5105. CustomerVisitLog::where([['customer_id', 'in', $no_repeat], ['org_id', 'in', $subOrg]])->update(['customer_employee_id' => $param['employee_id'], 'customer_org_id' => $org_id]);
  5106. }
  5107. if ($repeat) return json(['code' => 1, 'msg' => '迁移失败:[' . implode(',', $repeat) . ']撞单或员工名下已存在客户']);
  5108. return json(['code' => 0, 'msg' => '迁移完成']);
  5109. }
  5110. /**
  5111. * 客户自定义模块显示控制
  5112. */
  5113. public function moduleSwitch()
  5114. {
  5115. $root_id = $this->request->token['root_org'];
  5116. // 客户信息完善开关
  5117. $perfect_find = Setting::where([['root_id', '=', $root_id], ['name', '=', 'modulePerfectSwitch']])->findOrEmpty();
  5118. if ($perfect_find->isEmpty()) {
  5119. $perfect = 1;
  5120. } else {
  5121. $perfect = $perfect_find['content'];
  5122. }
  5123. $data['perfect'] = $perfect;
  5124. // 客户转化开关
  5125. $change_find = Setting::where([['root_id', '=', $root_id], ['name', '=', 'moduleChangeSwitch']])->findOrEmpty();
  5126. if ($change_find->isEmpty()) {
  5127. $change = 1;
  5128. } else {
  5129. $change = $change_find['content'];
  5130. }
  5131. $data['change'] = $change;
  5132. // 客户预约开关
  5133. $subscribe_find = Setting::where([['root_id', '=', $root_id], ['name', '=', 'moduleSubscribeSwitch']])->findOrEmpty();
  5134. if ($subscribe_find->isEmpty()) {
  5135. $subscribe = 1;
  5136. } else {
  5137. $subscribe = $subscribe_find['content'];
  5138. }
  5139. $data['subscribe'] = $subscribe;
  5140. return json(['code' => 0, 'data' => $data]);
  5141. }
  5142. /**
  5143. * 客户跟踪快速标签
  5144. */
  5145. public function clueTag()
  5146. {
  5147. $where[] = ['name', '=', 'clueTag'];
  5148. $where[] = ['root_id', '=', $this->request->token['root_org']];
  5149. $find = Setting::where($where)->findOrEmpty();
  5150. if ($find->isEmpty()) {
  5151. $list = ['已装修', '无需求', '有需求', '超地域', '未交房', '在外地', '无购买力', '未接通电话'];
  5152. } else {
  5153. $list = array_filter(explode(',', $find['content']));
  5154. }
  5155. return json(['code' => 0, 'data' => $list]);
  5156. }
  5157. /**
  5158. * 客户跟踪字段
  5159. */
  5160. public function visitField()
  5161. {
  5162. $id = input('id', '', 'intval');
  5163. $token = $this->request->token;
  5164. $v_where[] = ['root_id', '=', $token['root_org']];
  5165. $v_where[] = ['name', '=', 'visitSettingField'];
  5166. $visitField = Setting::where($v_where)->findOrEmpty();
  5167. $field = [];
  5168. if (!$visitField->isEmpty()) {
  5169. $v_field = !empty($visitField['content']) ? json_decode($visitField['content'], true) : [];
  5170. $ids = !empty($v_field) ? array_column($v_field, 'id') : [];
  5171. $v_list = CustomerPortraitField::with(['select'])->where('id', 'in', $ids)->select()->toArray();
  5172. foreach ($v_field as $k => $v) {
  5173. foreach ($v_list as $kk => $vv) {
  5174. if ($v['id'] == $vv['id']) {
  5175. $field[] = $vv;
  5176. }
  5177. }
  5178. }
  5179. } else {
  5180. $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();
  5181. }
  5182. $city = Company::where('root_id', $token['root_org'])->value('city');
  5183. foreach ($field as $k => $v) {
  5184. if ($v['keyname'] == 'current_region') {
  5185. $field[$k]['select'][] = ['id' => $token['root_org'], 'name' => $city, 'pid' => $v['pid']];
  5186. }
  5187. if ($v['keyname'] == 'source_id') {
  5188. $soudata = CustomerSource::field('id,source as name')->where('root_id', $token['root_org'])->select()->toArray();
  5189. $field[$k]['select'] = $soudata;
  5190. }
  5191. if ($v['keyname'] == 'deco_style') {
  5192. $decostyles = Decostyle::field('id,name')->where([['root_id', '=', $token['root_org']], ['type', '=', 0]])->select()->toArray();
  5193. $field[$k]['select'] = $decostyles;
  5194. }
  5195. }
  5196. if (!empty($id)) {
  5197. $c_logic = new CustomerLogic();
  5198. $cusdata = Customer::where([['id', '=', $id]])->find()->toArray();
  5199. if (!empty($cusdata['ext']) && $cusdata['ext'] != 'null') {
  5200. // $extdata=get_object_vars($cusdata['ext']);
  5201. $extdata = json_decode($cusdata['ext'], true);
  5202. if (isset($extdata['ext1'])) {
  5203. $field = $c_logic->old_data_saves($cusdata, $field);
  5204. } else {
  5205. $field = $c_logic->new_data_saves($cusdata, $extdata, $field);
  5206. }
  5207. } else {
  5208. $field = $c_logic->no_ext_saves($cusdata, $field);
  5209. }
  5210. }
  5211. return json(['code' => 0, 'data' => $field]);
  5212. }
  5213. /**
  5214. * 客户转化自定义设置
  5215. */
  5216. public function changeModule()
  5217. {
  5218. $id = input('id', '', 'intval');
  5219. $root_id = $this->request->token['root_org'];
  5220. // 子模块开关 量房、到店、活动、签单、转单、卖卡
  5221. $switch_where[] = ['name', 'in', ['changeSettingSwitchLF', 'changeSettingSwitchDD', 'changeSettingSwitchHD', 'changeSettingSwitchJD', 'changeSettingSwitchZD', 'changeSettingSwitchMK', 'changeSettingSwitchDDHD']];
  5222. $switch_where[] = ['root_id', '=', $root_id];
  5223. $z_setting = Setting::where($switch_where)->select()->toArray();
  5224. $lf_switch = 1; //量房
  5225. $dd_switch = 1; //到店
  5226. $hd_switch = 1; //活动
  5227. $jd_switch = 1; //签单 (交定)
  5228. $zd_switch = 1; //转单
  5229. $mk_switch = 1; //卖卡
  5230. $ddhd_switch = 1; //到店活动
  5231. foreach ($z_setting as $k => $v) {
  5232. if ($v['name'] == 'changeSettingSwitchLF') $lf_switch = $v['content'];
  5233. if ($v['name'] == 'changeSettingSwitchDD') $dd_switch = $v['content'];
  5234. if ($v['name'] == 'changeSettingSwitchHD') $hd_switch = $v['content'];
  5235. if ($v['name'] == 'changeSettingSwitchJD') $jd_switch = $v['content'];
  5236. if ($v['name'] == 'changeSettingSwitchZD') $zd_switch = $v['content'];
  5237. if ($v['name'] == 'changeSettingSwitchMK') $mk_switch = $v['content'];
  5238. if ($v['name'] == 'changeSettingSwitchDDHD') $ddhd_switch = $v['content'];
  5239. }
  5240. $data['lf']['show'] = $lf_switch;
  5241. $data['dd']['show'] = $dd_switch;
  5242. $data['hd']['show'] = $hd_switch;
  5243. $data['jd']['show'] = $jd_switch;
  5244. $data['zd']['show'] = $zd_switch;
  5245. $data['mk']['show'] = $mk_switch;
  5246. $data['ddhd']['show'] = $ddhd_switch;
  5247. $city = Company::where('root_id', $root_id)->value('city');
  5248. if (!empty($id)) {
  5249. $cusdata = Customer::where([['id', '=', $id]])->find()->toArray();
  5250. }
  5251. $array = ['LF', 'DD', 'HD', 'JD', 'ZD', 'MK'];
  5252. foreach ($array as $k => $v) {
  5253. $lower = strtolower($v);
  5254. unset($c_where);
  5255. $c_where[] = ['root_id', '=', $root_id];
  5256. $c_where[] = ['name', '=', 'changeSettingField' . $v];
  5257. $changeField = Setting::where($c_where)->findOrEmpty();
  5258. $new_list = [];
  5259. if (!$changeField->isEmpty()) {
  5260. $changeField_decode = !empty($changeField['content']) ? json_decode($changeField['content'], true) : [];
  5261. $ids_one = array_column($changeField_decode, 'id');
  5262. $ids_list = CustomerPortraitField::with('select')->where('id', 'in', $ids_one)->select()->toArray();
  5263. foreach ($changeField_decode as $kk => $vv) {
  5264. foreach ($ids_list as $vvv) {
  5265. if ($vv['id'] == $vvv['id']) {
  5266. $new_list[] = $vvv;
  5267. }
  5268. }
  5269. }
  5270. } elseif ($v == 'JD') {
  5271. $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();
  5272. }
  5273. foreach ($new_list as $kk => $vv) {
  5274. if ($vv['keyname'] == 'current_region') {
  5275. $new_list[$kk]['select'][] = ['id' => $root_id, 'name' => $city, 'pid' => $vv['pid']];
  5276. }
  5277. if ($vv['keyname'] == 'source_id') {
  5278. $soudata = CustomerSource::field('id,source as name')->where('root_id', $root_id)->select()->toArray();
  5279. $new_list[$kk]['select'] = $soudata;
  5280. }
  5281. if ($vv['keyname'] == 'deco_style') {
  5282. $decostyles = Decostyle::field('id,name')->where([['root_id', '=', $root_id], ['type', '=', 0]])->select()->toArray();
  5283. $new_list[$kk]['select'] = $decostyles;
  5284. }
  5285. }
  5286. $c_logic = new CustomerLogic();
  5287. if (!empty($id)) {
  5288. if (!empty($cusdata['ext']) && $cusdata['ext'] != 'null') {
  5289. // $extdata=get_object_vars($cusdata['ext']);
  5290. $extdata = json_decode($cusdata['ext'], true);
  5291. if (isset($extdata['ext1'])) {
  5292. $new_list = $c_logic->old_data_saves($cusdata, $new_list);
  5293. } else {
  5294. $new_list = $c_logic->new_data_saves($cusdata, $extdata, $new_list);
  5295. }
  5296. } else {
  5297. $new_list = $c_logic->no_ext_saves($cusdata, $new_list);
  5298. }
  5299. }
  5300. $data[$lower]['field'] = $new_list;
  5301. }
  5302. return json(['code' => 0, 'data' => $data]);
  5303. }
  5304. /**
  5305. * 客户预约自定义设置
  5306. */
  5307. public function subscribeModule()
  5308. {
  5309. $id = input('id', '', 'intval');
  5310. $root_id = $this->request->token['root_org'];
  5311. // 子模块开关 活动、到店、量房
  5312. $switch_where[] = ['name', 'in', ['subscribeSettingSwitchYYLF', 'subscribeSettingSwitchYYDD', 'subscribeSettingSwitchYYHD']];
  5313. $switch_where[] = ['root_id', '=', $root_id];
  5314. $z_setting = Setting::where($switch_where)->select()->toArray();
  5315. $hd_switch = 1; //活动
  5316. $dd_switch = 1; //到店
  5317. $lf_switch = 1; //量房
  5318. foreach ($z_setting as $k => $v) {
  5319. if ($v['name'] == 'subscribeSettingSwitchYYLF') $lf_switch = $v['content'];
  5320. if ($v['name'] == 'subscribeSettingSwitchYYDD') $dd_switch = $v['content'];
  5321. if ($v['name'] == 'subscribeSettingSwitchYYHD') $hd_switch = $v['content'];
  5322. }
  5323. $data['lf']['show'] = $lf_switch;
  5324. $data['dd']['show'] = $dd_switch;
  5325. $data['hd']['show'] = $hd_switch;
  5326. $city = Company::where('root_id', $root_id)->value('city');
  5327. if (!empty($id)) {
  5328. $cusdata = Customer::where([['id', '=', $id]])->find()->toArray();
  5329. }
  5330. $array = ['YYHD', 'YYDD', 'YYLF'];
  5331. foreach ($array as $k => $v) {
  5332. $lower = strtolower($v);
  5333. unset($sub_where);
  5334. $sub_where[] = ['root_id', '=', $root_id];
  5335. $sub_where[] = ['name', '=', 'subscribeSettingField' . $v];
  5336. $subscribeField = Setting::where($sub_where)->findOrEmpty();
  5337. $new_list = [];
  5338. if (!$subscribeField->isEmpty()) {
  5339. $subscribeField_decode = !empty($subscribeField['content']) ? json_decode($subscribeField['content'], true) : [];
  5340. $ids_one = array_column($subscribeField_decode, 'id');
  5341. $ids_list = CustomerPortraitField::with('select')->where('id', 'in', $ids_one)->select()->toArray();
  5342. foreach ($subscribeField_decode as $kk => $vv) {
  5343. foreach ($ids_list as $vvv) {
  5344. if ($vv['id'] == $vvv['id']) {
  5345. $new_list[] = $vvv;
  5346. }
  5347. }
  5348. }
  5349. }
  5350. foreach ($new_list as $kk => $vv) {
  5351. if ($vv['keyname'] == 'current_region') {
  5352. $new_list[$kk]['select'][] = ['id' => $root_id, 'name' => $city, 'pid' => $vv['pid']];
  5353. }
  5354. if ($vv['keyname'] == 'source_id') {
  5355. $soudata = CustomerSource::field('id,source as name')->where('root_id', $root_id)->select()->toArray();
  5356. $new_list[$kk]['select'] = $soudata;
  5357. }
  5358. if ($vv['keyname'] == 'deco_style') {
  5359. $decostyles = Decostyle::field('id,name')->where([['root_id', '=', $root_id], ['type', '=', 0]])->select()->toArray();
  5360. $new_list[$kk]['select'] = $decostyles;
  5361. }
  5362. }
  5363. if (!empty($id)) {
  5364. $c_logic = new CustomerLogic();
  5365. if (!empty($cusdata['ext']) && $cusdata['ext'] != 'null') {
  5366. $extdata = json_decode($cusdata['ext'], true);
  5367. if (isset($extdata['ext1'])) {
  5368. $new_list = $c_logic->old_data_saves($cusdata, $new_list);
  5369. } else {
  5370. $new_list = $c_logic->new_data_saves($cusdata, $extdata, $new_list);
  5371. }
  5372. } else {
  5373. $new_list = $c_logic->no_ext_saves($cusdata, $new_list);
  5374. }
  5375. }
  5376. $data[$lower]['field'] = $new_list;
  5377. }
  5378. return json(['code' => 0, 'data' => $data]);
  5379. }
  5380. /**
  5381. * 店面列表
  5382. */
  5383. public function shop_list()
  5384. {
  5385. $shop_list = Shop::where('root_id', '=', $this->request->token['root_org'])->select()->toArray();
  5386. return json(['code' => 0, 'data' => $shop_list]);
  5387. }
  5388. /**
  5389. * 申请死单
  5390. */
  5391. public function dieCustomer()
  5392. {
  5393. $customer_id = input('customer_id', '', 'intval');
  5394. $reason = input('reason', '', 'trim');
  5395. $find = Customer::where('id', '=', $customer_id)->findOrEmpty();
  5396. if ($find->isEmpty() || $find['employee_id'] != request()->token['employee_id']) {
  5397. return json(['code' => 1, 'msg' => '操作失败']);
  5398. }
  5399. $data['died'] = 1;
  5400. $data['died_reason'] = $reason;
  5401. $data['died_date'] = date('Y-m-d H:i:s', time());
  5402. $result = $find->save($data);
  5403. if ($result !== false) {
  5404. return json(['code' => 0, 'msg' => '操作成功']);
  5405. } else {
  5406. return json(['code' => 1, 'msg' => '操作失败']);
  5407. }
  5408. }
  5409. /**
  5410. * 操作设置
  5411. */
  5412. public function moduleHandel()
  5413. {
  5414. $root_id = request()->token['root_org'];
  5415. $setting = Setting::where([['root_id', '=', $root_id], ['name', '=', 'customerHandel']])->findOrEmpty();
  5416. if (!$setting->isEmpty()) {
  5417. $content = json_decode($setting['content'], true);
  5418. } else {
  5419. $content = [
  5420. 'wechat' => 1,
  5421. 'group_building' => 1,
  5422. 'live_broadcast' => 1
  5423. ];
  5424. }
  5425. return json(['code' => 0, 'data' => $content]);
  5426. }
  5427. /**
  5428. * 智慧屏 讲解链接
  5429. */
  5430. public function produceUrl()
  5431. {
  5432. $token = $this->request->token;
  5433. $param = request()->only(['customer_id' => 0]);
  5434. $str = $token['root_org'] . '#' . $token['employee_id'] . '#' . $param['customer_id'];
  5435. $aec = new Aec(config('app.aec_key'), config('app.aec_iv'));
  5436. $value = $aec->encrypt($str);
  5437. // $ali_oss_bindurl = config('app.ali_oss_bindurl');
  5438. // $url = 'https://' . $ali_oss_bindurl . '/' . 'dashboard/wisdom?token='.$value;
  5439. return json(['code' => 0, 'data' => $value]);
  5440. }
  5441. /**
  5442. * 获取小区
  5443. */
  5444. public function getCommunity()
  5445. {
  5446. $token = $this->request->token;
  5447. $name = input('name', '', 'trim');
  5448. if ($name) {
  5449. $where[] = ['name', 'like', '%' . $name . '%'];
  5450. }
  5451. $where[] = ['root_id', '=', $token['root_org']];
  5452. $list = Community::where($where)->order('addtime desc')->select()->toArray();
  5453. // 交房时间新增到了小区信息中,下方代码注释不再使用 2023-03-06
  5454. /* foreach ($list as $k => $v) {
  5455. $building = Building::where('community_id', '=', $v['id'])->order('addtime desc')->findOrEmpty();
  5456. if ($building->isEmpty()) {
  5457. $list[$k]['duetime'] = '';
  5458. } else {
  5459. $list[$k]['duetime'] = $building['duetime'];
  5460. }
  5461. } */
  5462. return json(['code' => 0, 'data' => $list, 'msg' => '获取成功']);
  5463. }
  5464. /**
  5465. * 小程序资源库分配 已分配客户列表
  5466. */
  5467. public function assignedCustomer()
  5468. {
  5469. $param = Request::only(['employee_id' => 0, 'crm_res_id' => 0, 'org_id' => 0, 'page' => 1, 'limit' => 10]);
  5470. $token = $this->request->token;
  5471. $root_id = $token['root_org'];
  5472. $subOrg = orgSubIds($root_id);
  5473. $p_where[] = ['org_id', 'in', $subOrg];
  5474. $p_where[] = ['pid|id', '=', $param['crm_res_id']];
  5475. $pid = CrmImportLog::where($p_where)->column('id');
  5476. $where[] = ['crm_res_id', 'in', $pid];
  5477. if ($param['employee_id']) {
  5478. $where[] = ['employee_id', '=', $param['employee_id']];
  5479. } elseif ($param['org_id']) {
  5480. $where[] = ['org_id', '=', $param['org_id']];
  5481. $where[] = ['is_resource', '=', 1];
  5482. $where[] = ['employee_id', 'NULL', null];
  5483. } else {
  5484. return json(['code' => 0, 'data' => [], 'count' => 0, 'msg' => '获取成功']);
  5485. }
  5486. $list = Customer::where($where)->page($param['page'], $param['limit'])->field('name,phone')->select()->toArray();
  5487. $count = Customer::where($where)->count();
  5488. foreach ($list as $k => $v) {
  5489. $list[$k]['phone'] = substr_replace($v['phone'], '******', 3, 6);
  5490. }
  5491. return json(['code' => 0, 'data' => $list, 'count' => $count, 'msg' => '获取成功']);
  5492. }
  5493. /**
  5494. * 客户智慧屏保存实景图,效果图
  5495. * [{img: "", serverId: ""},{img: "", serverId: ""}]
  5496. */
  5497. public function saveWisdomImg()
  5498. {
  5499. $arr = input('content', []);
  5500. $customer_id = input('customer_id', 0);
  5501. $cate = input('type', 0);
  5502. if (empty($arr) || !is_array($arr) || count($arr) == count($arr, 1) || !$customer_id) return json(['code' => 1, 'data' => '参数错误', 'msg' => '参数错误']);
  5503. $img = array_filter(array_column($arr, 'img'));
  5504. $media_id = array_filter(array_column($arr, 'serverId'));
  5505. if ($img) {
  5506. $type = 'img';
  5507. $arr = $img;
  5508. } elseif ($media_id) {
  5509. $type = 'media_id';
  5510. $arr = $media_id;
  5511. } else {
  5512. return json(['code' => 1, 'data' => '参数错误', 'msg' => '参数错误']);
  5513. }
  5514. $token = $this->request->token;
  5515. // $token['root_org'] = 23;
  5516. $save = [];
  5517. foreach ($arr as $k => $v) {
  5518. $save[] = [
  5519. 'root_id' => $token['root_org'],
  5520. 'customer_id' => $customer_id,
  5521. $type => $v,
  5522. 'type' => $cate
  5523. ];
  5524. }
  5525. CustomerWisdomImg::insertAll($save);
  5526. if ($media_id) Console::call('download', ['wisdom']);
  5527. //保存客户跟进记录0实景图,1效果图
  5528. $str = $cate ? '智慧屏效果图上传' : '智慧屏实景图上传';
  5529. $field = $img ? 'img' : 'media_id';
  5530. if ($img) {
  5531. $imgs = implode(',', $img);
  5532. } else {
  5533. $imgs = CustomerWisdomImg::where([['media_id', 'in', $arr]])->column('img');
  5534. $imgs = implode(',', $imgs);
  5535. }
  5536. $remark = $str . '##' . $imgs;
  5537. $save = [
  5538. 'customer_id' => $customer_id,
  5539. 'type' => '',
  5540. 'next_contact_date' => date('Y-m-d'),
  5541. 'remark' => '智慧屏客户图片##' . $remark,
  5542. 'addtime' => date('Y-m-d H:i:s'),
  5543. 'employee_id' => $token['employee_id'],
  5544. 'user_id' => $token['uid'],
  5545. 'state' => '未到访',
  5546. 'org_id' => $token['org_id'],
  5547. 'customer_employee_id' => $token['employee_id'],
  5548. 'customer_org_id' => $token['org_id']
  5549. ];
  5550. CustomerVisitLog::insert($save);
  5551. return json(['code' => 0, 'data' => '保存成功', 'msg' => '保存成功']);
  5552. }
  5553. /**
  5554. * 获取客户智慧屏图片图片
  5555. */
  5556. public function getWisdomImg()
  5557. {
  5558. $param = Request::only(['customer_id' => 0, 'type' => 0]);
  5559. $token = $this->request->token;
  5560. // $token['root_org'] = 23;
  5561. $where = [
  5562. 'customer_id' => $param['customer_id'],
  5563. 'type' => $param['type'],
  5564. 'root_id' => $token['root_org']
  5565. ];
  5566. $list = CustomerWisdomImg::where($where)->field('id,img')->order('id asc')->select()->toArray();
  5567. return json(['code' => 0, 'data' => $list, 'msg' => '获取成功']);
  5568. }
  5569. /**
  5570. * 删除客户智慧屏图片图片
  5571. */
  5572. public function delWisdomImg()
  5573. {
  5574. $param = Request::only(['customer_id' => 0, 'id' => 0]);
  5575. $info = CustomerWisdomImg::where('id', $param['id'])->findOrEmpty();
  5576. if ($info->isEmpty()) return json(['code' => 1, 'data' => '删除失败', 'msg' => '删除失败']);
  5577. $token = $this->request->token;
  5578. // $token['root_org'] = 23;
  5579. $where = [
  5580. 'customer_id' => $param['customer_id'],
  5581. 'id' => $param['id'],
  5582. 'root_id' => $token['root_org']
  5583. ];
  5584. $list = CustomerWisdomImg::where($where)->delete();
  5585. $str = $info->type ? '智慧屏效果图删除' : '智慧屏实景图删除';
  5586. //智慧屏删除
  5587. $remark = $str . '##' . $info->getData('img');
  5588. $save = [
  5589. 'customer_id' => $param['customer_id'],
  5590. 'type' => '',
  5591. 'next_contact_date' => date('Y-m-d'),
  5592. 'remark' => '智慧屏客户图片##' . $remark,
  5593. 'addtime' => date('Y-m-d H:i:s'),
  5594. 'employee_id' => $token['employee_id'],
  5595. 'user_id' => $token['uid'],
  5596. 'state' => '未到访',
  5597. 'org_id' => $token['org_id'],
  5598. 'customer_employee_id' => $token['employee_id'],
  5599. 'customer_org_id' => $token['org_id']
  5600. ];
  5601. CustomerVisitLog::insert($save);
  5602. return json(['code' => 0, 'data' => '删除成功', 'msg' => '删除成功']);
  5603. }
  5604. /**
  5605. * 是否有外呼系统
  5606. */
  5607. public function haveOutCall()
  5608. {
  5609. $info = OutCallSetting::where('root_id', '=', request()->token['root_org'])->findOrEmpty();
  5610. $have = false;
  5611. if (!$info->isEmpty()) {
  5612. if (!isset($info->config['open']) || $info->config['open'] == 1)
  5613. $have = true;
  5614. }
  5615. return json(['code' => 0, 'data' => $have, 'msg' => 'success']);
  5616. }
  5617. /**
  5618. * 获取指派类型
  5619. */
  5620. public function getAssignType()
  5621. {
  5622. $setting = Setting::where([['root_id', '=', request()->token['root_org']], ['name', '=', 'assign_type']])->findOrEmpty();
  5623. $default['yixiang'] = '意向客户指派';
  5624. $default['liangfang'] = '量房客户指派';
  5625. $default['daodian'] = '到店客户指派';
  5626. $data = [];
  5627. if (!$setting->isEmpty()) {
  5628. $content = json_decode($setting['content'], true);
  5629. if (!empty($content)) {
  5630. foreach ($content as $k => $v) {
  5631. if (isset($default[$v])) {
  5632. $data[$v] = $default[$v];
  5633. }
  5634. }
  5635. }
  5636. }
  5637. return json(['code' => 0, 'data' => $data, 'msg' => 'success']);
  5638. }
  5639. /**
  5640. * 智慧屏绑定客户
  5641. */
  5642. public function bindCustomers()
  5643. {
  5644. $token = $this->request->token;
  5645. $param = Request::only(['customer_id' => 0, 'employee_id' => 0, 'token' => '']);
  5646. if (strpos($param['token'], '@' . $token['root_org'] . '@') === false) return json(['code' => 1, 'data' => '绑定失败', 'msg' => '绑定失败']);
  5647. $org = Org::where([['path', 'like', $token['root_org'] . '-%']])->column('id');
  5648. $where = [
  5649. // ['employee_id|designer_id','=',$param['employee_id']],
  5650. ['id', '=', $param['customer_id']],
  5651. ['org_id', 'in', $org]
  5652. ];
  5653. $find = Customer::where($where)->value('id');
  5654. if (!$find) return json(['code' => 1, 'data' => '绑定失败', 'msg' => '绑定失败']);
  5655. $str = $token['root_org'] . '#' . $param['employee_id'] . '#' . $param['customer_id'];
  5656. $aec = new Aec(config('app.aec_key'), config('app.aec_iv'));
  5657. $str = $aec->encrypt($str);
  5658. Cache::set($param['token'], $str, 60);
  5659. return json(['code' => 0, 'data' => '绑定成功', 'msg' => '获取成功']);
  5660. }
  5661. /**
  5662. * 龙虎榜
  5663. */
  5664. public function topStatistics()
  5665. {
  5666. $root_id = request()->token['root_org'];
  5667. $orgList = orgSubIds($root_id);
  5668. $param = request()->param(['start_date' => '2021-01-01', 'end_date' => date('Y-m-d')]);
  5669. $type = input('type', '', 'trim');
  5670. !empty($param['start_date']) ?: $param['start_date'] = '2021-01-01';
  5671. !empty($param['end_date']) ?: $param['end_date'] = date('Y-m-d');
  5672. $start_date = date('Y-m-d 00:00:00', strtotime($param['start_date']));
  5673. $end_date = date('Y-m-d 00:00:00', strtotime($param['end_date']) + 86400);
  5674. switch ($type) {
  5675. case 'jiav':
  5676. $where[] = ['org_id', 'in', $orgList];
  5677. $where[] = ['add_wechat_time', '>=', $start_date];
  5678. $where[] = ['add_wechat_time', '<', $end_date];
  5679. $where[] = ['employee_id', 'NOTNULL', ''];
  5680. $e = Customer::where($where)->field('employee_id, count(id) as num')->group('employee_id')->order('num desc')->select();
  5681. break;
  5682. case 'daodian':
  5683. $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');
  5684. $cvl = array_count_values($cvl);
  5685. $e = [];
  5686. foreach ($cvl as $employee_id => $num) {
  5687. $e[] = [
  5688. 'employee_id' => $employee_id,
  5689. 'num' => $num
  5690. ];
  5691. }
  5692. array_multisort(array_column($e, 'num'), SORT_DESC, $e);
  5693. break;
  5694. case 'qiandan':
  5695. $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');
  5696. $dcvl = [];
  5697. foreach ($cvl as $i) {
  5698. if (!isset($dcvl[$i['employee_id']]))
  5699. $dcvl[$i['employee_id']] = 0;
  5700. $dcvl[$i['employee_id']] += $i['money'];
  5701. }
  5702. $e = [];
  5703. foreach ($dcvl as $employee_id => $money) {
  5704. $e[] = [
  5705. 'employee_id' => $employee_id,
  5706. 'num' => $money > 10000 ? round($money / 10000, 2) . '万元' : $money . '元',
  5707. 'money' => $money
  5708. ];
  5709. }
  5710. array_multisort(array_column($e, 'money'), SORT_DESC, $e);
  5711. break;
  5712. case 'sj_qiandan':
  5713. $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');
  5714. $dcvl = [];
  5715. foreach ($cvl as $i) {
  5716. if (!isset($dcvl[$i['designer_id']]))
  5717. $dcvl[$i['designer_id']] = 0;
  5718. $dcvl[$i['designer_id']] += $i['money'];
  5719. }
  5720. $e = [];
  5721. foreach ($dcvl as $employee_id => $money) {
  5722. $e[] = [
  5723. 'employee_id' => $employee_id,
  5724. 'num' => $money > 10000 ? round($money / 10000, 2) . '万元' : $money . '元',
  5725. 'money' => $money
  5726. ];
  5727. }
  5728. array_multisort(array_column($e, 'money'), SORT_DESC, $e);
  5729. break;
  5730. }
  5731. // 取前三名数据
  5732. $n = 3;
  5733. $i = 0;
  5734. $p = [];
  5735. foreach ($e as $ei) {
  5736. if (empty($p)) {
  5737. $p[] = $ei;
  5738. $i = $ei['num'];
  5739. continue;
  5740. }
  5741. if ($i == $ei['num']) {
  5742. $p[] = $ei;
  5743. continue;
  5744. } else {
  5745. $n--;
  5746. if ($n == 0) break;
  5747. $p[] = $ei;
  5748. $i = $ei['num'];
  5749. }
  5750. }
  5751. $eid = array_column($p, 'employee_id');
  5752. $emp = Employee::with('org')->where([['id', 'in', $eid]])->select()->toArray();
  5753. $emp = array_combine(array_column($emp, 'id'), $emp);
  5754. foreach ($p as &$ie) {
  5755. $ie['employee_name'] = $emp[$ie['employee_id']]['name'];
  5756. $ie['headimgurl'] = $emp[$ie['employee_id']]['headimgurl'];
  5757. $ie['org_name'] = $emp[$ie['employee_id']]['org']['name'];
  5758. }
  5759. return json(['code' => 0, 'data' => $p]);
  5760. }
  5761. }