123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408 |
- # -*- coding: utf-8 -*-
- # !/usr/bin/env python
- """
- web.user.views
- ~~~~~~~~~
- 关于扫码终端用户的一切视图
- """
- import base64
- import datetime
- import logging
- import random
- import re
- import time
- import uuid
- from copy import deepcopy
- from math import radians, fabs, cos, asin, sqrt, sin, isnan
- import simplejson as json
- from bson.objectid import ObjectId
- from django.conf import settings
- from mongoengine.errors import DoesNotExist
- from mongoengine.queryset.visitor import Q
- from typing import TYPE_CHECKING, cast, Optional, Union, Tuple, Dict
- from voluptuous.error import MultipleInvalid
- from apilib.monetary import VirtualCoin, RMB
- from apilib.utils_datetime import to_datetime, timestamp_to_dt
- from apilib.utils_json import JsonResponse
- from apilib.utils_string import cn
- #: ad
- from apilib.utils_sys import memcache_lock
- from apilib.utils_url import add_query, before_frag_add_query
- from apps import serviceCache
- from apps.common.utils import coordinateHandler
- from apps.web.ad.models import AdRecord, DevRegToAli
- from apps.web.agent.models import Agent, MoniApp
- from apps.web.common.proxy import ClientRechargeModelProxy, ClientConsumeModelProxy
- from apps.web.common.transaction.pay import OrderCacheMgr, PayManager
- from apps.web.common.transaction.refund import RefundManager
- from apps.web.common.utils import UserConsumeFilter
- from apps.web.common.validation import check_phone_number, check_entity_name
- from apps.web.constant import Const, GPS_TYPE, START_DEVICE_STATUS, ErrorCode, RECHARGE_CARD_TYPE, APP_TYPE, \
- AppPlatformType, DeviceOnlineStatus, support_policy_weifule, \
- support_policy_device, RechargeRecordVia
- from apps.web.core import PayAppType, ROLE
- from apps.web.core.auth.ali import AlipayAuthBridge
- from apps.web.core.auth.wechat import WechatAuthBridge
- from apps.web.core.bridge.wechat import WechatClientProxy
- from apps.web.core.exceptions import ServiceException, InvalidParameter, InvalidFileSize, \
- InvalidFileName, InterceptException
- from apps.web.core.file import AliOssFileUploader
- from apps.web.core.helpers import ActionDeviceBuilder
- from apps.web.core.messages.sms import userMobileVerifySMSProvider
- from apps.web.core.models import WechatPayApp, BoundOpenInfo, WechatAuthApp
- from apps.web.core.sysparas import SysParas
- from apps.web.core.utils import DefaultJsonErrorResponse
- from apps.web.core.utils import JsonErrorResponse, JsonOkResponse
- from apps.web.dealer.models import Dealer, OnSale, OnSaleRecord, VirtualCard, Complaint, \
- DealerMessage
- from apps.web.device.define import DeviceChannelType
- from apps.web.device.models import Device, Group, FeedBack, Comment, Cell, DeviceType, SwapGroup
- from apps.web.device.models import DeviceDict
- from apps.web.device.models import GroupDict
- from apps.web.device.utils import device_control_cache_key
- from apps.web.exceptions import UserServerException
- from apps.web.helpers import get_ali_auth_bridge, get_wx_config, get_wechat_auth_bridge, \
- get_user_manager_agent, get_app, start_device_lock_key
- from apps.web.management.models import Manager
- from apps.web.services.bluetooth.service import ActionBtDeviceBuilder
- #: user
- from apps.web.south_intf.yuchuanApi import YuChuanApi
- from apps.web.user import UserAuthState, MoniUserAuthState
- from apps.web.user.auth import response_with_login
- from apps.web.user.conf import USER_AUTH_REDIRECT_URL, PAY_NOTIFY_URL
- from apps.web.user.models import MyUser, ConsumeRecord, RechargeRecord, ServiceProgress, Card, CardRechargeRecord, \
- CardConsumeRecord, CardRechargeOrder, UserVirtualCard, VCardConsumeRecord, \
- RefundMoneyRecord, MoniUser, VirtualCardRechargeRecord, SwapCardRecord, MonthlyPackage, \
- EndUserLocation, Redpack, MyUserDetail
- from apps.web.user.transaction import post_pay
- from apps.web.user.transaction_deprecated import refund_post_pay
- from apps.web.user.utils import (
- get_homepage_response, auth_wechat_pay_app,
- auth_wechat_manager_app, login_required,
- user_last_time_use_ended_cache, parse_auth_payload, batteryInfo,
- is_need_renew, check_user_tel, check_black_user, PayParam, BUILDER_MAP, RedpackBuilder)
- from apps.web.user.utils2 import get_user_not_complete_order
- from apps.web.user.validation import feedbackSchema
- from apps.web.utils import (
- detect_alipay_client, detect_wechat_client, permission_required, error_tolerate, ErrorResponseRedirect,
- NotSupportedPlatformResponseRedirect, get_start_key_status, set_start_key_status,
- NetDeviceResponseRedirect, AdAccessResponseRedirect, ExternalResponseRedirect,
- FrontEndResponseRedirect, concat_server_end_url, concat_user_cardTicketList_entry_url,
- record_operation_behavior, get_client_ip, WechatAuthDummyRedirect, trace_call, concat_user_recharge_url)
- from apps.web.wrapper import request_limit_by_user
- from library.alipay.exceptions import AliException
- from library.wechatbase.exceptions import WechatOAuthDummyException
- from taskmanager.mediator import task_caller
- if TYPE_CHECKING:
- from django.core.handlers.wsgi import WSGIRequest
- from django.http import HttpResponse, HttpResponseRedirect
- from apps.web.common.proxy import QuerySetProxy
- from apps.web.core.db import CustomQuerySet
- from apps.web.core.models import PayAppBase
- logger = logging.getLogger(__name__)
- # 报错页面
- defaultErrorResponseRedirect = ErrorResponseRedirect(error = cn(u'系统错误,请重试'))
- def checkAdClick(request):
- # type: (WSGIRequest)->HttpResponse
- """
- :param request:
- :return:
- """
- adId = request.GET.get('adId', None)
- logger.debug('get adId success adId = %s' % adId)
- if not adId:
- return ErrorResponseRedirect(error = cn(u'无效的链接,无此广告'))
- return AdAccessResponseRedirect(adId = str(adId))
- @error_tolerate(nil = defaultErrorResponseRedirect)
- @login_required(error_response = ErrorResponseRedirect(error = cn(u'您未登陆,请扫码登录')))
- def adAccess(request):
- # type: (WSGIRequest)->HttpResponse
- """
- 减少cookie依赖, 参数全部通过state封装
- 用户领取广告效果奖励
- :param request:
- :return:
- """
- adId = request.GET.get('state', None)
- return ErrorResponseRedirect(error = cn(u'该广告不可用'))
- @trace_call(logger = logger)
- @error_tolerate(nil = defaultErrorResponseRedirect)
- def userLogin(request):
- # type: (WSGIRequest)->HttpResponse
- """
- 用户扫码-> 登陆渲染的首屏页面
- 扫码的读取分配入口,同时兼容老式设备号和新式逻辑码
- .. 2017/10/30 加入对支付宝识别的兼容。
- :param request:
- :return:
- """
- def by_agent(request, agentId, href):
- # type: (WSGIRequest, str, str)->(basestring, str)
- return UserAuthState.by_agent(agentId=agentId, href=href, productAgentId=agentId)
- def by_dev(request, devNo, logicalCode, port=None):
- # type: (WSGIRequest, str, str, str)->(basestring, str)
- logger.debug('user login. device = (logicalCode=%s), port = %s' % (logicalCode, port))
- if (logicalCode is not None) and (devNo is None):
- logicalCode = logicalCode.strip()
- devNo = Device.get_devNo_by_logicalCode(logicalCode)
- if not devNo:
- raise UserServerException(u'该设备未开通网络支付,请投币或者联系客服(1002)')
- devNo = devNo.strip()
- dev = Device.get_dev(devNo) # type: Optional[DeviceDict]
- if dev is None:
- raise UserServerException(u'该设备未开通网络支付,请投币或者联系客服(1003)')
- if not dev.is_registered or 'groupId' not in dev or 'washConfig' not in dev:
- raise UserServerException(u'该设备未开通网络支付,请投币或者联系客服(1005)')
- if dev.is_expired:
- raise UserServerException(
- u'设备({})的物联网卡已经过期,目前离线,无法扫码支付。请您联系提醒设备运营商进行充值,以便尽快恢复使用。'.format(
- dev.logicalCode))
- if dev.is_fault:
- raise UserServerException(u'设备故障中,正在等师傅过来维修,您试试看其他设备吧')
- if dev.is_DND_now:
- raise UserServerException(u'设备处于禁用时段,暂不支持扫码使用')
- if dev.ban:
- raise UserServerException(u'该设备暂时不可使用,请联系经销商')
- if port and dev.channelType != DeviceChannelType.Channel_BT:
- isFree = Group.get_group(dev.groupId).get('isFree', False)
- if not isFree:
- box = ActionDeviceBuilder.create_action_device(dev)
- isCanAdd = dev['devType'].get('payableWhileBusy', False)
- canUse, desc = box.is_port_can_use(port, isCanAdd)
- if not canUse:
- raise UserServerException(desc)
- dealer = dev.owner # type: Dealer
- # 平台agent必须配置自定义公众号, 否则普通扫码用户无法获取
- product_agent = get_user_manager_agent(dealer)
- state = UserAuthState.by_dev(devNo=devNo,
- chargeIndex=port,
- agentId=str(dealer.agentId),
- productAgentId=str(product_agent.id))
- logger.debug('initial user state = {}'.format(repr(state)))
- return dev, product_agent, state
- def generate_card_recharge_href(_cardNo, _product_agent_id): # type:(str, str) -> Optional[str]
- _baseHref = "/user/index.html#/chargeCard?cardNo={}&cardId={}"
- try:
- card = Card.objects.get(cardNo=_cardNo, agentId=str(_product_agent_id))
- except DoesNotExist:
- logger.error('card is not exist, cardNo=%s' % _cardNo)
- return None
- except Exception as e:
- logger.error(e)
- return None
- return _baseHref.format(_cardNo, str(card.id))
- def login_context(request):
- if 'devNo' not in request.GET and 'l' not in request.GET and 'agentId' not in request.GET:
- return ErrorResponseRedirect(error=cn(u'错误的二维码或者二维码损坏,请联系工作人员进行维修'))
- href = request.GET.get('redirect', '/user/index.html#/user/me')
- if 'agentId' in request.GET:
- # 个人中心登录
- dev = None # type: Optional[DeviceDict]
- product_agent_id = str(request.GET.get("agentId"))
- product_agent = Agent.objects(id = product_agent_id).get() # type: Agent
- cardNo = request.GET.get("cardNo")
- if cardNo:
- href = generate_card_recharge_href(cardNo, product_agent_id) or href
- state = by_agent(request, product_agent_id, href)
- groupId = MyUser._product_group_id(product_agent_id)
- else:
- # 扫描登录
- devNo = request.GET.get('devNo', None)
- logicalCode = request.GET.get('l', None)
- dev, product_agent, state = by_dev(request, devNo, logicalCode, request.GET.get('chargeIndex', None))
- groupId = dev.groupId
- if detect_wechat_client(request):
- # 微信平台登录
- auth_bridge = get_wechat_auth_bridge(
- source = product_agent, app_type = APP_TYPE.WECHAT_AUTH) # type: WechatAuthBridge
- pay_type = u'微信'
- auth_callback = None # 具体处理流程中写死
- elif detect_alipay_client(request):
- # 支付宝平台登录
- auth_bridge = get_ali_auth_bridge(source=product_agent,
- app_type=APP_TYPE.ALIPAY_AUTH) # type: AlipayAuthBridge
- pay_type = u'支付宝'
- auth_callback = USER_AUTH_REDIRECT_URL.ALIPAY
- else:
- raise UserServerException(u'不支持该平台下扫码')
- if not auth_bridge.enable:
- raise UserServerException(u'{}平台暂时未开通,请使用其他方式登录'.format(pay_type))
- if not product_agent.customizedUserGzhAllowable:
- return ErrorResponseRedirect(error=cn(u'系统配置错误,请联系平台客服(10009)'))
- return auth_bridge, auth_callback, product_agent, state, pay_type, dev, groupId
- def clone_from_login_user(login_user, auth_bridge, groupId, new_product_agent_id, new_agent_id):
- if login_user.groupId == groupId:
- my_user = login_user
- need_save = False
- if my_user.agentId != new_agent_id:
- my_user.agentId = new_agent_id
- need_save = True
- if my_user.productAgentId != new_product_agent_id:
- my_user.productAgentId = new_product_agent_id
- need_save = True
- if need_save:
- my_user.save()
- else:
- if login_user.productAgentId == new_product_agent_id:
- payload = login_user.cloneable_user_info
- else:
- payload = {}
- payload.update({
- 'authAppId': auth_bridge.appid,
- 'agentId': new_agent_id,
- 'productAgentId': new_product_agent_id
- })
- my_user = MyUser.get_or_create(app_platform_type = auth_bridge.gateway_type,
- open_id = login_user.openId,
- group_id = groupId,
- **payload)
- return my_user
- try:
- ip = get_client_ip(request)
- logger.debug("user<ip={}> login. ".format(ip))
- auth_bridge, auth_callback, product_agent, state, pay_type, dev, groupId = login_context(request)
- login_user = request.user # type: MyUser
- if auth_bridge.gateway_type == AppPlatformType.WECHAT:
- need_auth = (not login_user.is_authenticated()) or (login_user.authAppId != auth_bridge.appid)
- if state.by == UserAuthState.BY.AGENT:
- if need_auth:
- manager_auth_bridge = get_wechat_auth_bridge(product_agent, APP_TYPE.WECHAT_USER_MANAGER)
- if manager_auth_bridge.appid == auth_bridge.appid:
- logger.debug('auth bridge is same with manager auth bridge.')
- return ExternalResponseRedirect(
- auth_bridge.generate_auth_url_user_scope(
- redirect_uri = USER_AUTH_REDIRECT_URL.WECHAT_USER_CENTER_AUTH_USER,
- payload = state.encode()))
- else:
- return ExternalResponseRedirect(
- auth_bridge.generate_auth_url_base_scope(
- redirect_uri = USER_AUTH_REDIRECT_URL.WECHAT_USER_CENTER_AUTH_BASE,
- payload = state.encode()))
- else:
- my_user = clone_from_login_user(
- login_user, auth_bridge, groupId, str(product_agent.id), str(product_agent.id))
- manager_auth_bridge = get_wechat_auth_bridge(product_agent, APP_TYPE.WECHAT_USER_MANAGER)
- manager_openid = my_user.get_bound_pay_openid(manager_auth_bridge.bound_openid_key)
- if manager_openid and (manager_openid != my_user.managerialOpenId):
- my_user.managerialAppId = manager_auth_bridge.appid
- my_user.managerialOpenId = manager_openid
- my_user.save()
- if (not manager_openid) or (not my_user.nickname):
- state.uid = str(my_user.id)
- return ExternalResponseRedirect(
- manager_auth_bridge.generate_auth_url_user_scope(
- redirect_uri = USER_AUTH_REDIRECT_URL.WECHAT_USER_CENTER_MANAGER_AUTH_USER,
- payload = state.encode()))
- else:
- if need_auth:
- return ExternalResponseRedirect(
- auth_bridge.generate_auth_url_base_scope(
- redirect_uri = USER_AUTH_REDIRECT_URL.WECHAT_AUTH_BASE,
- payload = state.encode()))
- else:
- my_user = clone_from_login_user(
- login_user, auth_bridge, groupId, str(product_agent.id),
- dev.owner.agentId if dev else str(product_agent.id))
- state.uid = str(my_user.id)
- response = auth_wechat_manager_app(my_user, product_agent, state, dev)
- if response:
- return response
- response = auth_wechat_pay_app(
- my_user, dev.owner, product_agent, state, USER_AUTH_REDIRECT_URL.WECHAT_PAY_AUTH_BASE)
- if response:
- return response
- else:
- if not login_user.is_authenticated():
- return ExternalResponseRedirect(
- auth_bridge.generate_auth_url_user_scope(
- redirect_uri=auth_callback,
- payload=state.encode()))
- else:
- my_user = clone_from_login_user(
- login_user, auth_bridge, groupId, str(product_agent.id),
- dev.owner.agentId if dev else str(product_agent.id))
- if my_user.nickname is None:
- return ExternalResponseRedirect(
- auth_bridge.generate_auth_url_user_scope(
- redirect_uri = auth_callback,
- payload = state.encode()))
- if state.by == UserAuthState.BY.AGENT:
- response = FrontEndResponseRedirect(str(state.href))
- else:
- response = get_homepage_response(auth_bridge.gateway_type, my_user, dev,
- state.chargeIndex if state.chargeIndex else '', product_agent)
- return response_with_login(request, my_user, response)
- except UserServerException as e:
- return ErrorResponseRedirect(error=cn(e.message))
- except Exception as e:
- logger.exception(e)
- return ErrorResponseRedirect(error=cn(u'系统错误'))
- @trace_call(logger = logger)
- @error_tolerate(nil = defaultErrorResponseRedirect, logger = logger)
- def wxpayBaseAccess(request):
- # type: (WSGIRequest)->HttpResponse
- """
- 获取微信用户支付的openId
- :param request:
- :return:
- """
- def authorize(app, request):
- # type: (Optional[WechatPayApp], WSGIRequest)->None
- if isinstance(app, WechatPayApp):
- code = request.GET.get('code', None)
- if not code:
- raise InvalidParameter(u'参数错误,请重新扫码({})'.format(ErrorCode.AUTH_CODE_IS_NULL))
- auth_bridge = WechatAuthBridge(app)
- openId = auth_bridge.authorize(code)
- user.set_bound_pay_openid(auth_bridge.bound_openid_key, openId = openId)
- user.save()
- try:
- if 'code' not in request.GET and 'openId' not in request.GET:
- raise InvalidParameter(u'参数错误,请重新扫码({})'.format(ErrorCode.AUTH_CODE_IS_NULL))
- state = parse_auth_payload(request)
- if not state.is_valid():
- raise InvalidParameter(u'参数错误,请重新扫码({})'.format(ErrorCode.USER_STATE_IS_NOT_VALID))
- user = MyUser.objects.get(id = state.uid) # type: MyUser
- dev = Device.get_dev(state.devNo) # type: DeviceDict
- product_agent = Agent.objects(id = str(state.productAgentId)).get()
- app = get_app(source = product_agent,
- app_type = APP_TYPE.WECHAT_ENV_PAY,
- role = ROLE.myuser) # type: PayAppBase
- authorize(app, request)
- response = get_homepage_response(AppPlatformType.WECHAT, user, dev,
- state.chargeIndex if state.chargeIndex else '', product_agent)
- return response_with_login(request, user, response)
- except Exception as e:
- logger.exception(e)
- return ErrorResponseRedirect(error = u'系统错误, 请重新扫码')
- @trace_call(logger = logger)
- @error_tolerate(nil = defaultErrorResponseRedirect)
- def wechatAuthBase(request):
- # type: (WSGIRequest)->HttpResponse
- """
- 老终端用户扫码进入
- 只获取openId
- 用户通过扫码转到的中继器
- :param request:
- :return:
- """
- try:
- auth_code = request.GET.get('code', None)
- if auth_code is None:
- raise UserServerException(u'网络开小差了,重新扫码试试喔(%s)' % ErrorCode.AUTH_CODE_IS_NULL)
- state = parse_auth_payload(request) # type: UserAuthState
- logger.info('return to wechatAuthBase. code = %s; state = %s' % (auth_code, state))
- product_agent = Agent.objects(id = str(state.productAgentId)).get() # type: Agent
- dev = Device.get_dev(state.devNo) # type: DeviceDict
- groupId = dev.groupId
- auth_bridge = get_wechat_auth_bridge(source = product_agent, app_type = APP_TYPE.WECHAT_AUTH)
- logger.debug(
- 'wechat auth for login. appid = {}, code = {}, state = {}, agent = {}, group_id = {}'.format(
- auth_bridge.appid, auth_code, str(state.encode()), str(product_agent.id), groupId))
- openId = auth_bridge.authorize(auth_code)
- if not openId:
- logger.error(
- 'auth error, app = %s; payload = %s' % (repr(auth_bridge.app), str(state.encode())))
- return ErrorResponseRedirect(error = u'系统错误,请重新扫码')
- payload = {
- 'authAppId': auth_bridge.app.appid,
- 'agentId': str(state.agentId),
- 'productAgentId': str(state.productAgentId),
- 'payOpenIdMap': {
- auth_bridge.bound_openid_key: BoundOpenInfo(openId = openId)
- }
- }
- manager_auth_bridge = get_wechat_auth_bridge(source = product_agent, app_type = APP_TYPE.WECHAT_USER_MANAGER)
- if manager_auth_bridge.appid == auth_bridge.appid:
- payload.update({
- 'managerialAppId': auth_bridge.appid,
- 'managerialOpenId': openId
- })
- my_user = MyUser.get_or_create(
- app_platform_type = AppPlatformType.WECHAT, open_id = openId, group_id = groupId, **payload)
- if not my_user:
- raise UserServerException(u'网络开小差了,重新扫码试试喔(%s)' % ErrorCode.LOGIN_USER_IS_NULL)
- dealer = dev.owner # type: Dealer
- state.uid = str(my_user.id)
- response = auth_wechat_manager_app(my_user, product_agent, state, dev)
- if response:
- return response
- response = auth_wechat_pay_app(my_user, dealer, product_agent, state, USER_AUTH_REDIRECT_URL.WECHAT_PAY_AUTH_BASE)
- if response:
- return response
- response = get_homepage_response(AppPlatformType.WECHAT, my_user, dev,
- state.chargeIndex if state.chargeIndex else '', product_agent)
- return response_with_login(request, my_user, response)
- except UserServerException as e:
- logger.error(e.message)
- return ErrorResponseRedirect(error = cn(e.message))
- except Exception as e:
- logger.exception(e)
- return ErrorResponseRedirect(error = cn(u'网络开小差了,重新扫码试试喔'))
- @trace_call(logger = logger)
- @error_tolerate(nil = ErrorResponseRedirect, logger = logger)
- def wechatManagerAuthBase(request):
- # type: (WSGIRequest)->HttpResponse
- """
- manager做基础鉴权, 获取OpenId. 只有从用户信息获取不到managerOpenId的情况下才会走这个分支
- :param request:
- :return:
- """
- try:
- auth_code = request.GET.get(WechatAuthBridge.auth_code_key, None)
- if not auth_code:
- raise InvalidParameter(u'参数错误,请重新扫码({})'.format(ErrorCode.AUTH_CODE_IS_NULL))
- state = parse_auth_payload(request)
- my_user = MyUser.objects.get(id = state.uid)
- product_agent = Agent.objects(id = str(state.productAgentId)).get()
- manager_auth_bridge = get_wechat_auth_bridge(
- source = product_agent, app_type = APP_TYPE.WECHAT_USER_MANAGER) # type: WechatAuthBridge
- openId = manager_auth_bridge.authorize(auth_code)
- if openId is None:
- logger.error(
- 'manager auth error, app = %s; state = %s' % (repr(manager_auth_bridge.app), str(state.encode())))
- return ErrorResponseRedirect(error = u'系统错误, 请重新扫码')
- my_user.managerialAppId = manager_auth_bridge.appid
- my_user.managerialOpenId = openId
- my_user.set_bound_pay_openid(manager_auth_bridge.bound_openid_key, openId = openId)
- my_user.save()
- dev = Device.get_dev(state.devNo) # type: DeviceDict
- response = auth_wechat_manager_app(my_user, product_agent, state, dev)
- if response:
- return response
- response = auth_wechat_pay_app(my_user, dev.owner, product_agent, state, USER_AUTH_REDIRECT_URL.WECHAT_PAY_AUTH_BASE)
- if response:
- return response
- response = get_homepage_response(AppPlatformType.WECHAT, my_user, dev,
- state.chargeIndex if state.chargeIndex else '', product_agent)
- return response_with_login(request, my_user, response)
- except UserServerException as e:
- logger.error(e.message)
- return ErrorResponseRedirect(error = cn(e.message))
- except WechatOAuthDummyException as e:
- logger.error(e.message)
- return WechatAuthDummyRedirect()
- except Exception as e:
- logger.exception(e)
- return ErrorResponseRedirect(error = cn(u'网络开小差了,重新扫码试试喔'))
- @trace_call(logger = logger)
- @error_tolerate(nil = ErrorResponseRedirect, logger = logger)
- def wechatManagerAuthUser(request):
- # type: (WSGIRequest)->HttpResponse
- """
- 用户首次授权,需要创建用户
- :param request:
- :return:
- """
- try:
- auth_code = request.GET.get(WechatAuthBridge.auth_code_key, None)
- if not auth_code:
- raise InvalidParameter(u'参数错误,请重新扫码({})'.format(ErrorCode.AUTH_CODE_IS_NULL))
- state = parse_auth_payload(request)
- user = MyUser.objects.get(id = state.uid)
- product_agent = Agent.objects(id = str(state.productAgentId)).get()
- manager_auth_bridge = get_wechat_auth_bridge(
- source = product_agent, app_type = APP_TYPE.WECHAT_USER_MANAGER) # type: WechatAuthBridge
- userInfo = manager_auth_bridge.get_user_info(auth_code = auth_code)
- openId = userInfo['openId']
- if openId is None:
- logger.error(
- 'manager auth error, app = %s; payload = %s' % (repr(manager_auth_bridge.app), str(state.encode())))
- return ErrorResponseRedirect(error = u'系统错误, 请重新扫码')
- user.sex = userInfo.get('sex', 0)
- user.city = userInfo.get('city', '')
- user.province = userInfo.get('province', '')
- user.country = userInfo.get('country', '')
- user.nickname = userInfo.get('nickname', '')
- user.avatar = userInfo.get('avatar', '')
- user.unionId = userInfo.get('unionid', '')
- user.set_bound_pay_openid(manager_auth_bridge.bound_openid_key, openId = openId)
- user.managerialAppId = manager_auth_bridge.appid
- user.managerialOpenId = openId
- user.save()
- dev = Device.get_dev(state.devNo) # type: DeviceDict
- response = auth_wechat_pay_app(user, dev.owner, product_agent, state, USER_AUTH_REDIRECT_URL.WECHAT_PAY_AUTH_BASE)
- if response:
- return response
- response = get_homepage_response(AppPlatformType.WECHAT, user, dev,
- state.chargeIndex if state.chargeIndex else '', product_agent)
- return response_with_login(request, user, response)
- except UserServerException as e:
- logger.error(e.message)
- return ErrorResponseRedirect(error = cn(e.message))
- except WechatOAuthDummyException as e:
- logger.error(e.message)
- return WechatAuthDummyRedirect()
- except Exception as e:
- logger.exception(e)
- return ErrorResponseRedirect(error = cn(u'网络开小差了,重新扫码试试喔'))
- @trace_call(logger = logger)
- @error_tolerate(nil=defaultErrorResponseRedirect)
- def wechatBaseAuthForUserCenter(request):
- # type: (WSGIRequest)->HttpResponse
- """
- 个人中心
- :param request:
- :return:
- """
- try:
- auth_code = request.GET.get('code', None)
- if auth_code is None:
- raise UserServerException(u'网络开小差了,重新扫码试试喔(%s)' % ErrorCode.AUTH_CODE_IS_NULL)
- state = parse_auth_payload(request) # type: UserAuthState
- assert state.by == UserAuthState.BY.AGENT, 'must be enter user center.'
- logger.info('return to wechatBaseAuthForUserCenter. code = %s; state = %s' % (auth_code, state))
- product_agent = Agent.objects(id = str(state.productAgentId)).get() # type: Agent
- groupId = MyUser.groupId.default
- auth_bridge = get_wechat_auth_bridge(source = product_agent, app_type = APP_TYPE.WECHAT_AUTH)
- logger.debug(
- 'wechat base auth for user center login. appid = {}, code = {}, state = {}, agent = {}, group_id = {}'.format(
- auth_bridge.appid, auth_code, str(state.encode()), str(product_agent.id), groupId))
- openId = auth_bridge.authorize(auth_code)
- if not openId:
- logger.error(
- 'auth error, app = %s; payload = %s' % (repr(auth_bridge.app), str(state.encode())))
- return ErrorResponseRedirect(error = u'系统错误,请重新扫码')
- payload = {
- 'authAppId': auth_bridge.app.appid,
- 'agentId': str(state.agentId),
- 'productAgentId': str(state.productAgentId),
- 'payOpenIdMap': {
- auth_bridge.bound_openid_key: BoundOpenInfo(openId = openId)
- }
- }
- user = MyUser.get_or_create(
- app_platform_type = AppPlatformType.WECHAT, open_id = openId, group_id = groupId, **payload)
- manager_auth_bridge = get_wechat_auth_bridge(
- source = product_agent, app_type = APP_TYPE.WECHAT_USER_MANAGER)
- manager_openid = user.get_bound_pay_openid(manager_auth_bridge.bound_openid_key)
- if manager_openid and (manager_openid != user.managerialOpenId):
- user.managerialOpenId = manager_openid
- user.managerialAppId = manager_auth_bridge.appid
- user.save()
- if (not manager_openid) or (not user.nickname):
- state.uid = str(user.id)
- return ExternalResponseRedirect(
- manager_auth_bridge.generate_auth_url_user_scope(
- redirect_uri = USER_AUTH_REDIRECT_URL.WECHAT_USER_CENTER_MANAGER_AUTH_USER,
- payload = state.encode()))
- else:
- logger.debug('redirect url is: {}'.format(state.href))
- response = FrontEndResponseRedirect(str(state.href))
- return response_with_login(request, user, response)
- except UserServerException as e:
- logger.error(e.message)
- return ErrorResponseRedirect(error = cn(e.message))
- except Exception as e:
- logger.exception(e)
- return ErrorResponseRedirect(error = cn(u'网络开小差了,重新扫码试试喔'))
- @trace_call(logger = logger)
- @error_tolerate(nil = defaultErrorResponseRedirect)
- def wechatUserAuthForUserCenter(request):
- # type: (WSGIRequest)->HttpResponse
- """
- 个人中心
- :param request:
- :return:
- """
- try:
- auth_code = request.GET.get('code', None)
- if auth_code is None:
- raise UserServerException(u'网络开小差了,重新扫码试试喔(%s)' % ErrorCode.AUTH_CODE_IS_NULL)
- state = parse_auth_payload(request) # type: UserAuthState
- assert state.by == UserAuthState.BY.AGENT, 'must be enter user center.'
- logger.info('return to wechatUserAuthForUserCenter. code = %s; state = %s' % (auth_code, state))
- product_agent = Agent.objects(id = str(state.productAgentId)).get() # type: Agent
- groupId = MyUser.groupId.default
- auth_bridge = get_wechat_auth_bridge(source = product_agent, app_type = APP_TYPE.WECHAT_AUTH)
- logger.debug(
- 'wechat user auth for user center login. appid = {}, code = {}, state = {}, agent = {}, group_id = {}'.format(
- auth_bridge.appid, auth_code, str(state.encode()), str(product_agent.id), groupId))
- userInfo = auth_bridge.get_user_info(auth_code = auth_code)
- openId = userInfo['openId']
- if openId is None:
- logger.error(
- 'manager auth error, app = %s; payload = %s' % (repr(auth_bridge.app), str(state.encode())))
- return ErrorResponseRedirect(error = u'系统错误, 请重新扫码')
- payload = {
- 'sex': userInfo.get('sex', 0),
- 'city': userInfo.get('city', ''),
- 'province': userInfo.get('province', ''),
- 'country': userInfo.get('country', ''),
- 'nickname': userInfo.get('nickname', ''),
- 'avatar': userInfo.get('avatar', ''),
- 'unionId': userInfo.get('unionid', ''),
- 'authAppId': auth_bridge.appid,
- 'payOpenIdMap': {
- auth_bridge.bound_openid_key: BoundOpenInfo(openId = openId)
- },
- 'agentId': str(state.agentId),
- 'productAgentId': str(state.productAgentId),
- 'managerialAppId': auth_bridge.appid,
- 'managerialOpenId': openId
- }
- user = MyUser.get_or_create(app_platform_type = AppPlatformType.WECHAT,
- open_id = openId, group_id = groupId, **payload)
- logger.debug('redirect url is: {}'.format(state.href))
- response = FrontEndResponseRedirect(str(state.href))
- return response_with_login(request, user, response)
- except UserServerException as e:
- logger.error(e.message)
- return ErrorResponseRedirect(error = cn(e.message))
- except WechatOAuthDummyException as e:
- logger.error(e.message)
- return WechatAuthDummyRedirect()
- except Exception as e:
- logger.exception(e)
- return ErrorResponseRedirect(error = cn(u'网络开小差了,重新扫码试试喔'))
- @trace_call(logger = logger)
- @error_tolerate(nil=ErrorResponseRedirect, logger=logger)
- def wechatManagerAuthForUserCenter(request):
- # type: (WSGIRequest)->HttpResponse
- """
- :param request:
- :return:
- """
- try:
- auth_code = request.GET.get(WechatAuthBridge.auth_code_key, None)
- if not auth_code:
- raise InvalidParameter(u'参数错误,请重新扫码({})'.format(ErrorCode.AUTH_CODE_IS_NULL))
- state = parse_auth_payload(request)
- assert state.by == UserAuthState.BY.AGENT, 'must enter in user center.'
- user = MyUser.objects.get(id=state.uid)
- product_agent = Agent.objects(id=str(state.productAgentId)).get()
- manager_auth_bridge = get_wechat_auth_bridge(
- source=product_agent, app_type=APP_TYPE.WECHAT_USER_MANAGER) # type: WechatAuthBridge
- userInfo = manager_auth_bridge.get_user_info(auth_code=auth_code)
- openId = userInfo['openId']
- if openId is None:
- logger.error(
- 'manager auth error, app = %s; payload = %s' % (repr(manager_auth_bridge.app), str(state.encode())))
- raise UserServerException(u'系统错误, 请重新扫码')
- user.sex = userInfo.get('sex', 0)
- user.city = userInfo.get('city', '')
- user.province = userInfo.get('province', '')
- user.country = userInfo.get('country', '')
- user.nickname = userInfo.get('nickname', '')
- user.avatar = userInfo.get('avatar', '')
- user.unionId = userInfo.get('unionid', '')
- user.set_bound_pay_openid(manager_auth_bridge.bound_openid_key, openId=openId)
- user.managerialAppId = manager_auth_bridge.appid
- user.managerialOpenId = openId
- user.save()
- logger.debug('redirect url is: {}'.format(state.href))
- response = FrontEndResponseRedirect(str(state.href))
- return response_with_login(request, user, response)
- except UserServerException as e:
- logger.error(e.message)
- return ErrorResponseRedirect(error=cn(e.message))
- except WechatOAuthDummyException as e:
- logger.error(e.message)
- return WechatAuthDummyRedirect()
- except Exception as e:
- logger.exception(e)
- return ErrorResponseRedirect(error=cn(u'网络开小差了,重新扫码试试喔'))
- @permission_required(ROLE.myuser)
- def baseMoniAccess(request):
- """
- moni app 的鉴权
- """
- code = request.GET.get("code", None)
- if code is None:
- raise UserServerException(u'网络开小差了,重新扫码试试喔(%s)' % ErrorCode.MONI_AUTH_IS_NULL)
- state = parse_auth_payload(request) # type: UserAuthState
- inhouseMoniApp = MoniApp.objects.filter(appid=state.appid).first() # type: MoniApp
- if not inhouseMoniApp:
- raise UserServerException(u'网络开小差了,重新扫码试试喔(%s)' % ErrorCode.MONI_APP_IS_NULL)
- user = MyUser.objects.filter(id=state.uid).first()
- if not user:
- raise UserServerException(u'网络开小差了,重新扫码试试喔(%s)' % ErrorCode.LOGIN_USER_IS_NULL)
- # 存在app 的情况下 使用app进行解码 写入数据
- moniAuthBridge = WechatAuthBridge(WechatAuthApp(appid=inhouseMoniApp.appid, secret=inhouseMoniApp.secret))
- openId = moniAuthBridge.authorize(code)
- user.set_bound_pay_openid(moniAuthBridge.bound_openid_key, openId=openId)
- user.save()
- productAgent = Agent.objects.get(id=state.productAgentId)
- dev = Device.get_dev(state.devNo)
- response = get_homepage_response(AppPlatformType.WECHAT, user, dev, state.chargeIndex, productAgent)
- return response_with_login(request, user, response)
- @error_tolerate(logger=logger, nil=JsonErrorResponse(description=u"系统繁忙,请稍后重试"))
- @permission_required(ROLE.myuser)
- @request_limit_by_user(operation='equipmentPara', logger=logger)
- def equipmentPara(request):
- # type: (WSGIRequest)->HttpResponse
- """
- 扫码后获取设备侧以及用户的相关信息
- """
- currentUser = request.user # type: MyUser
- logicalCode = request.GET.get("logicalCode")
- force = True if request.GET.get('refresh', 'false') == 'true' else False
- dev = Device.get_dev_by_l(logicalCode) # type: DeviceDict
- if not dev:
- logger.info('(%s) cannot find device, devNo = %s' % (request.user, logicalCode))
- return JsonErrorResponse(description=u"该设备尚未注册(1002)")
- if not dev.group:
- logger.info('can not find group. dev = %s' % dev)
- return JsonErrorResponse(description=u'该设备未注册,暂时无法使用支付宝或者微信支付, 请投币(1010)')
- if not dev.dealer:
- logger.info('can not find dealer. dev = %s; group = %s' % (str(dev), str(dev.group)))
- return JsonErrorResponse(description=u'该设备未注册,暂时无法使用支付宝或者微信支付, 请投币(1011)')
- if check_black_user(dealerId=dev.get("ownerId"), openId = request.user.openId):
- return JsonErrorResponse(u"该设备暂不对您开放,请联系经销商")
- agent = Agent.objects(id=str(dev.dealer['agentId'])).first() # type: Agent
- agentFeatures = set(agent.features) if agent is not None else set([])
- dealer_features = map(lambda x: x['key'], filter(lambda x: x['value'] is True, dev.dealer['featureList']))
- if 'mini_recharge' in dealer_features:
- agentFeatures.add('mini_recharge')
- if 'mini_card_recharge' in dealer_features:
- agentFeatures.add('mini_card_recharge')
- devType = deepcopy(dev.devType)
- try:
- portDict = dev.deviceAdapter.get_port_status(force)
- if not force:
- dev.deviceAdapter.async_update_portinfo_from_dev()
- if portDict:
- chargeIndex = {}
- for index, info in portDict.items():
- if info['status'] == Const.DEV_WORK_STATUS_IDLE:
- chargeIndex[index] = 'idle'
- elif info['status'] == Const.DEV_WORK_STATUS_WORKING:
- chargeIndex[index] = 'busy'
- elif info['status'] == Const.DEV_WORK_STATUS_FAULT:
- chargeIndex[index] = 'fault'
- elif info['status'] == Const.DEV_WORK_STATUS_FORBIDDEN:
- chargeIndex[index] = 'ban'
- elif info['status'] == Const.DEV_WORK_STATUS_CONNECTED:
- chargeIndex[index] = 'connected'
- elif info['status'] == Const.DEV_WORK_STATUS_FINISHED:
- chargeIndex[index] = 'finished'
- elif info['status'] == Const.DEV_WORK_STATUS_ESTOP:
- chargeIndex[index] = 'estop'
- elif info['status'] == Const.DEV_WORK_STATUS_READY:
- chargeIndex[index] = 'ready'
- else:
- chargeIndex[index] = 'busy'
- devType.update({"chargeIndex": chargeIndex})
- except ServiceException as e:
- return JsonErrorResponse(description=e.result.get('description'))
- except Exception as e:
- logger.exception('cannot get_port_status, error=%s' % (str(e),))
- return JsonErrorResponse(description=u'未知错误')
- data = {
- "devType": devType,
- "groupId": dev.groupId,
- "cityId": dev.group.get('districtId', ''),
- "inFreeGroup": dev.group.get('isFree', False),
- "lbs": dev.lbs,
- "instructions": dev.get('instructions', ''),
- "logicalCode": dev.logicalCode,
- "payAfterAd": dev.dealer['adShow'],
- "dealerId": dev.ownerId,
- "dealerDes": dev.dealer['description'],
- 'devNo': dev.devNo,
- 'channelType': dev.channelType,
- 'avatarUrl': currentUser.avatar,
- 'nickname': currentUser.nickname,
- 'openId': currentUser.openId,
- 'agentFeatures': list(agentFeatures),
- 'countDown': False,
- 'bottomAd': dev.dealer.get('bottomAd', {}),
- 'noRecharge': dev.dealer.get('noRecharge', False),
- 'favorite': True if dev.devNo in currentUser.collectedDeviceList else False,
- "payAfterUse": dev.get("otherConf", dict()).get("payAfterUse", False),
- 'majorDeviceType': dev.majorDeviceType,
- 'subTemplateId': agent.get_user_sub_template_id_list(),
- 'priceDescription': dev.priceDescription,
- 'popPriceDescriptionButton': dev.group.popPriceDescriptionButton
- }
- if "hasTempPackage" in dev.dealer:
- if dev.devTypeCode in [Const.DEVICE_TYPE_CODE_WEIFULE_POLICY_CLASSIC]:
- data["hasTempPackage"] = False
- data["displayTempPackage"] = False
- elif dev.devTypeCode in support_policy_weifule + support_policy_device:
- try:
- data["displayTempPackage"] = dev.dealer.get("displayTempPackage", True)
- packages = dev.deviceAdapter.user_show_package(isTemp=True)
- if packages:
- data["hasTempPackage"] = True
- else:
- data["hasTempPackage"] = False
- except Exception as e:
- logger.error("[equipmentPara] get hasTempPackage error = {}".format(e))
- data["hasTempPackage"] = False
- else:
- if dev.dealer.get("hasTempPackage", None) is True:
- data["hasTempPackage"] = dev.dealer.get("hasTempPackage")
- data["displayTempPackage"] = dev.dealer.get("displayTempPackage", True)
- if dev.need_fetch_online:
- data.update({'online': DeviceOnlineStatus.DEV_STATUS_ONLINE})
- else:
- data.update({'online': DeviceOnlineStatus.DEV_STATUS_OFFLINE})
- if "telVerify" in agent.features:
- needTelVerify = check_user_tel(request.user)
- data.update({
- "needTelVerify": needTelVerify
- })
- data.update({'countDown': dev.deviceAdapter.support_count_down()})
- if dev.devTypeCode == Const.DEVICE_TYPE_CODE_TIMESWITCH7:
- pricePerHour = dev.my_obj.otherConf.get('pricePerHour', 2.0)
- data.update({'pricePerHour': pricePerHour})
- elif dev.devTypeCode in [
- Const.DEVICE_TYPE_CODE_CAR_NENGPAI,
- Const.DEVICE_TYPE_CODE_CHARGE_WEIFULE_CAR,
- Const.DEVICE_TYPE_CODE_CAR_WEIFULE_CHARGING_DOUB,
- Const.DEVICE_TYPE_CODE_CAR_WEIFULE_21KW,
- Const.DEVICE_TYPE_CODE_CAR_WEIFILE_HOME_JFPG,
- Const.DEVICE_TYPE_CODE_CAR_WEIFILE_HOME_DOUB_JFPG,
- ]:
- infos = dev.deviceAdapter.get_policy_for_user()
- data.update({"policyInfos": infos})
- resultResponse = JsonResponse({'result': 1, 'description': '', 'payload': data})
- resultResponse = Agent.record_cookie(dev.dealer['agentId'], resultResponse)
- return resultResponse
- @error_tolerate(nil = defaultErrorResponseRedirect)
- @permission_required(ROLE.myuser)
- def deviceInfo(request):
- """
- 通过logicalCode获取 设备的一些基本信息, 功能上需要和equipment区分开
- :param request:
- :return:
- """
- logicalCode = request.GET.get("logicalCode")
- if not logicalCode:
- return JsonErrorResponse(description = u"无效的设备编号")
- dev = Device.get_dev_by_l(logicalCode)
- if not dev:
- return JsonErrorResponse(description = u"无效的设备编号")
- group = Group.get_group(dev.get("groupId", ""))
- # TODO zjl 目前只添加这些信息,后续有需要再添加 但是此接口定义为获取设备的简易信息 需要和equipment区分
- data = {
- "devNo": dev.get("devNo", ""),
- "logicalCode": dev.get("logicalCode", ""),
- "ownerId": dev.get("ownerId", ""),
- "groupId": dev.get("groupId", ""),
- "groupName": group.get("groupName", ""),
- "isFree": group.get("isFree", False)
- }
- return JsonOkResponse(payload = data)
- @permission_required(ROLE.myuser)
- def userBalance(request):
- # type: (WSGIRequest)->JsonResponse
- """
- 用户余额
- 用户余额是以地址为单位建立 但是由于地址可以设置通用 并且个人中心也需要显示总余额
- """
- logicalCode = request.GET.get("logicalCode")
- if not logicalCode:
- overallBalance = sum((u.balance for u in request.user.product_users), RMB(0))
- return JsonOkResponse(
- payload={
- 'balance': overallBalance,
- 'overallBalance': overallBalance,
- 'currencyCoins': overallBalance
- })
- dev = Device.get_dev_by_l(logicalCode) # type: DeviceDict
- if not dev:
- return JsonErrorResponse(description=u'设备没有注册,或者二维码错误,请联系客服处理')
- if not dev.is_registered:
- return JsonErrorResponse(description=u'设备没有注册,请联系客服处理')
- if dev.ownerId != dev.group.ownerId:
- return JsonErrorResponse(description=u'设备注册信息错误,请联系客服处理')
- if dev.group.groupId != request.user.groupId:
- product_agent = get_user_manager_agent(dev.owner) # type: Agent
- if str(product_agent.id) != request.user.productAgentId:
- return JsonErrorResponse(description=u'设备投放地址不属于该平台,请重新扫描设备二维码。')
- # 分别为用户总余额、用户经销商下的余额、用户的通用地址余额
- overall, dealer_balance, usable_balance = request.user.get_balance_in_dealer(dev.owner, dev.group)
- return JsonOkResponse(
- payload={
- 'balance': usable_balance,
- 'balanceInDealer': dealer_balance,
- 'overallBalance': overall
- })
- @permission_required(ROLE.myuser)
- def getBalanceList(request):
- # type: (WSGIRequest)->Union[HttpResponse,JsonResponse]
- """
- 用户账户详情
- :param request:
- :return:
- """
- pageIndex = int(request.GET.get('pageIndex', 1))
- pageSize = int(request.GET.get('pageSize', 10))
- currentGroupId = request.GET.get('groupId', None)
- if currentGroupId == '-1':
- currentGroupId = None
- if currentGroupId:
- current_group = Group.get_group(currentGroupId) # type: GroupDict
- else:
- current_group = None # type: None
- totalCharge, totalBestow, total, dataList = request.user.filter_my_balance(current_group)
- cmp_dealer = lambda x, y: 1 if x['dealerId'] > y['dealerId'] else -1
- dataList.sort(cmp = cmp_dealer)
- return JsonResponse(
- {
- 'result': 1,
- 'description': '',
- 'payload': {
- 'totalCharge': totalCharge,
- 'totalBestow': totalBestow,
- 'total': total,
- 'dataList': dataList[(pageIndex - 1) * pageSize:pageIndex * pageSize]
- }
- }
- )
- def asynDiscountList(request):
- # type: (WSGIRequest)->JsonResponse
- """
- 用户充值菜单
- :param request:
- :return:
- """
- devNo = Device.get_dev_no_from_request(request)
- dev = Device.get_dev(devNo)
- if dev is None:
- return JsonResponse({'result': 0, 'description': u'该设备未开通网络支付,请投币或者联系客服(1000)', 'payload': {}})
- group = Group.get_group(dev['groupId']) # type:GroupDict
- if not group:
- return JsonResponse({'result': 0, 'description': u'该设备未开通网络支付,请投币或者联系客服(1001)', 'payload': {}})
- return JsonResponse({
- 'result': 1,
- 'description': 'SUCCESS',
- 'payload': {
- 'discountList': group.recharge_rule_list
- }
- })
- @permission_required(ROLE.myuser)
- def getPackage(request):
- # type: (WSGIRequest)->JsonResponse
- """
- 获取设备套餐
- :param request:
- :return:
- """
- devNo = request.GET.get("devNo")
- device = Device.get_dev(devNo) # type: DeviceDict
- if device is None:
- return JsonResponse({'result': 0, 'description': u'无此设备', 'payload': {}})
- washConfig = device['washConfig']
- otherConf = device.get('otherConf')
- if "displaySwitchs" in otherConf:
- displaySwitchs = otherConf.get('displaySwitchs')
- displaySwitchs = dict(filter(lambda x: "display" in x[0], displaySwitchs.items()))
- else:
- displaySwitchs = {
- 'displayCoinsSwitch': True,
- 'displayTimeSwitch': True,
- 'displayPriceSwitch': True
- }
- if device.devTypeCode in support_policy_weifule + support_policy_device + [
- Const.DEVICE_TYPE_CODE_CAR_CHANGING_JINQUE,
- Const.DEVICE_TYPE_CODE_CAR_WEIFILE_HOME_JFPG,
- Const.DEVICE_TYPE_CODE_CAR_WEIFILE_HOME_DOUB_JFPG,
- Const.DEVICE_TYPE_CODE_CHARGE_XIAOKEDOU
- ]:
- try:
- if device.deviceAdapter.support_device_package:
- packages = device.deviceAdapter.user_show_package()
- return JsonResponse({'result': 1, 'description': 'SUCCESS', 'payload': packages})
- except Exception as e:
- logger.exception(e)
- return JsonResponse({'result': 0, 'description': '当前套餐参数有误, 请联系经销商重新配置', 'payload': []})
- packages = []
- for packageId, rule in washConfig.items():
- # 没有启用的套餐 直接掠过
- if not rule.get("switch", True):
- continue
- price = rule['price']
- imgList = []
- try:
- for img in rule.get('imgList', []):
- if img.startswith('/'):
- imgList.append('{}{}'.format(settings.OSS_RESOURCE_URL, img))
- else:
- imgList.append(img)
- except Exception as e:
- logger.exception(e)
- imgList = rule.get('imgList', [])
- item = {
- 'id': packageId,
- 'name': rule['name'],
- 'time': rule['time'],
- 'price': price,
- 'description': rule.get('description', ''),
- 'imgList': imgList,
- 'unit': rule.get('unit', u'分钟'),
- }
- if rule.get('basePrice'):
- item.update({'basePrice': rule.get('basePrice')})
- if rule.get('sn', None) is not None:
- item.update({'sn': rule.get('sn')})
- if rule['name'] == u'充满自停' and float(rule['coins']) == 0 and float(price) == 0:
- item.update({'displayCoinsSwitch': False, 'displayTimeSwitch': False, 'displayPriceSwitch': False})
- else:
- item.update(displaySwitchs)
- packages.append(item)
- packages = sorted(packages, key=lambda x: (x.get('sn'), x.get('price')))
- return JsonResponse({'result': 1, 'description': 'SUCCESS', 'payload': packages})
- @permission_required(ROLE.myuser)
- def getTempPackage(request):
- # type: (WSGIRequest)->JsonResponse
- """
- 设备套餐
- :param request:
- :return:
- """
- def cmp_by_price(x, y):
- if x['price'] < y['price']:
- return -1
- elif x['price'] > y['price']:
- return 1
- else:
- return 0
- devNo = Device.get_dev_no_from_request(request)
- if not devNo:
- return JsonResponse({'result': 0, 'description': u'获取数据失败,请重新扫码登录'})
- device = Device.get_dev(devNo)
- if device is None:
- return JsonResponse({'result': 0, 'description': u'无此设备', 'payload': {}})
- if device['devType']['code'] in support_policy_weifule + support_policy_device:
- try:
- if device.deviceAdapter.support_device_package:
- packages = device.deviceAdapter.user_show_package(isTemp=True)
- if not packages:
- return JsonResponse({'result': 0, 'description': '当前设备未配置临时套餐, 请联系经销商去配置', 'payload': {}})
- else:
- return JsonResponse({'result': 1, 'description': 'SUCCESS', 'payload': packages})
- else:
- return JsonResponse({'result': 0, 'description': '当前套餐参数有误, 请联系经销商重新配置', 'payload': []})
- except:
- return JsonResponse({'result': 0, 'description': '当前套餐参数有误, 请联系经销商重新配置', 'payload': []})
- elif device['devType']['code'] in [Const.DEVICE_TYPE_CODE_CAR_CHANGING_JINQUE, Const.DEVICE_TYPE_CODE_CAR_WEIFILE_HOME_JFPG,Const.DEVICE_TYPE_CODE_CAR_WEIFILE_HOME_DOUB_JFPG,]:
- tempWashConfig = device['tempWashConfig']
- if not tempWashConfig:
- return JsonResponse({'result': 0, 'description': u'当前设备未配置临时套餐, 请联系经销商去配置', 'payload': {}})
- packages = device.deviceAdapter.user_show_package(isTemp=True)
- return JsonResponse({'result': 1, 'description': 'SUCCESS', 'payload': packages})
- if device['tempWashConfig'] == {}:
- Device.get_and_update_device_cache(device["devNo"], tempWashConfig = device['washConfig'])
- device = Device.get_dev(devNo)
- tempWashConfig = device['tempWashConfig']
- otherConf = device.get('otherConf')
- if "displayTempSwitchs" in otherConf:
- displayTempSwitchs = otherConf.get('displayTempSwitchs')
- displayTempSwitchs = dict(filter(lambda x: "display" in x[0], displayTempSwitchs.items()))
- else:
- displayTempSwitchs = {'displayCoinsSwitch': True,
- 'displayTimeSwitch': True,
- 'displayPriceSwitch': True,
- }
- group = Group.get_group(device['groupId'])
- # 探测是否地址为免费活动组,默认为否
- is_free_service = group.get('isFree', False)
- appendix = u' 免费使用' if is_free_service else ''
- packages = []
- for packageId, rule in tempWashConfig.items():
- item = {
- 'id': packageId,
- 'coins': rule['coins'],
- 'name': rule['name'] + appendix,
- 'time': rule['time'],
- 'price': rule['price'],
- 'description': rule.get('description', ''),
- 'imgList': rule.get('imgList', []),
- 'unit': rule.get('unit', u'分钟')
- }
- if rule.get('basePrice'):
- item.update({'basePrice': rule.get('basePrice')})
- if rule.get('sn', None) is not None:
- item.update({'sn': rule.get('sn')})
- item.update(displayTempSwitchs)
- packages.append(item)
- packages = sorted(packages, key = lambda x: (x.get('sn'), x.get('price')))
- return JsonResponse({'result': 1, 'description': 'SUCCESS', 'payload': packages})
- def authCallback(request, gateway):
- try:
- state = UserAuthState.decode(str(request.GET.get('payload'))) # type: UserAuthState
- if not state.is_valid():
- return ErrorResponseRedirect(error = cn(u'网络异常,请重新扫码(10000)'))
- if state.by == UserAuthState.BY.AGENT:
- source = Agent.objects(id = str(state.agentId)).get() # type: Agent
- group_id = MyUser.groupId.default
- dealer = None
- else:
- dev = Device.get_dev(state.devNo) # type: DeviceDict
- if not dev:
- return ErrorResponseRedirect(error = u'该设备未开通网络支付,请投币或者联系客服(1006)')
- source = dealer = dev.owner
- if not dealer:
- return ErrorResponseRedirect(error = u'该设备未开通网络支付,请投币或者联系客服(1007)')
- group_id = dev.groupId
- # 配置平台的代理商ID必定配置自定义公众号, 否则扫码客户无法知道平台代理商是谁
- product_agent = get_user_manager_agent(source)
- if str(product_agent.id) != state.productAgentId:
- return ErrorResponseRedirect(error = u'系统配置错误,请联系平台客服(10004)')
- if gateway == AppPlatformType.ALIPAY:
- auth_bridge = get_ali_auth_bridge(source = product_agent,
- app_type = APP_TYPE.ALIPAY_AUTH) # type: AlipayAuthBridge
- else:
- return ErrorResponseRedirect(error = cn(u'参数错误,请重新扫码(10001)'))
- auth_code = request.GET.get(auth_bridge.auth_code_key)
- if not auth_code:
- return ErrorResponseRedirect(error = cn(u'参数错误,请重新扫码(10002)'))
- user_info = auth_bridge.get_user_info(auth_code = auth_code)
- open_id = user_info.pop('openId')
- user = MyUser.get_or_create(
- app_platform_type = auth_bridge.gateway_type,
- open_id = open_id,
- group_id = group_id,
- authAppId = auth_bridge.appid,
- agentId = state.agentId,
- productAgentId = state.productAgentId,
- payOpenIdMap = {
- auth_bridge.bound_openid_key: BoundOpenInfo(openId = open_id)
- },
- **user_info)
- if state.by == UserAuthState.BY.AGENT:
- response = FrontEndResponseRedirect(state.href)
- else:
- response = get_homepage_response(gateway, user, dev, state.chargeIndex if state.chargeIndex else '',
- product_agent)
- return response_with_login(request, user, response)
- except AliException as e:
- logger.error(repr(e))
- return ErrorResponseRedirect(error = cn(e.errMsg))
- @error_tolerate(nil = u"获取消费详情失败", logger = logger)
- @permission_required(ROLE.myuser)
- def getConsumeRecord(request):
- """
- 获取用户的单一的 消费订单记录
- :param request:
- :return:
- """
- recordId = request.GET.get("id", None)
- cardTicketId = request.GET.get('cardTicketId', None)
- # 这个接口是同时 查询虚拟卡消费记录 以及用户的直接消费记录 的入口
- if not any([recordId, cardTicketId]):
- return JsonErrorResponse(description = u'参数错误,请刷新后再试')
- if recordId:
- ownerId = request.GET.get('ownerId', None)
- if ownerId:
- record = ClientConsumeModelProxy.get_one(shard_filter = {'ownerId': ownerId},
- id = recordId) # type: ConsumeRecord
- else:
- record = ConsumeRecord.objects(id = recordId).first()
- else:
- record = VCardConsumeRecord.objects(id = cardTicketId).first() # type: VCardConsumeRecord
- if not record:
- return JsonErrorResponse(description = u"未查询到相应订单,请刷新页面重试")
- payload = record.to_user_detail()
- try:
- agentId = request.user.productAgentId
- agent = Agent.objects.get(id = agentId)
- except Exception as e:
- logger.exception(e)
- agent = None
- if payload.get("actualNeedTime"):
- elecKeys = [_key for _key in payload.keys() if _key.startswith("elec") or _key.endswith("elec")]
- for _elecKey in elecKeys:
- payload.pop(_elecKey, None)
- if not agent or 'show_elec_data_for_user' not in agent.features:
- payload.pop('elec', None)
- payload.pop('needElec', None)
- if agent and 'hide_time_data_for_user' in agent.features:
- payload.pop("leftTime", None)
- payload.pop("duration", None)
- payload = UserConsumeFilter(record.owner, payload).filter()
- return JsonOkResponse(payload = payload)
- @permission_required(ROLE.myuser)
- def asynTransactionRecord(request):
- # type: (WSGIRequest)->JsonResponse
- """
- 用户消费记录
- :param request:
- :return: JsonResponse
- """
- pageIndex = int(request.GET.get('pageIndex', 1))
- pageSize = int(request.GET.get('pageSize', 10))
- startTime = request.GET.get('startTime', Const.QUERY_START_DATE)
- endTime = request.GET.get('endTime', datetime.datetime.now().strftime('%Y-%m-%d'))
- dataList = []
- if 'cardTicketId' in request.GET and request.GET.get('cardTicketId'):
- records = VCardConsumeRecord.objects.filter(cardId = request.GET.get('cardTicketId')).order_by('-dateTimeAdded')
- total = records.count()
- for rcd in records.paginate(pageIndex, pageSize):
- dataList.append(rcd.summary)
- else:
- dealer_ids = MyUser.get_dealer_ids(openId = request.user.openId, productAgentId = request.user.productAgentId)
- if len(dealer_ids) > 0:
- records = ClientConsumeModelProxy.get_data_list(
- ownerId__in = dealer_ids,
- startTime = startTime,
- endTime = endTime,
- openId = request.user.openId,
- isNormal = True,
- hint = [('openId', 1), ('dateTimeAdded', -1)]) # type: CustomQuerySet
- total = records.count()
- for rcd in records.paginate(pageIndex, pageSize):
- dataList.append(rcd.summary)
- else:
- total = 0
- return JsonResponse(
- {
- 'result': 1,
- 'description': '',
- 'payload': {'total': total, 'dataList': dataList}
- })
- @permission_required(ROLE.myuser)
- def getChargeRecordDetail(request):
- # type: (WSGIRequest)->JsonResponse
- """
- 用户充值详细记录
- :param request:
- :return: JsonResponse
- """
- _id = str(request.GET.get('id'))
- ownerId = request.GET.get('ownerId')
- record = ClientRechargeModelProxy.get_one(shard_filter = {'ownerId': ownerId}, id = _id) # type: RechargeRecord
- if not record:
- return JsonResponse({'result': 1, 'description': '', 'payload': {}})
- payload = {
- 'createdTime': record.dateTimeAdded,
- 'orderNo': record.orderNo,
- 'amount': record.my_amount,
- 'groupName': record.groupName,
- 'groupNumber': record.groupNumber,
- 'address': record.address,
- 'logicalCode': record.logicalCode,
- 'devTypeName': record.dev_type_name,
- 'via': record.via,
- 'ownerId': record.ownerId
- }
- payload.update(record.extra_detail_info)
- return JsonResponse(
- {
- 'result': 1,
- 'description': '',
- 'payload': payload
- }
- )
- @permission_required(ROLE.myuser)
- def hybridStartAction(request):
- """
- 此处有红包链接, 可以判断出往下走的流程是拉起支付还是直接启动
- """
- payload = json.loads(request.body)
- urlId = payload.get('urlId')
- dev = Device.get_dev(payload['devNo'])
- if not dev:
- return JsonErrorResponse(description= '设备参数缺失, 请重试')
- if not urlId:
- return JsonErrorResponse(description='传入参数有误, 请重试')
- url = payload.pop('url', None)
- payload = {
- "packageId": payload['packageId'],
- "groupId": dev.groupId,
- "devNo": dev['devNo'],
- "logicalCode": dev['logicalCode'],
- "openId": payload['openId'],
- "attachParas": payload['attachParas']
- }
- serviceCache.set('urlId_{}'.format(urlId), payload)
- return JsonResponse(
- {
- 'result': 1,
- 'description': '',
- 'payload': {'url': url}
- }
- )
- @permission_required(ROLE.myuser)
- def getHybridStartActionInfo(request):
- """
- 返回缓存的参数 直接拉起支付
- """
- payload = json.loads(request.body)
- urlId = payload.get('mktId')
- openId = request.user.openId
- redpack = Redpack.objects.filter(openId=openId, urlId=urlId).first()
- if redpack:
- if redpack.taskStatus != redpack.Result.FINISHED:
- try:
- # 去查询
- ApiRequest = json.loads(redpack.extra.get('ApiRequest', ''))
- clicklink = ApiRequest['Seatbid'][0]['Bid'][0]['Ads'][0]['Trackers']['Imps'][0]
- adid = ApiRequest['Seatbid'][0]['Bid'][0]['Ads'][0]['Id']
- from apps.thirdparties.aliyun import AlipayYunMaV3
- resp = AlipayYunMaV3().query_task_status(
- clicklink=clicklink,
- openId=openId,
- adid=adid,
- )
- if resp.body.success and resp.body.result.success:
- redpack = Redpack.take_effect(openId=openId, urlId=urlId,
- **{'ApiResult': json.dumps(resp.body.result.to_map(),
- ensure_ascii=False)})
- RedpackBuilder._set_alipay_key(openId, redpack.factoryCode, urlId, redpack.money.mongo_amount,
- showType=redpack.showType)
- else:
- pass
- except:
- import traceback
- logger.error(traceback.format_exc())
- else:
- pass
- if redpack.taskStatus == redpack.Result.FINISHED:
- cacheInfo = serviceCache.get('urlId_{}'.format(urlId))
- serviceCache.delete('urlId_{}'.format(urlId))
- if urlId and cacheInfo:
- logicalCode = cacheInfo['logicalCode']
- attachParas = cacheInfo['attachParas']
- device = Device.get_dev_by_l(logicalCode)
- if "isTempPackage" in attachParas and attachParas['isTempPackage'] is True:
- washConfig = device["tempWashConfig"]
- else:
- washConfig = device["washConfig"]
- package = washConfig.get(cacheInfo['packageId'])
- if not package:
- payload = {
- "startAction": False,
- "logicalCode": logicalCode
- }
- else:
- showInfo = {
- 'goodsInfo': {
- 'name': '{}, {}'.format(device.majorDeviceType, device.logicalCode),
- 'port': attachParas.get('chargeIndex'),
- },
- 'packageInfo': {
- 'name': '{}{}'.format(package.get('time', ''), package.get('unit', '')),
- 'coins': package['coins'],
- 'price': package['price']
- },
- 'redPackInfo': {
- 'price': min(redpack.money.amount, package['price']),
- # 'coins': Redpack.pre_deducted_coins(str(redpack.id), package),
- },
- # 'checkoutInfo': {
- # 'price': (RMB(package['price']) - redpack.money).mongo_amount,
- # 'coins': RMB(package['coins'] - Redpack.pre_deducted_coins(str(redpack.id), package)).mongo_amount,
- # },
- }
- attachParas['redpackId'] = str(redpack.id)
- payload = {
- "packageId": cacheInfo['packageId'],
- "groupId": cacheInfo['groupId'],
- "devNo": cacheInfo['devNo'],
- "logicalCode": logicalCode,
- "openId": cacheInfo['openId'],
- "attachParas": attachParas,
- "startAction": True,
- 'showInfo': showInfo
- }
- else:
- payload = {
- "startAction": False,
- "logicalCode": redpack.logicalCode
- }
- return JsonResponse(
- {
- 'result': 1,
- 'description': '',
- 'payload': payload
- }
- )
- else:
- return JsonResponse(
- {
- 'result': 1,
- 'description': '',
- 'payload': {'startAction': False}
- }
- )
- @error_tolerate(nil = JsonErrorResponse(description = u'系统错误'), logger = logger)
- @permission_required(ROLE.myuser)
- def submitFeedback(request):
- # type: (WSGIRequest)->JsonResponse
- """
- 用户提交反馈
- :param request:
- :return:
- """
- openId = request.user.openId
- with memcache_lock(key="{openId}.submitFeedBack".format(openId=openId), value='1', expire=60) as acquired:
- if acquired:
- try:
- payload = feedbackSchema(json.loads(request.body))
- except MultipleInvalid as e:
- logger.exception(e)
- return JsonErrorResponse(description = u"信息不完整,请补充信息或尝试重新扫码")
- dev = Device.get_dev_by_logicalCode(payload['detailInfo']['logicalCode']) # type: DeviceDict
- if not dev:
- return JsonErrorResponse(description = u"当前设备不存在,请重新扫码")
- if not dev.is_registered:
- return JsonErrorResponse(description = u'当前设备已经被运营商解绑定(1001)')
- group = dev.group # type: GroupDict
- if group is None:
- logger.error('[submitFeedback] failed to get group, device\'s logicalCode=%s groupId=%s'
- % (dev['logicalCode'], dev['groupId']))
- return JsonErrorResponse(description = u"当前设备已经被运营商解绑定(1002)")
- feedbackPayload = {
- 'openId': openId,
- 'ownerId': dev.ownerId,
- 'nickname': request.user.nickname,
- 'description': payload['description'],
- 'phone': payload['phone'],
- 'feedType': payload['feedType'],
- 'imgList': payload['imgList'],
- 'isRead': True
- }
- detail_info = payload.pop('detailInfo')
- if payload['feedType'] == 'netpay':
- detail_info = {
- 'orderNo': detail_info['orderNo']
- }
- detail_info.update(dev.identity_info)
- feedbackPayload['detailInfo'] = detail_info
- feedback = FeedBack(**feedbackPayload).save()
- if bool(payload.get('orderNo')) and not feedbackPayload['feedType'] == 'fault':
- order = ConsumeRecord.objects(
- ownerId = dev.ownerId,
- orderNo = feedbackPayload['consumeRecordOrderNo']
- ).first() # type: ConsumeRecord
- if not order:
- return JsonErrorResponse(description = u'您选择的订单不存在,请重新选择。')
- if order.feedbackId:
- return JsonErrorResponse(description = u'您选择的订单已有投诉反馈,请等待设备运营商处理。')
- updated = order.update(feedbackId = ObjectId(feedback.id))
- if not updated:
- logger.info('failed to update ConsumeRecord feedbackId = %s' % (str(feedback.id),))
- dealer = Dealer.objects(id = str(dev['ownerId'])).first()
- if dealer is None:
- logger.error('[submitFeedback] cannot get dealer by id = %s' % (str(dev['ownerId']),))
- return JsonOkResponse()
- agent = Agent.objects(id = str(dealer.agentId)).first()
- if agent is None:
- logger.error('[submitFeedback] cannot get agent by id = %s' % (str(dealer.agentId),))
- return JsonOkResponse()
- if payload['feedType'] == 'fault':
- msgType = u'设备故障'
- else:
- msgType = u'订单投诉'
- msg = u'尊敬的%s用户%s,您的客户刚才给您报告了一条【%s】的信息,请您登录后台,从【用户反馈】查看详情' \
- % (agent.productName, dealer.nickname, msgType)
- task_caller('report_feedback_to_dealer_via_wechat', dealerId = str(dealer.id),
- msg = msg,
- nickname = request.user.nickname,
- feedbackTime = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
- return JsonOkResponse()
- else:
- return JsonErrorResponse(description = u'您已正在提交')
- @error_tolerate(nil = JsonErrorResponse(description = u'获取反馈失败'), logger = logger)
- @permission_required(ROLE.myuser)
- def getFeedbackList(request):
- # type: (WSGIRequest)->JsonResponse
- """
- 用户提交反馈
- :param request:
- :return:
- """
- openId = request.user.openId
- pageIndex = int(request.GET.get('pageIndex', 1))
- pageSize = int(request.GET.get('pageSize', 10))
-
- dealerIds = MyUser.get_dealer_ids(openId, request.user.productAgentId)
- feedbacks = FeedBack.objects(openId = openId, ownerId__in = dealerIds) \
- .order_by('-createTime') \
- .paginate(pageIndex, pageSize) # type: CustomQuerySet
- total = feedbacks.count()
- items = []
- for item in feedbacks: # type: FeedBack
- items.append(item.summary)
- return JsonResponse(
- {
- 'result': 1,
- 'description': "",
- 'payload': {
- 'total': total,
- 'dataList': items
- }
- }
- )
- @error_tolerate(nil = JsonErrorResponse(description = u'系统错误'), logger = logger)
- @permission_required(ROLE.myuser)
- def getFeedbackDetail(request):
- id_ = request.GET.get('id')
- feedback = FeedBack.objects(id = id_).first() # type: FeedBack
- if not feedback:
- return JsonErrorResponse(description = u'没有找到反馈单,请刷新试试')
- else:
- if not feedback.isRead:
- feedback.isRead = True
- feedback.save()
- return JsonResponse({'result': 1, 'description': '', 'payload': feedback.detail})
-
- @error_tolerate(nil = JsonErrorResponse(description = u'系统错误'), logger = logger)
- @permission_required(ROLE.myuser)
- def getFeedbackConfigs(request):
- # type: (WSGIRequest)->JsonResponse
- """
- :param request:
- :return:
- """
- logicalCode = request.GET.get('logicalCode')
- # if not logicalCode:
- # return JsonErrorResponse(description = u'找不到设备编号')
- dev = Device.get_dev_by_l(logicalCode) or dict()
- #: 暂时只是显示充电桩的端口
- devTypeName = dev.get("devType", dict()).get("name", "")
- if re.match(ur"充电桩", devTypeName):
- payload = {"port": [str(_) for _ in range(1, 21)]}
- else:
- payload = {}
- return JsonResponse({'result': 1, 'description': '', 'payload': payload})
- @error_tolerate(nil = JsonErrorResponse(description = u'系统错误'), logger = logger)
- @permission_required(ROLE.myuser)
- def getConsumeRecordsForFeedback(request):
- # type: (WSGIRequest)->JsonResponse
- """
- :param request:
- :return:
- """
- pageIndex = int(request.GET.get('pageIndex', 1))
- pageSize = int(request.GET.get('pageSize', 10))
- skip = (pageIndex - 1) * pageSize
- logicalCode = request.GET.get('logicalCode', None)
- if logicalCode:
- device = Device.get_dev_by_logicalCode(logicalCode)
- if not device:
- return JsonErrorResponse(description = u'设备不存在,请重新扫码')
- ownerIds = [device.ownerId]
- else:
- ownerIds = MyUser.get_dealer_ids(request.user.openId, request.user.productAgentId)
- records = ConsumeRecord.objects(
- ownerId__in = ownerIds,
- openId = request.user.openId,
- dateTimeAdded__gte = (datetime.datetime.now() - datetime.timedelta(days = 30)),
- feedbackId__exists = 0).order_by("-dateTimeAdded") # type: CustomQuerySet
- dataList = []
- for record in records.skip(skip).limit(pageSize): # type: ConsumeRecord
- dataList.append(record.info_for_feedback)
- return JsonResponse(
- {
- 'result': 1,
- 'description': '',
- 'payload': {'total': records.count(), 'dataList': dataList}
- })
- def getNearbyDevicesFromDB(lng, lat, pageIndex, pageSize, maxDistance, agentId, devTypeName, groupId = None):
- def hav(theta):
- s = sin(theta / 2)
- return s * s
- def get_distance_hav(lat0, lng0, lat1, lng1):
- if lat1 == 360 or lng1 == 360:
- return -1
- EARTH_RADIUS = 6371000
- lat0 = radians(lat0)
- lat1 = radians(lat1)
- lng0 = radians(lng0)
- lng1 = radians(lng1)
- dlng = fabs(lng0 - lng1)
- dlat = fabs(lat0 - lat1)
- h = hav(dlat) + cos(lat0) * cos(lat1) * hav(dlng)
- return int(2 * EARTH_RADIUS * asin(sqrt(h)))
- def formatDeviceInfo(dev, devTypeName):
- # type: (DeviceDict, basestring)->Optional[Dict]
- logger.debug('try to format device<l={}, devNo={}> info.'.format(dev.logicalCode, dev.devNo))
- distance = get_distance_hav(lat, lng, float(dev['lat']), float(dev['lng']))
- group = Group.get_group(dev['groupId'])
- if group is None:
- return None
- package = [
- {
- 'name': rule.get('name', ''),
- 'coins': rule['coins'],
- 'price': rule.get('price', rule['coins']),
- 'time': rule.get('time', 20),
- 'unit': rule.get('unit', u'分钟')
- } for packageId, rule in dev['washConfig'].items()]
- return {
- 'devNo': dev.devNo,
- 'type': devTypeName,
- 'logicalCode': dev.logicalCode,
- 'groupName': group['groupName'],
- 'groupNumber': dev['groupNumber'],
- 'groupId': dev.groupId,
- 'address': group['address'],
- 'online': dev.online,
- 'status': dev.status,
- 'signal': dev.signal,
- 'remarks': dev['remarks'],
- 'distance': distance,
- 'lng': float(dev.lng),
- 'lat': float(dev.lat),
- 'often': False,
- 'beingUsed': False,
- 'package': package,
- 'devTypeCode': dev.devType['code']
- }
- if not agentId:
- logger.error('agent is null.')
- return {
- 'total': 0,
- 'items': []
- }
- dealers = Dealer.get_dealers(agentId)
- if not dealers:
- return {
- 'total': 0,
- 'items': []
- }
- if groupId:
- devices = Device.get_collection().find({'groupId': groupId})
- else:
- if devTypeName:
- devices = Device.get_collection().find(
- {
- 'ownerId': {'$in': dealers},
- '$where': 'this.devType != null && this.devType.name == "%s"' % devTypeName,
- 'isFault': False,
- 'location': {
- '$near': {'$geometry': {'type': 'Point', 'coordinates': [lng, lat]},
- '$maxDistance': maxDistance}}})
- else:
- devices = Device.get_collection().find(
- {
- 'ownerId': {'$in': dealers},
- 'isFault': False,
- 'location': {
- '$near': {'$geometry': {'type': 'Point', 'coordinates': [lng, lat]},
- '$maxDistance': maxDistance}}})
- items = []
- for dev in devices:
- dev = DeviceDict(dev) # type: DeviceDict
- if dev is None or not dev.lbs:
- continue
- try:
- devInfo = formatDeviceInfo(dev, dev.devType.get('name', '')) # type: Dict
- except Exception as e:
- logger.exception(e)
- continue
- if devInfo is None:
- continue
- items.append(devInfo)
- return_items = items[(pageIndex - 1) * pageSize:pageIndex * pageSize]
- dev_ctrl_map = Device.get_many_dev_control_cache([item['devNo'] for item in return_items])
- for item in return_items:
- # 换电柜的端口显示可用电池数量
- if item['devTypeCode'] in [Const.DEVICE_TYPE_CODE_CHARGING_AQKJ, Const.DEVICE_TYPE_CODE_CHARGING_AQKJ_NEW]:
- dev_ctrl_info = dev_ctrl_map.get(device_control_cache_key(item['devNo']), {})
- item["canUseBattery"] = dev_ctrl_info.get("canUseBattery", 0)
- elif Const.DEVICE_TYPE_CODE_CHARGING_KYXN <= item['devTypeCode'] < Const.DEVICE_TYPE_CODE_WASHER_BASE:
- dev_ctrl_info = dev_ctrl_map.get(device_control_cache_key(item['devNo']), {})
- item['allPorts'] = dev_ctrl_info.get('allPorts', 10)
- item['usedPorts'] = dev_ctrl_info.get('usedPorts', 0)
- item['usePorts'] = dev_ctrl_info.get('usePorts', 10)
- if 'power' in dev_ctrl_info:
- item['power'] = dev_ctrl_info['power']
- payload = {
- 'total': len(items),
- 'items': return_items
- }
- return payload
- @permission_required(ROLE.myuser)
- def getNearbyGroups(request):
- # type: (WSGIRequest)->JsonResponse
- try:
- lng = float(request.GET.get('lng'))
- lat = float(request.GET.get('lat'))
- maxDistance = int(request.GET.get('distance', 3000))
- logger.debug('now location. lat = %s; lng = %s' % (lat, lng))
- if maxDistance > Const.NEAR_BY_MAX_DISTANCE:
- maxDistance = Const.NEAR_BY_MAX_DISTANCE
- if lng == 360 or lat == 360 or isnan(lng) or isnan(lat):
- return JsonResponse({'result': 0, 'description': u'定位失败,请打开位置权限,刷新后重试'})
- payload = getNearbyDevicesFromDB(lng, lat, 1, 1000, maxDistance, request.user.agentId,
- request.GET.get('type', None))
- groupDict = {}
- for dev in payload['items']:
- if groupDict.has_key(dev['groupId']):
- groupDict[dev['groupId']]['allDevices'] += 1
- if dev['status'] == Const.DEV_WORK_STATUS_IDLE:
- groupDict[dev['groupId']]['idleDevices'] += 1
- else:
- newValue = {
- 'distance': dev['distance'],
- 'lng': float(dev['lng']),
- 'lat': float(dev['lat']),
- 'address': dev['address'],
- 'groupName': dev['groupName'],
- 'groupId': dev['groupId'],
- 'allDevices': 1,
- 'idleDevices': 1 if dev['status'] == Const.DEV_WORK_STATUS_IDLE else 0
- }
- groupDict[dev['groupId']] = newValue
- payload = {'total': len(groupDict.values()), 'items': groupDict.values()}
- return JsonResponse({'result': 1, 'description': '', 'payload': payload})
- except Exception as e:
- logger.exception(e)
- return JsonResponse({'result': 0, 'description': u'获取附近设备失败'})
- @permission_required(ROLE.myuser)
- def getNearbyDevices(request):
- # type: (WSGIRequest)->JsonResponse
- try:
- groupId = request.GET.get('groupId', None)
- lng = float(request.GET.get('lng'))
- lat = float(request.GET.get('lat'))
- maxDistance = int(request.GET.get('distance', 3000))
- logger.debug('now location. lat = %s; lng = %s' % (lat, lng))
- if maxDistance > Const.NEAR_BY_MAX_DISTANCE:
- maxDistance = Const.NEAR_BY_MAX_DISTANCE
- if lng == 360 or lat == 360 or isnan(lng) or isnan(lat):
- return JsonResponse({'result': 0, 'description': u'定位失败,请打开位置权限,刷新后重试'})
- pageIndex = int(request.GET.get('pageIndex', 0))
- pageSize = int(request.GET.get('pageSize', 10))
- payload = getNearbyDevicesFromDB(lng, lat, pageIndex, pageSize, maxDistance,
- getattr(request.user, 'productAgentId', ''),
- request.GET.get('type', None), groupId)
- return JsonResponse({'result': 1, 'description': '', 'payload': payload})
- except Exception as e:
- logger.exception(e)
- return JsonResponse({'result': 0, 'description': u'获取附近设备失败'})
- @permission_required(ROLE.manager)
- def getEndUserDetailList(request):
- # type: (WSGIRequest)->JsonResponse
- """
- :param request:
- :return:
- """
- mid = str(request.user.id)
- pageIndex = int(request.GET.get('pageIndex', 1))
- pageSize = int(request.GET.get('pageSize', 10))
- searchKey = request.GET.get('searchKey', None)
- agentIds = [str(agent['_id']) for agent in Agent.get_collection().find({'managerId': mid}, {'_id': True})]
- dealerIds = [str(dealer['_id']) for dealer in
- Dealer.get_collection().find({'agentId': {'$in': agentIds}}, {'_id': True})]
- groupIds = [str(group['_id']) for group in
- Group.get_collection().find({'ownerId': {'$in': dealerIds}}, {'_id': True})]
- skip = (pageIndex - 1) * pageSize
- dataList = []
- users = MyUser.search(searchKey).filter(groupId__in = groupIds)
- for u in users.skip(skip).limit(pageSize):
- item = {
- 'id': str(u.id),
- 'nickname': u.nickname,
- 'openId': u.openId,
- 'sex': u.sex,
- 'country': u.country,
- 'province': u.province,
- 'city': u.city,
- 'balance': u.balance,
- 'groupName': '',
- 'gateway': u.gateway
- }
- group = Group.get_group(u.groupId)
- if group:
- item.update({'groupName': group.get('groupName')})
- dataList.append(item)
- total = users.count()
- return JsonResponse({
- 'result': 1,
- 'description': '',
- 'payload': {
- 'total': total,
- 'dataList': dataList
- }
- })
- @error_tolerate(nil = JsonErrorResponse(description = u'获取消费记录失败'), logger = logger)
- @permission_required(ROLE.manager)
- def getEndUserConsumeRecords(request):
- # type: (WSGIRequest)->JsonResponse
- """
- :param request:
- :return:
- """
- pageIndex = int(request.GET.get('pageIndex', 1))
- pageSize = int(request.GET.get('pageSize', 10))
- userId = request.GET.get('id', None)
- if not userId:
- return JsonErrorResponse(description = u'用户id为空')
- else:
- startTime = request.GET.get('startTime', Const.QUERY_START_DATE)
- endTime = request.GET.get('endTime', datetime.datetime.now().strftime('%Y-%m-%d'))
- user = MyUser.objects(id = str(userId)).get()
- group = Group.get_group(user.groupId)
- cursor = ClientConsumeModelProxy.get_data_list(
- startTime = startTime,
- endTime = endTime,
- ownerId = group['ownerId'],
- openId = user.openId,
- groupId = user.groupId) # type: QuerySetProxy
- total = cursor.count()
- records = [
- {
- "orderNo": r.orderNo,
- "time": r.time,
- "coins": r.coin,
- "devNo": r.devNo,
- "devType": r.dev_type_name,
- "groupName": r.groupName
- }
- for r in cursor.paginate(pageIndex, pageSize)
- ]
- return JsonResponse({'result': 1, 'description': '', 'payload': {'total': total, 'dataList': records}})
- @error_tolerate(nil = JsonErrorResponse(description = u'获取充值记录失败'), logger = logger)
- @permission_required(ROLE.manager)
- def getEndUserRechargeRecords(request):
- # type: (WSGIRequest)->JsonResponse
- """
- :param request:
- :return:
- """
- pageIndex = int(request.GET.get('pageIndex', 1))
- pageSize = int(request.GET.get('pageSize', 10))
- userId = request.GET.get('id', None)
- if not userId:
- return JsonErrorResponse(description = u'用户id为空')
- else:
- startTime = request.GET.get('startTime', Const.QUERY_START_DATE)
- endTime = request.GET.get('endTime', datetime.datetime.now().strftime('%Y-%m-%d'))
- user = MyUser.objects(id = str(userId)).get()
- group = Group.get_group(user.groupId)
- cursor = ClientRechargeModelProxy.get_data_list(startTime = startTime,
- endTime = endTime,
- ownerId = group['ownerId'],
- openId = user.openId,
- groupId = user.groupId,
- hint = [('openId', 1)]) # type: QuerySetProxy
- total = cursor.count()
- records = [
- {
- "orderNo": r.orderNo,
- "time": r.to_js_timestamp(r.dateTimeAdded),
- "money": r.money,
- "coins": r.coins,
- "devNo": r.devNo,
- "devType": r.dev_type_name,
- "groupName": r.groupName,
- "gateway": r.gateway
- } for r in cursor.paginate(pageIndex, pageSize)]
- return JsonResponse({'result': 1, 'description': '', 'payload': {'total': total, 'dataList': records}})
- def wxconfig(request):
- url = request.GET.get('href')
- if not url:
- return JsonResponse({'result': 0, 'description': u'参数错误', 'payload': {}})
- current_user = request.user # type: MyUser
- wxconfig = get_wx_config(current_user, url)
- return JsonOkResponse(payload = {'wxconfig': wxconfig})
- # 用于前台界面时间计时用
- @error_tolerate(nil = JsonErrorResponse(description = u'系统错误'), logger = logger)
- @permission_required(ROLE.myuser)
- def countDown(request):
- # type: (WSGIRequest)->JsonResponse
- openId = str(request.user.openId)
- devNo = str(request.GET.get('devNo', ''))
- portStr = request.GET.get('chargeIndex', None)
- if portStr is not None:
- port = int(portStr)
- else:
- port = None
- dev = Device.get_dev(devNo)
- logicalCode = dev['logicalCode']
- group = Group.get_group(dev['groupId'])
- devType = dev.get('devType')
- dealer = Dealer.objects.get(id = dev['ownerId'])
- agent = Agent.objects.get(id = dealer.agentId)
- # 判断是否是摩丫丫的设备 判断是否是烘干机设备
- if (agent.features != [] and 'moyaya666' in agent.features) or (
- dealer.features != [] and 'dryer' in dealer.features):
- last_time_cache = serviceCache.get(user_last_time_use_ended_cache(openId, logicalCode), '')
- if last_time_cache == '':
- serviceCache.set(user_last_time_use_ended_cache(openId, logicalCode), datetime.datetime.now(), 3600)
- elif last_time_cache != '':
- if datetime.datetime.now() > last_time_cache + datetime.timedelta(hours = 1):
- serviceCache.set(user_last_time_use_ended_cache(openId, logicalCode), datetime.datetime.now(), 3600)
- ctrInfo = Device.get_dev_control_cache(devNo)
- if ctrInfo:
- lastOpenId = ctrInfo.get('openId', '')
- else:
- lastOpenId = ''
- box = ActionDeviceBuilder.create_action_device(dev)
- try:
- response = box.count_down(request, dev, agent, group, devType, lastOpenId, port)
- if response is None:
- return JsonErrorResponse(description = u'系统不支持此操作哦')
- return response
- except ServiceException as e:
- logger.error('get count_down error=%s' % e.result['description'].encode('utf-8'))
- return JsonErrorResponse(description = e.result['description'])
- except Exception, e:
- logger.error('device(%s) get count_down error=%s' % (devNo, e))
- return JsonErrorResponse(description = u'系统异常,请重新刷新页面')
- # 只要有回调过来,说明一定是登录成功了,就直接送金币,然后跳转到控制页面即可。暂时不考虑authCode的鉴定以防止伪造URL。
- @error_tolerate(nil = ErrorResponseRedirect(error = cn(u'系统开小差了哦,真是抱歉呀,请您刷新页面试试哦')))
- @permission_required(ROLE.myuser)
- def huaweiAccess(request):
- # type: (WSGIRequest)->HttpResponseRedirect
- openId = request.user.openId
- devNo = request.COOKIES.get('devNo', None)
- groupId = request.COOKIES.get('groupId', None)
- if openId is None or devNo is None or groupId is None:
- return ErrorResponseRedirect(error = cn(u'系统开小差了哦,真是抱歉呀,请您重新扫码试试哦'))
- dev = Device.get_dev(devNo)
- ads = AdRecord.objects.filter(openId = openId, adId = 0)
- if ads.count() > 0:
- return NetDeviceResponseRedirect(l = dev.logicalCode)
- newRcd = AdRecord(converted = True, adId = 0, openId = openId, groupId = groupId, devNo = devNo)
- newRcd.save()
- user = MyUser.objects.get(openId = openId, groupId = groupId)
- user.balance += 1
- user.save()
- return NetDeviceResponseRedirect(l = dev.logicalCode)
- @error_tolerate(nil = JsonErrorResponse(description = u'系统错误'), logger = logger)
- def getCardStatus(request):
- # type: (WSGIRequest)->JsonResponse
- lc = request.GET.get('logicalCode')
- devNo = Device.get_devNo_by_logicalCode(lc)
- cardInfo = Card.get_dev_cur_card(devNo)
- if cardInfo is None:
- return JsonResponse(
- {
- "result": 0,
- "description": u'刷卡区没有检测到卡,请您先把卡放到读卡区,这样才能开始充值哦',
- "para": None
- }
- )
- return JsonResponse(
- {
- "result": 1,
- "description": None,
- "para": {
- "ready": True,
- "cardId": cardInfo['cardNo'],
- "money": cardInfo["money"]
- }
- }
- )
- @permission_required(ROLE.myuser)
- def pollBtInfo(request):
- # type: (WSGIRequest)->JsonResponse
- payload = json.loads(request.body)
- device = Device.get_dev_by_logicalCode(payload.get('logicalCode'))
- if not device:
- return JsonResponse({'result': 0, 'description': u'设备不存在', 'payload': {}})
- code = Const.BT_DEVICE_TYPE_CODE_MAP[int(payload.get('code'))]
- actionBox = ActionBtDeviceBuilder.create(code, device)
- major = int(payload.get('major'))
- minor = int(payload.get('minor'))
- notify_payload = payload.get('payload', None)
- if not notify_payload:
- notify_payload = payload.get('advertisData', None)
- if notify_payload:
- result, description = actionBox.poll_notify(notify_payload, **{'major': major, 'minor': minor})
- return JsonResponse({'result': result, 'description': description, 'payload': {}})
- else:
- return JsonResponse({'result': 1, 'description': 'empty', 'payload': {}})
- @error_tolerate(nil=JsonErrorResponse(description=u'显示用户信息错误'), logger=logger)
- @permission_required(ROLE.myuser)
- @request_limit_by_user(operation='userInfo', limit=50, logger=logger)
- def userInfo(request):
- # type: (WSGIRequest)->JsonResponse
- logger.info('receive userInfo')
- user = request.user # type: MyUser
- agentId = user.agentId
- payload = {
- 'nickname': user.nickname,
- 'balance': user.total_balance,
- 'agentId': agentId,
- 'domain': settings.MY_DOMAIN,
- 'avatarUrl': request.user.avatar if request.user.avatar else settings.DEFAULT_AVATAR_URL,
- 'noVirtualCard': False,
- 'noRechargeCard': False,
- 'noRecharge': False,
- 'userId': ''
- }
- agent = Agent.objects(id = agentId).first() # type: Optional[Agent]
- if agent:
- payload['agentFeatures'] = agent.features
- if 'hideRechargeCardForUser' in agent.features:
- payload.update({'noRechargeCard': True})
- # if 'ledgerAfterFinished' in agent.features:
- # payload.update({
- # 'noVirtualCard': True,
- # 'noRechargeCard': True,
- # 'noRecharge': True
- # })
- # 校验是否要绑定用户的手机号码
- if 'telVerify' in agent.features:
- needTelVerify = check_user_tel(user)
- payload.update({
- "needTelVerify": needTelVerify
- })
- # 检查是否支持一卡多用
- if 'card_multi_use' in agent.features:
- payload.update({'card_multi_use': True})
- user_id = user.user_id
- if user_id:
- payload.update({'userId': user_id})
- return JsonResponse({'result': 1, 'description': '', 'payload': payload})
- @error_tolerate(nil = JsonErrorResponse(description = u'获取组失败'), logger = logger)
- @permission_required(ROLE.myuser)
- def getRecentlyGroup(request):
- # type: (WSGIRequest)->JsonResponse
- my_product_agent_id = request.user.productAgentId
- # 是否是查询卡卷
- hasCoupon = request.GET.get('hasCoupon', False)
- openId = request.user.openId
- rcds = ConsumeRecord.objects.filter(openId = openId, isNormal = True).order_by('-dateTimeAdded')
- devNoList = list(set([rcd.devNo for rcd in rcds[0:100]]))
- dataList = []
- groupIdList = []
- dealerIdList = []
- map_dealer_product = {}
- for devNo in devNoList:
- dev = Device.get_dev(devNo)
- if (dev is None) or (not dev.has_key('groupId')):
- continue
- group = Group.get_group(dev['groupId'])
- if not group:
- continue
- dealer_id = str(dev['ownerId'])
- if not dealer_id:
- logger.error('dealer is null. id = %s' % dealer_id)
- continue
- try:
- dealer = Dealer.objects(id = dealer_id).first()
- if not dealer:
- logger.error('dealer is null. id = %s' % dealer_id)
- continue
- except Exception as e:
- logger.error('dealerId = {}; exception = {}'.format(dealer_id, str(e)))
- if dealer_id not in map_dealer_product:
- try:
- product_agent = get_user_manager_agent(dealer) # type:Agent
- except Exception as e:
- logger.exception(e)
- product_agent = None
- if not product_agent:
- logger.error('get product agent failure. devNo = {}; dealer id = {}'.format(dev['devNo'], dealer_id))
- continue
- map_dealer_product[dealer_id] = str(product_agent.id)
- if map_dealer_product[dealer_id] != my_product_agent_id:
- logger.debug('{} is not equal agent({})'.format(repr(dev), my_product_agent_id))
- continue
- if dev['groupId'] not in groupIdList:
- if (not group.has_key('address')) or (not group.has_key('groupName')):
- continue
- dataList.append({'address': group['address'],
- 'groupName': group['groupName'],
- 'groupId': dev['groupId'],
- 'devType': dev.get('devType', {}).get('name', ''),
- 'logicalCode': dev['logicalCode'],
- 'ownerId': dev['ownerId']}
- )
- groupIdList.append(dev['groupId'])
- dealerIdList.append(dev['ownerId'])
- if not hasCoupon:
- return JsonResponse({"result": 1, "description": "", "payload": {"total": len(dataList), "dataList": dataList}})
- # 查询下地址下的已经发布的虚拟卡
- dealerIdList = list(set(dealerIdList))
- vCards = VirtualCard.objects.filter(ownerId__in = dealerIdList, status = 1)
- dataList1 = []
- for data in dataList:
- match = False
- for card in vCards:
- if data['ownerId'] == card.ownerId and ('*' in card.groupIds or data['groupId'] in card.groupIds):
- match = True
- break
- if match:
- dataList1.append(data)
- return JsonResponse({"result": 1, "description": "", "payload": {"total": len(dataList1), "dataList": dataList1}})
- @error_tolerate(nil = JsonErrorResponse(description = u'获取卡列表失败'), logger = logger)
- @permission_required(ROLE.myuser)
- def getCardList(request):
- # type: (WSGIRequest)->JsonResponse
- """
- :param request:
- :return:
- """
- pageIndex = int(request.GET.get('pageIndex', 1))
- pageSize = int(request.GET.get('pageSize', 10))
- searchKey = request.GET.get('searchKey', None)
- openId = request.user.openId
- agentId = request.user.agentId # zjl user.agentId -> user.productAgentId
- agent = Agent.objects.get(id = agentId)
- manager = Manager.objects(id = agent.managerId).get() # zjl delete
- agent_id_list = [str(item.id) for item in Agent.objects(managerId = str(manager.id))] # zjl delete
- hideMenu = True if 'hideCardMenu' in agent.features else False
- skip = (pageIndex - 1) * pageSize
- cards = Card.objects.filter(openId = openId, # zjl delete
- agentId__in = agent_id_list).search(searchKey) # zjl delete
- # cards = Card.objects.filter(openId=openId, # zjl new
- # agentId=agentId).search(searchKey) # zjl new
- dataList = []
- for card in cards.skip(skip).limit(pageSize):
- hide = ['orderRecord', 'rechargeRecord', 'backRecord', 'frozen'] if (card.cardType == 'IC' and hideMenu) else []
- if card.devNo:
- dev = Device.get_dev(card.devNo) or dict()
- devType = dev.get('devType', {})
- if devType.has_key('id'):
- try:
- devType = DeviceType.objects.get(id = devType['id'])
- if not devType.supportIcCardcharge:
- hide.append('cardCharge')
- except Exception, e:
- pass
- # 分以下三种情况处理
- # 1 有groupId, 但是没有dealerId, 这个查数据目前没有。 这个情况下dealerId设置为group对应的, 如果没有dealer, 全部清空
- # 2 有dealerId, 没有groupId, 这种情况下, 直接取dealer的第一个groupId, 没有全部取空
- # 3 两个都没有的情况下, 直接取设备对应的group和dealerId
- if not card.groupId:
- if card.dealerId:
- group = Group.get_default_group(card.dealerId) # type: GroupDict
- if group:
- card.groupId = group.groupId
- else:
- card.groupId = ''
- card.dealerId = ''
- card.save()
- else:
- # 不处理. 这个用户自己去绑定
- pass
- else:
- if not card.dealerId:
- group = Group.get_group(card.groupId) # type: GroupDict
- if not group:
- card.groupId = ''
- card.dealerId = ''
- else:
- card.dealerId = group.ownerId
- card.save()
- group = Group.get_group(card.groupId) # type: GroupDict
- dataList.append(
- {
- 'cardId': str(card.id),
- 'cardNo': card.cardNo,
- 'cardType': card.cardType,
- 'cardName': card.cardName,
- 'phone': card.phone,
- 'groupId': card.groupId,
- 'groupName': group.groupName if group else '',
- 'dealerId': card.dealerId,
- 'balance': card.balance,
- 'isHaveBalance': card.isHaveBalance,
- 'remarks': card.remarks,
- 'status': card.status,
- 'frozen': False if card.frozen is None else card.frozen,
- 'hide': hide,
- 'boundVirtualCardId': card.boundVirtualCardId
- }
- )
- total = cards.count()
- return JsonResponse(
- {
- 'result': 1,
- 'description': '',
- 'payload':
- {
- 'total': total, "dataList": dataList
- }
- }
- )
- @error_tolerate(nil = JsonOkResponse(description = u"获取卡信息失败"), logger = logger)
- @permission_required(ROLE.myuser)
- def getCard(request):
- """
- 获取单一的卡信息
- :param request:
- :return:
- """
- cardId = request.GET.get("cardId", "")
- try:
- card = Card.objects.get(id = cardId)
- except DoesNotExist:
- return JsonErrorResponse(description = u"获取卡信息失败,请刷新页面试试")
- agentId = request.user.agentId
- agent = Agent.objects.get(id = agentId)
- hideMenu = True if 'hideCardMenu' in agent.features else False
- hide = ['orderRecord', 'rechargeRecord', 'backRecord', 'frozen'] if (card.cardType == 'IC' and hideMenu) else []
- if card.devNo:
- dev = Device.get_dev(card.devNo) or dict()
- devType = dev.get('devType', {})
- if devType.has_key('id'):
- try:
- devType = DeviceType.objects.get(id = devType['id'])
- if not devType.supportIcCardcharge:
- hide.append('cardCharge')
- except Exception as e:
- logger.exception(e)
- group = Group.get_group(card.groupId)
- data = {
- 'cardId': str(card.id),
- 'cardNo': card.cardNo,
- 'cardType': card.cardType,
- 'cardName': card.cardName,
- 'phone': card.phone,
- 'groupId': card.groupId,
- 'groupName': group.groupName if group else '',
- 'dealerId': card.dealerId,
- 'balance': card.balance,
- 'isHaveBalance': card.isHaveBalance,
- 'remarks': card.remarks,
- 'status': card.status,
- 'frozen': False if card.frozen is None else card.frozen,
- 'hide': hide,
- }
- return JsonOkResponse(payload = data)
- @error_tolerate(nil = JsonErrorResponse(description = u"查询卡信息失败"), logger = logger)
- @permission_required(ROLE.myuser)
- def queryCard(request):
- """
- 根据前台提供的cardNo 以及 groupId 返回该卡的所有信息
- :param request:
- :return:
- """
- # 获取参数 参数校验
- cardNo = request.GET.get("cardNo")
- groupId = request.GET.get("groupId")
- if not all([cardNo, groupId]):
- return JsonErrorResponse(description = u"参数不全,请输入卡号获取扫描设备获取绑定地址")
- group = Group.get_group(groupId) # type: GroupDict
- if not group:
- return JsonErrorResponse(description = u"开卡地址不存在,请重新扫描设备获取绑定地址或联系发卡经销商(1001)")
- dealer = Dealer.objects(id = str(group.ownerId)).first() # type: Dealer
- if not dealer:
- return JsonErrorResponse(description = u"开卡地址不存在,请重新扫描设备获取绑定地址或联系发卡经销商(1002)")
- agent = Agent.objects(id = str(dealer.agentId)).first()
- if not agent:
- return JsonErrorResponse(description = u"代理商不存在,请刷新页面后重试(1001)")
- productAgent = get_user_manager_agent(agent)
- if str(productAgent.id) != request.user.productAgentId:
- return JsonErrorResponse(description = u"不是该平台下的地址,请换个设备编号扫码试试(1001)")
- # 鉴别卡相应信息
- try:
- card = Card.objects.get(cardNo=cardNo, agentId=str(agent.id))
- except DoesNotExist:
- # 没有找到卡的情况下 如果代理商规定了经销商必须要先录入卡
- dealerBindCard = True if "dealerBindCard" in agent.features else False
- if dealerBindCard:
- return JsonErrorResponse(description=u"无效的卡号,该卡号未被录入,请联系发卡方")
- return JsonResponse(
- {
- "result": 1,
- "description": u"",
- "payload": {
- "cardNo": cardNo,
- "groupId": group.groupId,
- "groupName": group.groupName,
- }
- }
- )
- # 卡已经被被别人绑定了
- if card.openId and card.openId != request.user.openId and card.openId != Const.DEFAULT_CARD_OPENID:
- return JsonResponse(
- {
- "result": ErrorCode.CARD_BIND_BY_OTHER,
- "description": u"{} 卡片已经被其他用户使用,请检查卡号是否正确或联系相应的经销商".format(cardNo),
- "payload": {}
- }
- )
- if group.groupId != card.groupId:
- card_bind_group = Group.get_group(card.groupId)
- else:
- card_bind_group = group
- if not card_bind_group:
- card_bind_dealer = None
- else:
- card_bind_dealer = Dealer.objects(id = str(card_bind_group.ownerId)).first()
- # 卡綁定的組和經銷商只要有一個無效, 就走增加的流程
- if not card_bind_group or not card_bind_dealer:
- return JsonResponse(
- {
- "result": 1,
- "description": u"",
- "payload": {
- "cardNo": cardNo,
- "groupId": group.groupId,
- "groupName": group.groupName,
- }
- }
- )
- # 该卡已经被自己绑定
- if card.openId and card.openId != Const.DEFAULT_CARD_OPENID:
- return JsonResponse(
- {
- "result": ErrorCode.CARD_BIND_BY_SELF,
- "description": u"{} 卡片已经存在于您的卡包中,是否进入编辑界面编辑该卡的相应信息".format(cardNo),
- "payload": {
- "cardId": str(card.id),
- "cardNo": cardNo,
- "cardName": card.cardName,
- "groupId": card_bind_group.groupId,
- "groupName": card_bind_group.groupName,
- "phone": card.phone
- }
- }
- )
- # 该卡没有被绑定, 但是经销商信息已经绑定, 直接走绑定流程
- if not card.openId or card.openId == Const.DEFAULT_CARD_OPENID:
- return JsonResponse(
- {
- "result": ErrorCode.CARD_FORBID_CHARGE_GROUP,
- "description": u"该卡已经被经销商录入,是否进入卡绑定界面绑定卡{}".format(cardNo),
- "payload": {
- "cardId": str(card.id),
- "cardNo": cardNo,
- "cardName": card.cardName,
- "groupId": card_bind_group.groupId,
- "groupName": card_bind_group.groupName,
- "phone": card.phone
- }
- }
- )
- @error_tolerate(nil = JsonErrorResponse(description = u"添加卡失败"), logger = logger)
- @permission_required(ROLE.myuser)
- def addCard(request):
- """
- 添加卡 之前已经做过校验了
- :param request:
- :return:
- """
- payload = json.loads(request.body)
- cardNo = payload.get("cardNo")
- cardName = payload.get("cardName")
- phone = payload.get("phone")
- logicalCode = payload.get("logicalCode")
- cardId = payload.get("cardId")
- cardType = payload.get('cardType', '')
- # 参数校验
- if cardNo.isdigit():
- cardNo = str(int(cardNo))
- if not Card.check_card_no(cardNo):
- return JsonErrorResponse(description = u"激活失败,无效的卡号,卡号长度不能超过32位")
- if cardName and not check_entity_name(cardName):
- return JsonErrorResponse(description = u"请输入正确的持卡人昵称(2-20位)")
- if phone and not check_phone_number(phone):
- return JsonErrorResponse(description = u"手机号码输入错误")
- # 绑定设备和经销商的关系校验
- device = Device.get_dev_by_l(logicalCode)
- if not device:
- return JsonErrorResponse(description = u"错误的设备二维码,请重新扫描设备二维码")
- group = Group.get_group(device.get("groupId"))
- if not group:
- return JsonErrorResponse(description = u"未找到设备组,请刷新页面重试")
- dealer = Dealer.objects.filter(id = group.get("ownerId")).first()
- if not dealer:
- return JsonErrorResponse(description = u"未找到经销商,请刷新页面重试")
- agent = Agent.objects.filter(id = str(dealer.agentId)).first()
- if not agent:
- return JsonErrorResponse(description = u"未找到代理商,请刷新页面重试")
- productAgent = get_user_manager_agent(agent)
- if str(productAgent.id) != request.user.productAgentId:
- return JsonErrorResponse(description = u"不是该平台下的用户,不能绑定该平台的实体卡")
- if not cardId:
- # 是否允许办理多张实体卡
- onlyOneCard = True if "onlyOneCard" in agent.features and not request.user.many_cards else False
- if onlyOneCard and request.user.cards_num > 0:
- return JsonErrorResponse(description = u"您只能绑定一张实体卡,请联系经销商了解相应的规则")
- # 卡存在校验
- try:
- card = Card.objects.get(Q(agentId=str(agent.id)) | Q(agentId=str(agent.id)), cardNo=cardNo)
- except DoesNotExist:
- # 没有找到卡的情况下 如果代理商规定了经销商必须要先录入卡
- dealerBindCard = True if "dealerBindCard" in agent.features else False
- if dealerBindCard:
- return JsonErrorResponse(description=u"无效的卡号,该卡号未被录入,请联系发卡方")
- card = Card(
- cardNo = cardNo,
- openId = request.user.openId,
- cardName = cardName,
- groupId = device.get("groupId"),
- phone = phone,
- nickName = request.user.nickname,
- agentId = str(agent.id),
- dealerId = str(dealer.id),
- productAgentId = request.user.productAgentId,
- managerialAppId = request.user.managerialAppId,
- managerialOpenId = request.user.managerialOpenId,
- cardType = cardType
- )
- card.save()
- return JsonOkResponse(u"添加成功", payload = {"cardId": str(card.id)})
- # 优先判断dealerId是否允许,在判断绑定关系
- if card.dealerId and card.dealerId != device.get("ownerId"):
- return JsonErrorResponse(description = u"该卡已被其他经销商录入,请确认卡号无误后联系您的发卡经销商")
- if card.openId and card.openId != request.user.openId and card.openId != Const.DEFAULT_CARD_OPENID:
- return JsonErrorResponse(description = u"该卡已被其他用户绑定,请确认卡号无误后联系您的发卡经销商")
- card.openId = request.user.openId
- card.cardName = cardName
- card.phone = phone
- card.nickName = request.user.nickname
- card.groupId = device.get("groupId")
- card.dealerId = str(dealer.id)
- card.agentId = str(agent.id)
- card.productAgentId = request.user.productAgentId
- card.managerialAppId = request.user.managerialAppId
- card.managerialOpenId = request.user.managerialOpenId
- card.save()
- return JsonOkResponse(u"添加成功", payload = {"cardId": str(card.id)})
- # 1003 ErrorCode 过来的
- else:
- try:
- card = Card.objects.get(id = cardId)
- except DoesNotExist:
- return JsonErrorResponse(description = u"未找到实体卡,请刷新页面后重试")
- card.openId = request.user.openId
- card.groupId = group.groupId
- card.dealerId = group.ownerId
- card.agentId = str(agent.id)
- if cardName != card.cardName:
- card.cardName = cardName
- if phone != card.phone:
- card.phone = phone
- card.nickName = request.user.nickname
- card.productAgentId = request.user.productAgentId
- card.managerialAppId = request.user.managerialAppId
- card.managerialOpenId = request.user.managerialOpenId
- card.save()
- return JsonOkResponse(u"添加成功", payload = {"cardId": str(card.id)})
- @error_tolerate(nil = JsonErrorResponse(description = u"编辑卡失败"), logger = logger)
- @permission_required(ROLE.myuser)
- def editCard(request):
- """
- 卡编辑
- :param request:
- :return:
- """
- payload = json.loads(request.body)
- cardName = payload.get("cardName")
- if cardName and not check_entity_name(cardName):
- return JsonErrorResponse(description = u"请输入正确的持卡人昵称(2-20位)")
- phone = payload.get("phone")
- if phone and not check_phone_number(phone):
- return JsonErrorResponse(description = u"手机号码输入错误")
- card = Card.objects(id = str(payload.get("cardId"))).first()
- if not card:
- return JsonErrorResponse(description = u"未找到可编辑的卡片,请刷新页面重试")
- card.cardName = cardName
- card.phone = phone
- card.save()
- return JsonOkResponse(description = u"修改成功")
- @error_tolerate(nil = JsonErrorResponse(description = u"补卡失败"), logger = logger)
- @permission_required(ROLE.myuser)
- def swapCardNo(request):
- """
- 用户补卡 其实就是换个卡号
- :param request:
- :return:
- """
- payload = json.loads(request.body)
- cardNo = payload.get("cardNo", "")
- cardId = payload.get("cardId")
- # 卡号前置去0
- if cardNo.isdigit():
- cardNo = str(int(cardNo))
- openId = str(request.user.openId)
- if not Card.check_card_no(cardNo):
- return JsonErrorResponse(description = u"无效的卡号,卡号长度不能超过32位")
- try:
- oldCard = Card.objects.get(id = cardId)
- except DoesNotExist:
- return JsonErrorResponse(description = u"查询旧卡失败")
- # 没有找到卡的情况下 如果代理商规定了经销商必须要先录入卡
- agent = Agent.objects.get(id=oldCard.productAgentId)
- dealerBindCard = True if "dealerBindCard" in agent.features else False
- if dealerBindCard:
- return JsonErrorResponse(description=u"无效的卡号,该卡号未被录入,请联系发卡方")
- if oldCard.cardNo == cardNo:
- return JsonErrorResponse(description = u"卡号一致无需修改")
- if oldCard.openId != openId:
- return JsonErrorResponse(description = u"不是您的卡号,无权修改")
- checkStatus, checkMsg = Card.check_swap_card_no(cardNo, oldCard.dealerId, oldCard.agentId)
- if not checkStatus:
- return JsonErrorResponse(description = checkMsg)
- # 直接将卡号更新掉,然后新建一条换卡记录
- oldCard.update(cardNo = cardNo)
- SwapCardRecord.add_record(oldCard.cardNo, cardNo, oldCard.agentId, str(request.user.id))
- return JsonOkResponse(description = u"卡号修改成功")
- @error_tolerate(nil = JsonErrorResponse(description = u"绑定失败"), logger = logger)
- def bindCard(request):
- """
- 用户通过经销商分享的链接进来绑定实体卡
- :param request:
- :return:
- """
- openId = request.user.openId
- payload = json.loads(request.body)
- cardName = payload.get("cardName")
- if not check_entity_name(cardName):
- return JsonErrorResponse(description = u"请输入正确的持卡人昵称(2-20位)")
- phone = payload.get("phone")
- if not check_phone_number(phone):
- return JsonErrorResponse(description = u"手机号码输入错误")
- cardId = payload.get('cardId')
- card = Card.objects(id = cardId).first() # type: Card
- if not card:
- return JsonErrorResponse(u"该实体卡不存在,请联系经销商获取正确的绑定二维码")
- group = Group.get_group(card.groupId) # type: GroupDict
- if not group:
- return JsonErrorResponse(u'开卡地址无效,请联系经销商获取正确的绑定二维码(1001)')
- dealer = Dealer.objects(id = str(group.ownerId)).first() # type: Dealer
- if not dealer:
- return JsonErrorResponse(u'开卡地址无效,请联系经销商获取正确的绑定二维码(1002)')
- if str(dealer.id) != card.dealerId:
- return JsonErrorResponse(u'开卡地址无效,请联系经销商获取正确的绑定二维码(1003)')
- agent = Agent.objects(id = str(dealer.agentId)).first()
- if not agent:
- return JsonErrorResponse(description = u'代理商不存在,请刷新页面后重试(1002)')
- productAgent = get_user_manager_agent(agent)
- if str(productAgent.id) != request.user.productAgentId:
- return JsonErrorResponse(description = u"不是该平台下的用户,不能绑定该平台的实体卡")
- # 和卡相关的特性的获取
- onlyOneCard = True if "onlyOneCard" in agent.features and not request.user.many_cards else False
- if onlyOneCard and request.user.cards_num > 0:
- return JsonErrorResponse(description = u"您只能绑定一张实体卡,请联系经销商了解相应的规则")
- card.openId = openId
- card.cardName = cardName
- card.phone = phone
- card.nickName = request.user.nickname
- card.productAgentId = request.user.productAgentId
- card.managerialAppId = request.user.managerialAppId
- card.managerialOpenId = request.user.managerialOpenId
- card.save()
- return JsonOkResponse(description = u"添加成功", payload = {"cardId": str(card.id)})
- @error_tolerate(nil = JsonErrorResponse(description = u'解绑卡失败'), logger = logger)
- @record_operation_behavior()
- @permission_required(ROLE.myuser)
- def unbindCard(request):
- # type: (WSGIRequest)->JsonResponse
- openId = request.user.openId
- payload = json.loads(request.body)
- cardId = payload.get('id', None)
- card = Card.objects(id = cardId, openId = openId).first()
- if not card:
- return JsonErrorResponse(description = u'找不到该卡')
- updated = card.clear_card()
- if not updated:
- return JsonErrorResponse(description = u'变更状态失败')
- return JsonResponse({"result": 1, "description": "", "payload": {}})
- @error_tolerate(nil = JsonErrorResponse(description = u'获取正在使用失败'), logger = logger)
- @permission_required(ROLE.myuser)
- def getCurrentUse(request):
- # type: (WSGIRequest)->JsonResponse
- openId = request.user.openId
- filters = {
- "open_id": openId,
- "isFinished": False,
- "port": {"$ne": -1}
- }
- # 后付费流程中,扫码的时候会将 跳转到用户的正在服务 这个地方不要受其他设备类型的干扰
- orderId = request.GET.get("orderId")
- if orderId:
- consumeOrder = ClientConsumeModelProxy.get_one(id=orderId)
- device = Device.get_dev(consumeOrder.devNo)
- if not device.owner: # 经销商此时解绑了
- return JsonResponse({"result": 1, "description": "", "payload": {"total": 0, "dataList": []}})
- # 下面的可以恢复正常流程
- if device.devTypeCode in support_policy_device:
- filters = {
- "open_id": openId,
- "device_imei": device.devNo,
- "consumeOrder.consumeRecordId": orderId,
- }
- pageIndex = int(request.GET.get('pageIndex', 1))
- pageSize = int(request.GET.get('pageSize', 10))
- dataList = []
- for item in ServiceProgress.get_collection().find(filters):
- if int(time.time()) > item['finished_time']:
- continue
- else:
- try:
- devNo = item['device_imei']
- device = Device.get_dev(devNo) # type: DeviceDict
- smartBox = ActionDeviceBuilder.create_action_device(device)
- group = Group.get_group(device['groupId'])
- nowTime = int(time.time())
- data = {
- 'startTime': time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(item['start_time'])),
- 'order': item['consumeOrder'],
- 'address': group.get('address', ''),
- 'groupName': group.get('groupName', ''),
- 'devType': device['devType'].get('name'),
- 'devTypeCode': device['devType'].get('code'),
- 'logicalCode': device['logicalCode'],
- 'status': Const.DEV_WORK_STATUS_WORKING,
- 'devNo': devNo,
- 'majorDeviceType': device.majorDeviceType
- }
- if 'show_PG_to_user' in device.owner.features and device.support_power_graph and item.get("port"):
- data.update({'showPG': True, 'port': item.get("port")})
- if device['devType']['code'] in support_policy_weifule:
- orderInfoList = smartBox.get_current_use(base_data=data, spDict=item)
- dataList.extend(orderInfoList)
- continue
- needTime = item.get('consumeOrder', {}).get('needTime', None)
- unit = item.get('consumeOrder', {}).get('unit', None)
- if needTime and unit in [u'分钟', u'小时', u'天',
- u'秒']: # 数据库里面记录的都是归为分钟(建议后续全部统一为秒).这里计算的时间是以设备为准,不是以端口为准的,实际如果有端口,应该以端口为准
- if needTime == 999: # 特殊表示充满自停
- data.update({'needTime': u'充满自停'})
- else:
- data.update({'needTime': u'%s分钟' % needTime,
- 'leftTime': round(int(item['finished_time'] - nowTime) / 60.0, 1)})
- if item.get('port', -2) in [0, -1]:
- dataList.append(data)
- continue
- else:
- data.update({"port": item["port"]})
- ctrInfo = Device.get_dev_control_cache(devNo)
- _coin = data.get("order", dict()).get("coin")
- if _coin:
- data["order"].update({"coin": "{}{}".format(_coin, smartBox.show_pay_unit)})
- try:
- curInfo = device.deviceAdapter.get_port_using_detail(item['port'], ctrInfo)
- if curInfo.has_key('startTime'): # 微付乐自己的单板会上报startTime上来,和这里的startTime有冲突,所以,需要以订单的startTime为准
- curInfo.pop('startTime')
- if device.devTypeCode == Const.DEVICE_TYPE_CODE_CHARGING_HAINIAO:
- curInfo['port'] = str(int(curInfo['port']) + 1)
- if 'orderNo' in curInfo:
- if data['order']['orderNo'] == curInfo['orderNo']: # 说明此单正处于运行中,数据可以直接用
- data.update(curInfo)
- else:
- data.update({
- 'orderNo': data['order']['orderNo'],
- 'desc': u'此订单已经下发到设备上,上一单运行完毕就会自动运行此订单',
- })
- data.pop('leftTime', None)
- data.pop('leftElec', None)
- else:
- data.update(curInfo)
- # 正在服务显示按钮
- data.update(DeviceType.get_services_button(device['devType']['id']))
- try:
- data.update({'actualNeedTime': data['usedTime'] + data['leftTime']})
- except Exception as e:
- pass
- dealer = Dealer.get_dealer(device.ownerId)
- if dealer:
- agent = Agent.objects(id = dealer['agentId']).first() # type: Agent
- if agent:
- agentFeatures = agent.features
- if 'show_elec_data_for_user' not in agentFeatures:
- data.pop('elec', None)
- data.pop('needElec', None)
- data.pop('power', None)
- data.pop("leftElec", None)
- data.pop("usedElec",None)
- if not device.is_auto_refund and "hide_refund_data_for_user" in agentFeatures:
- data.pop("consumeMoney", None)
- data.pop("leftMoney", None)
- data.pop("usedTime", None)
- data.pop("leftTime", None)
- if 'hide_consume_coin_data' in device.devTypeFeatures:
- data.pop('consumeMoney', None)
- data.pop('leftMoney', None)
- if device.devTypeCode in [Const.DEVICE_TYPE_CODE_CHARGING_HONGZHUO]:
- data.pop('actualNeedTime',None)
- data['power'] = data['powerNow']
- if device.devTypeCode in [Const.DEVICE_TYPE_CODE_CHANGING_BL_TEN,
- Const.DEVICE_TYPE_CODE_CHANGING_BL_TWELVE]:
- data.pop('actualNeedTime',None)
- # 这里需要反过来做一次校验,因为网络不稳定,可能造成丢包,没有刷新状态。
- # 如果出来的状态是空闲的,那就说明服务已经结束
- # zjl 充电柜的临时跳过 下个版本会对这个function进行彻底的拆分
- if device.devTypeCode not in [
- Const.DEVICE_TYPE_CODE_CABINET_NEW,
- Const.DEVICE_TYPE_CODE_CABINET,
- Const.DEVICE_TYPE_CODE_CHANGING_DIANCHUANCARCHARGING,
- Const.DEVICE_TYPE_CODE_CHANGING_BL_TEN,
- Const.DEVICE_TYPE_CODE_CHANGING_BL_TWELVE,] + support_policy_device:
- isFinished = False
- if curInfo.has_key('power') and curInfo.has_key('leftTime'):
- if curInfo['power'] == 0 and curInfo['leftTime'] in [0, u'(线路空载)']:
- isFinished = True
- else:
- if (curInfo.has_key('power') and curInfo['power'] == 0) or (
- curInfo.has_key('leftTime') and curInfo['leftTime'] in [0, u'(线路空载)']):
- isFinished = True
- if isFinished:
- try:
- ServiceProgress.get_collection().update_many(
- {
- 'open_id': openId,
- 'isFinished': False,
- 'device_imei': devNo,
- 'port': item['port']
- }, {
- '$set':
- {
- 'isFinished': True,
- 'expireAt': datetime.datetime.now()
- }
- })
- data['leftTime'] = 0
- except Exception as e:
- logger.error('update service progress e=%s' % e)
- except Exception as e:
- logger.exception('get cur info=%s' % e)
- dataList.append(data)
- except Exception as e:
- logger.exception(e)
- # 返回数据之前 将数据再次过滤一遍
- count = len(dataList)
- dataList = dataList[(pageIndex - 1) * pageSize: pageIndex * pageSize]
- newDataList = list()
- for _consumeDict in dataList:
- if "devNo" in _consumeDict:
- dev = Device.get_dev(_consumeDict["devNo"])
- newDataList.append(UserConsumeFilter(dev.owner, _consumeDict).filter())
- else:
- newDataList.append(_consumeDict)
- return JsonResponse({
- "result": 1,
- "description": "",
- "payload": {
- "total": count,
- "dataList": newDataList
- }
- })
- @error_tolerate(nil=JsonErrorResponse(description = u'获取计数失败'), logger = logger)
- @permission_required(ROLE.myuser)
- def getUserCenterCount(request):
- # type: (WSGIRequest)->JsonResponse
- openId = request.user.openId
- # 统计正在使用
- currentUse = ConsumeRecord.objects.filter(
- openId=openId,
- status__in=[
- ConsumeRecord.Status.RUNNING, ConsumeRecord.Status.END
- ]
- ).count()
- # 统计反馈消息
- dealerIds = MyUser.get_dealer_ids(openId, request.user.productAgentId)
- newMessage = FeedBack.objects.filter(openId=openId, ownerId__in=dealerIds, isRead=False)
- return JsonResponse(
- {
- "result": 1,
- "description": "",
- "payload": {
- "currentUse": currentUse, "newMessage": newMessage.count()
- }
- })
- @error_tolerate(nil = JsonErrorResponse(description = u'获取卡记录失败'), logger = logger)
- @permission_required(ROLE.myuser)
- def getUserCardRecord(request):
- # type: (WSGIRequest)->JsonResponse
- pageIndex = int(request.GET.get('pageIndex', 1))
- pageSize = int(request.GET.get('pageSize', 10))
- startTime = request.GET.get('startTime', 10)
- endTime = request.GET.get('endTime', 10)
- cardId = request.GET.get('cardId', None)
- type = request.GET.get('type', None)
- card = Card.objects.get(id = cardId)
- if type == "chargeCard":
- dataList = []
- for item in CardRechargeRecord.get_collection().find(
- {
- 'cardId': cardId,
- 'dateTimeAdded':
- {
- '$gte': to_datetime(startTime + " 00:00:00"),
- '$lte': to_datetime(endTime + " 23:59:59")
- },
- "remarks": {
- "$ne": u"退币"
- }
- }
- ).sort("dateTimeAdded", -1):
- data = {
- "cardId": str(item['_id']),
- "cardNo": card.cardNo,
- "via": "chargeCard",
- "amount": item['money'],
- "coins": item.get('coins', item['money']),
- "address": item['address'],
- "groupName": item['groupName'],
- "balance": item['balance'],
- "createdTime": item['dateTimeAdded'].strftime('%Y-%m-%d %H:%M:%S')
- }
- if item.has_key('preBalance'):
- data.update({'preBalance': item['preBalance']})
- dataList.append(data)
- elif type == "consume":
- dataList = []
- rcds = CardConsumeRecord.get_collection().find({'cardId': cardId,
- 'dateTimeAdded': {
- '$gte': to_datetime(startTime + " 00:00:00"),
- '$lte': to_datetime(endTime + " 23:59:59")}}).sort(
- "dateTimeAdded", -1)
- for item in rcds:
- newData = {
- "cardId": str(cardId),
- "cardNo": card.cardNo,
- "via": "consume",
- "devType": item['devType'],
- "amount": item['money'],
- "logicalCode": item['logicalCode'],
- "address": item['address'],
- "groupName": item['groupName'],
- "createdTime": item['dateTimeAdded'].strftime('%Y-%m-%d %H:%M:%S')
- }
- newData.update(item.get('servicedInfo', {}))
- dataList.append(newData)
- elif type == 'order':
- dataList = [
- {
- "via": "order",
- "amount": item['money'],
- "coins": item.get('coins', item['money']),
- "createdTime": item['dateTimeAdded'].strftime('%Y-%m-%d %H:%M:%S'),
- "status": u'等待刷卡充值' if item['status'] == 'finishedPay' else u'充值完成',
- "desc": item['remarks']
- }
- for item in CardRechargeOrder.get_collection().find({
- 'cardId': cardId,
- 'dateTimeAdded': {'$gte': to_datetime(startTime + " 00:00:00"),
- '$lte': to_datetime(endTime + " 23:59:59")}})
- .sort("dateTimeAdded", -1)]
- elif type == "refund":
- dataList = []
- for item in CardRechargeRecord.get_collection().find(
- {
- 'cardId': cardId,
- 'dateTimeAdded':
- {
- '$gte': to_datetime(startTime + " 00:00:00"),
- '$lte': to_datetime(endTime + " 23:59:59")
- },
- "remarks": u"退币"
- }
- ).sort("dateTimeAdded", -1):
- data = {
- "cardId": str(item['_id']),
- "cardNo": card.cardNo,
- "via": "refund",
- "amount": item['money'],
- "coins": item.get('coins', item['money']),
- "address": item['address'],
- "groupName": item['groupName'],
- "balance": item['balance'],
- "createdTime": item['dateTimeAdded'].strftime('%Y-%m-%d %H:%M:%S')
- }
- if item.has_key('preBalance'):
- data.update({'preBalance': item['preBalance']})
- dataList.append(data)
- elif type == "frozen":
- dataList = []
- for item in getattr(card, 'ongoingList', []):
- order = ConsumeRecord.objects.filter(id = item['transaction_id']).first()
- data = {
- "amount": order.coin.mongo_amount,
- "createdTime": order.startTime.strftime(Const.DATETIME_FMT),
- "via": "consume",
- "devType": order.dev_type_name,
- "chargeIndex": order.used_port,
- "logicalCode": order.logicalCode,
- "address": order.address,
- "groupName": order.groupName,
- "balance": card.balance.mongo_amount,
- "spendMoney": order.coin.mongo_amount,
- }
- dataList.append(data)
- else:
- return JsonResponse({"result": 0, "description": u"查询类型错误", "payload": {}})
- return JsonResponse({"result": 1, "description": "", "payload": {"total": len(dataList), "dataList": dataList[(pageIndex - 1) * pageSize: pageIndex * pageSize]}})
- @permission_required(ROLE.myuser)
- def freezeCard(request):
- # type: (WSGIRequest)->JsonResponse
- payload = json.loads(request.body)
- isFrozen = payload.get('frozen')
- cardId = payload.get('id', '')
- try:
- card = Card.objects.get(id = cardId)
- card.frozen = isFrozen
- card.status = 'deactive'
- card.save()
- except Exception as e:
- logger.exception(e.message)
- return JsonResponse({"result": 0, "description": u'系统错误', "payload": {}})
- # 如果是淋浴器,如果卡正在使用,直接把设备停掉,发指令过去
- return JsonResponse({"result": 1, "description": '', "payload": {}})
- @permission_required(ROLE.myuser)
- def bindVirtualCardToRechargeIDCard(request):
- # type: (WSGIRequest)->JsonResponse
- # TODO zjl 这个地方最好加上虚拟卡的绑定记录
- payload = json.loads(request.body)
- virtualCardId = payload.get('virtualCardId')
- rechargeIDCardId = payload.get('rechargeIDCardId')
- if virtualCardId is None:
- return JsonErrorResponse(description = u'未找到虚拟卡ID')
- if rechargeIDCardId is None:
- return JsonErrorResponse(description = u'未找到ID实体卡')
- card = Card.objects(id = rechargeIDCardId).first()
- if card is None:
- return JsonErrorResponse(description = u'未找到ID实体卡')
- if card.cardType != RECHARGE_CARD_TYPE.ID:
- return JsonErrorResponse(description = u'该卡不是ID卡')
- virtualCard = UserVirtualCard.objects(id = virtualCardId).first()
- if virtualCard is None:
- return JsonErrorResponse(description = u'未找到虚拟卡')
- updated = card.bind_virtual_card(virtualCard)
- if updated:
- return JsonOkResponse()
- else:
- return JsonErrorResponse(description = u'绑定失败')
- def unbindVirtualCardToRechargeIDCard(request):
- # type: (WSGIRequest)->JsonResponse
- payload = json.loads(request.body)
- virtualCardId = payload.get('virtualCardId')
- rechargeIDCardId = payload.get('rechargeIDCardId')
- if virtualCardId is None:
- return JsonErrorResponse(description = u'未找到虚拟卡ID')
- if rechargeIDCardId is None:
- return JsonErrorResponse(description = u'未找到ID实体卡')
- card = Card.objects(id = rechargeIDCardId).first()
- if card is None:
- return JsonErrorResponse(description = u'未找到ID实体卡')
- if card.cardType != RECHARGE_CARD_TYPE.ID:
- return JsonErrorResponse(description = u'该卡不是ID卡')
- virtualCard = UserVirtualCard.objects(id = virtualCardId).first()
- if virtualCard is None:
- return JsonErrorResponse(description = u'未找到虚拟卡')
- updated = card.unbind_virtual_card(virtualCard)
- if updated:
- return JsonOkResponse()
- else:
- return JsonErrorResponse(description = u'解绑失败')
- @permission_required(ROLE.myuser)
- def cardDiscountList(request):
- # type: (WSGIRequest)->JsonResponse
- """
- 获取用户实体卡套餐.
- 获取的方式有两种:
- 1、实体卡管理里面,直接选择卡,进入套餐界面。传入cardId参数;
- 2、在扫码的充卡界面,直接输入卡号,进入套餐界面,传入扫码的设备号;
- :param request:
- :return:
- """
- def user_center_recharge(card_id):
- card = Card.objects(id = str(card_id)).first() # type: Card
- if not card:
- logger.error('can not find the cardId = %s' % request.GET.get('cardId'))
- return JsonResponse({'result': 0, 'description': u'没有找到对应的卡,请您刷新页面重试', 'payload': {}})
- if not card.dealerId or not card.groupId:
- return JsonResponse({
- 'result': ErrorCode.CARD_NEED_BIND_GROUP,
- 'description': u'此卡没有绑定开卡地址',
- 'payload': {
- 'cardId': str(card.id),
- 'cardNo': card.cardNo,
- 'phone': card.phone,
- 'cardName': card.cardName
- }})
- group = Group.get_group(card.groupId) # type: GroupDict
- card_rule_list = group.card_rule_list
- card_rule_list = filter(lambda x: (float(x["coins"]) + float(card.balance)) < 5000, card_rule_list)
- return JsonResponse({
- 'result': 1, 'description': 'SUCCESS', 'payload': {'groupId': card.groupId, 'ruleList': card_rule_list}})
- def device_type_card_charge(devCache):
- """
- 从套餐页面的充卡按钮进入的卡充值页面。
- 不同设备类型进入不同的判断,后续有新的设备类型特有的需求增加新的判断分支。
- """
- if devCache.devTypeCode == Const.DEVICE_TYPE_CODE_WASHCAR_LANGUANG:
- box = ActionDeviceBuilder.create_action_device(devCache)
- devStatus = box.get_dev_status()
- if devStatus.get('xf_status') == '0x0001':
- allowCardCharge = True
- else:
- allowCardCharge = False
- return allowCardCharge
- return True
- if 'cardId' in request.GET:
- return user_center_recharge(request.GET.get('cardId'))
- else:
- if 'devNo' in request.GET and request.GET.get('devNo'):
- dev = Device.get_dev(request.GET.get('devNo')) # type: Optional[DeviceDict]
- elif 'logicalCode' in request.GET and request.GET.get('logicalCode'):
- dev = Device.get_dev_by_logicalCode(request.GET.get('logicalCode')) # type: Optional[DeviceDict]
- else:
- dev = None # type: Optional[DeviceDict]
- if not dev:
- return JsonErrorResponse(description = u'参数错误,请刷新重试(1001)')
- if device_type_card_charge(dev) is False:
- return JsonErrorResponse(description = u'暂不支持卡充值,请联系经销商检查设备或重试一下')
- group = Group.get_group(dev.groupId) # type: GroupDict
- return JsonResponse({'result': 1, 'description': 'SUCCESS',
- 'payload': {'groupId': dev.groupId, 'ruleList': group.card_rule_list}})
- @error_tolerate(nil = JsonErrorResponse(description = u'未知错误'))
- def getAgentQRCode(request):
- # type: (WSGIRequest)->JsonResponse
- agentId = request.GET.get('agentId', None)
- if agentId is None:
- return JsonErrorResponse(description = u'页面过期,请您重新扫码重试')
- try:
- agent = Agent.objects.get(id = agentId)
- if agent.gzhServiceQrcodeUrl == '':
- return JsonErrorResponse(description = u'没有提供公众号的二维码,需要先配置好公众号的二维码')
- else:
- return JsonOkResponse(
- payload = {'url': agent.gzhServiceQrcodeUrl, 'linkUrl': agent.gzhServiceLinkUrl, 'title': agent.title,
- 'desc': agent.desc})
- except DoesNotExist:
- logger.exception('could not find agent by agentId={0}'.format(agentId))
- return JsonErrorResponse(description = u'没有找到对应的代理商,请您检查数据是否正确')
- @permission_required(ROLE.myuser)
- def reportEndUserLocation(request):
- # type: (WSGIRequest)->JsonResponse
- """
- 上报终端用户的地理信息
- `sample request`
- {
- 'logicalCode': '111',
- 'lng': 12323.23
- 'lat': 1232123.22,
- 'type': 'gcj02'
- }
- :param request:
- :return:
- """
- currentUser = request.user # type: cast(MyUser)
- payload = json.loads(request.body)
- logger.debug('end user location is: %s' % payload)
- try:
- GPS_TYPE.lookupByValue(payload['type'])
- except ValueError:
- return JsonErrorResponse(u'无效的GPS类型')
- pointPair = (float(payload.get('lng', 360)), float(payload.get('lat', 360))) # type: Tuple[float, float]
- if any(map(lambda _: _ == 360 or isnan(_), pointPair)):
- return JsonResponse({'result': 0, 'description': u'定位失败,请打开位置权限,刷新后重试'})
- if pointPair in [_.coordinates for _ in currentUser.locations]:
- logger.debug('user{0!r} location point{1} duplicates'.format(currentUser, pointPair))
- return JsonResponse({'result': 1, 'description': ''})
- location = EndUserLocation(logicalCode = payload['logicalCode'],
- point = pointPair,
- type = payload['type'])
- updated = currentUser.update(add_to_set__locations = location)
- if not updated:
- logger.info(u'记录终端用户地址失败 user({0!r}) payload={1}'.format(currentUser, payload))
- return JsonResponse({'result': 1, 'description': ''})
- @permission_required(ROLE.myuser)
- def getOnsale(request):
- # type: (WSGIRequest)->JsonResponse
- """
- 用户侧 进入之前获取营销活动的流程
- :param request:
- :return:
- """
- lc = request.GET.get('logicalCode')
- showSite = int(request.GET.get('showSite'))
- dev = Device.get_dev_by_logicalCode(lc)
- nowTime = datetime.datetime.now()
- onsales = OnSale.objects.filter(status = 'start', showSite = showSite, dealerId = dev['ownerId'],
- logicalCodeList = lc, startTime__lte = nowTime, endTime__gte = nowTime)
- if onsales.count() <= 0:
- return JsonOkResponse()
- onsaleList = []
- # 查询是否已经参加了活动, 如果已经参加 并且活动描述仅仅只能参加一次 不在展示该活动
- for onsale in onsales:
- if OnSaleRecord.objects.filter(onsaleId = str(onsale['id']), userId__in = [str(request.user.id),
- request.user.openId]).count() and onsale.showType == "onlyOne":
- continue
- onsaleList.append(onsale)
- if not onsaleList:
- return JsonOkResponse()
- # TODO 这个活动为什么是随机的 ??? 这个 shuffle 也很有问题
- # random.shuffle(onsaleList)
- # onsale = onsaleList[0]
- onsale = random.choice(onsaleList)
- return JsonResponse({
- "result": 1, "description": '',
- "payload": {
- 'onsaleId': str(onsale.id),
- 'img': onsale.img,
- 'desc': onsale.desc,
- 'onClickUrl': onsale.onClickUrl,
- 'showType': onsale.showType
- }
- })
- @permission_required(ROLE.myuser)
- def getPromotionalCoins(request):
- # type: (WSGIRequest)->JsonResponse
- """
- 营销活动,用户获币
- :param request:
- :return:
- """
- lc = request.GET.get('logicalCode')
- onsaleId = request.GET.get('onsaleId')
- # 先检查这个用户是否有领取过,如果领取过,就不允许领取
- if not onsaleId:
- return JsonErrorResponse(description = u'找不到营销活动ID')
- if not lc:
- return JsonErrorResponse(description = u'找不到设备')
- user = request.user # type: MyUser
- userId = str(user.id)
- key = '{user}{onsale}-lock'.format(user = userId, onsale = onsaleId)
- with memcache_lock(key = key, value = '1', expire = 60) as acquired:
- if acquired:
- count = OnSaleRecord.objects.filter(onsaleId = onsaleId, userId = userId).count()
- if count > 0:
- return JsonErrorResponse(description = u'您已经领取过金币了哦,不能再领了哦')
- onsale = OnSale.objects(id = onsaleId).first() # type: Optional[OnSale]
- if not onsale:
- return JsonErrorResponse(description = u'推广活动不存在')
- if onsale.status == 'stop':
- return JsonErrorResponse(description = u'推广活动已经下架,无法领取了哦')
- coins = int(onsale.detailDict.get('coins', 0))
- updated = user.incr_balance(VirtualCoin(coins))
- if not updated:
- return JsonErrorResponse(description = u'获币失败')
- # 添加一条充值记录
- orderNo = str(uuid.uuid1())
- dev = Device.get_dev_by_logicalCode(lc)
- group = Group.get_group(dev['groupId'])
- try:
- newRcd = RechargeRecord(orderNo = orderNo,
- coins = coins, money = 0.00, openId = request.user.openId,
- groupId = dev['groupId'],
- devNo = dev['devNo'], logicalCode = lc,
- ownerId = dev['ownerId'], groupName = group['groupName'],
- groupNumber = dev['groupNumber'], address = group['address'],
- wxOrderNo = u'活动赠币',
- devTypeName = dev.devTypeName, nickname = '',
- result = 'success', via = 'onsaleSendCoins')
- newRcd.save()
- except Exception as e:
- logger.exception('update record for feedback coins error=%s,orderNo=%s' % (e, orderNo))
- # 增加一条活动
- try:
- newRcd = OnSaleRecord(
- onsaleId = onsaleId,
- userId = userId,
- nickName = request.user.nickname,
- addedTime = datetime.datetime.now(),
- onsaleDetail = {'coins': coins}
- )
- newRcd.save()
- except Exception as e:
- logger.exception('update record for onsale record error=%s,orderNo=%s' % e)
- return JsonOkResponse(description = u'赠送成功!您可以直接使用金币!')
- else:
- return JsonErrorResponse(description = u'您已正在领取')
- @permission_required(ROLE.myuser)
- def getPromotionalDuration(request):
- # type: (WSGIRequest)->JsonResponse
- """
- :param request:
- :return:
- """
- lc = request.GET.get('logicalCode')
- onsaleId = request.GET.get('onsaleId')
- # 先检查这个用户是否有领取过,如果领取过,就不允许领取
- if not onsaleId:
- return JsonErrorResponse(description = u'找不到营销活动ID')
- if not lc:
- return JsonErrorResponse(description = u'找不到设备')
- userId = str(request.user.id)
- key = '{user}{onsale}-lock'.format(user = userId, onsale = onsaleId)
- with memcache_lock(key = key, value = '1', expire = 60) as acquired:
- if acquired:
- # 先检查这个用户是否有领取过,如果领取过,就不允许领取
- count = OnSaleRecord.objects.filter(onsaleId = onsaleId, userId = userId).count()
- if count > 0:
- return JsonErrorResponse(description = u'您已经免费体验过了哦,不能再免费体验了哦,您可以试试充值消费哦')
- onsale = OnSale.objects(id = onsaleId).first() # type: Optional[OnSale]
- if not onsale:
- return JsonErrorResponse(description = u'该活动不存在')
- if onsale.status == 'stop':
- return JsonErrorResponse(description = u'推广活动已经下架,无法体验了哦')
- duration = int(onsale.detailDict.get('duration')) * 60
- dev = Device.get_dev_by_logicalCode(lc) # type: DeviceDict
- box = ActionDeviceBuilder.create_action_device(dev)
- try:
- box.send_dev_runtime(request.user.openId, duration)
- except ServiceException, e:
- return JsonErrorResponse(description = e.result.get('description'))
- except Exception, e:
- return JsonErrorResponse(description = u'系统异常,请您重试')
- # 增加一条活动
- try:
- OnSaleRecord(
- onsaleId = onsaleId,
- userId = str(request.user.id),
- nickName = request.user.nickname,
- addedTime = datetime.datetime.now(),
- onsaleDetail = {'duration': int(onsale.detailDict.get('duration'))}
- ).save()
- except Exception as e:
- logger.exception('update record for onsale record error=%s' % (e,))
- return JsonOkResponse(description = u'服务开始啦!您可以体验啦')
- else:
- return JsonErrorResponse(description = u'您已领取福利')
- @permission_required(ROLE.myuser)
- def getBannerList(request):
- # type: (WSGIRequest)->JsonResponse
- """
- :param request:
- :return:
- """
- lc = request.GET.get('logicalCode')
- dev = Device.get_dev_by_logicalCode(lc)
- dealer = Dealer.objects.get(id = dev['ownerId'])
- agent = Agent.objects.get(id = dealer.agentId)
- aBannerList = agent.bannerList
- if not aBannerList or dealer.isShowBanner is False:
- return JsonResponse({"result": 1, "description": '', "payload": {}})
- return JsonResponse({"result": 1, "description": '', "payload": aBannerList})
- @error_tolerate(nil = DefaultJsonErrorResponse, logger = logger)
- @permission_required(ROLE.myuser)
- def submitComment(request):
- # type: (WSGIRequest)->JsonResponse
- """
- :param request:
- :return:
- """
- payload = json.loads(request.body)
- lc = payload.get('logicalCode')
- desc = payload.get('description')
- dev = Device.get_dev_by_logicalCode(lc)
- group = Group.get_group(dev['groupId'])
- Comment(
- devNo = dev['devNo'],
- logicalCode = lc,
- groupId = dev['groupId'],
- groupNumber = dev['groupNumber'],
- groupName = group['groupName'],
- address = group['address'],
- ownerId = dev['ownerId'],
- openId = request.user.openId,
- nickname = request.user.nickname,
- ratingList = payload['rating'],
- description = desc
- ).save()
- return JsonResponse({"result": 1, "description": '', "payload": {}})
- @permission_required(ROLE.myuser)
- def onsaleRecharge(request):
- # type: (WSGIRequest)->JsonResponse
- """
- :param request:
- :return:
- """
- user = request.user # type: MyUser
- lc = request.GET.get('logicalCode')
- if not lc:
- return JsonResponse({"result": 0, "description": u'设备不存在,请刷新后重试(1001)', "payload": {}})
- device = Device.get_dev_by_logicalCode(lc) # type: DeviceDict
- if not device:
- return JsonResponse({"result": 0, "description": u'设备不存在,请刷新后重试(1002)', "payload": {}})
- onsaleId = request.GET.get('onsaleId')
- if not onsaleId:
- return JsonResponse({"result": 0, "description": u'活动ID错误,请刷新后重试', "payload": {}})
- if user.groupId != device.groupId:
- return JsonResponse({"result": 0, "description": u'请在扫码后点击活动页面去充值。点击其他方式的活动链接无效。', "payload": {}})
- jumpUrl = concat_user_recharge_url(l = lc)
- # 增加一条活动
- try:
- OnSaleRecord(
- onsaleId = onsaleId,
- userId = str(request.user.id),
- nickName = request.user.nickname,
- addedTime = datetime.datetime.now(),
- onsaleDetail = {}
- ).save()
- except Exception as e:
- logger.exception(e)
- return JsonResponse({"result": 0, "description": u'系统异常,请重试', "payload": {}})
- return JsonResponse({"result": 1, "description": '', "payload": {'url': jumpUrl}})
- @permission_required(ROLE.myuser)
- def onsaleTicketList(request):
- # type: (WSGIRequest)->JsonResponse
- """
- :param request:
- :return:
- """
- user = request.user # type: MyUser
- lc = request.GET.get('logicalCode')
- onsaleId = request.GET.get('onsaleId')
- agentId = user.productAgentId
- if agentId is None:
- return JsonResponse({"result": 0, "description": '获取代理商错误', "payload": {}})
- encodeUrl = concat_user_cardTicketList_entry_url(agentId = agentId, l = lc)
- # 增加一条活动
- try:
- OnSaleRecord(
- onsaleId = onsaleId,
- userId = str(request.user.id),
- nickName = request.user.nickname,
- addedTime = datetime.datetime.now(),
- onsaleDetail = {}
- ).save()
- except Exception as e:
- logger.exception(e)
- return JsonResponse({"result": 0, "description": u'系统异常,请重试', "payload": {}})
- return JsonResponse({"result": 1, "description": '', "payload": {'url': encodeUrl}})
- @permission_required(ROLE.myuser)
- def sendCodeForVerify(request):
- # type: (WSGIRequest)->JsonResponse
- """
- :param request:
- :return:
- """
- payload = json.loads(request.body)
- lc = payload.get('logicalCode')
- onsaleId = payload.get('onsaleId')
- userId = str(request.user.id)
- key = '{user}{onsale}-lock'.format(user = userId, onsale = onsaleId)
- with memcache_lock(key = key, value = '1', expire = 60) as acquired:
- if acquired:
- count = OnSaleRecord.objects.filter(onsaleId = onsaleId, userId = userId).count()
- if count > 0:
- return JsonErrorResponse(description = u'您已经免费体验过了哦,不能再免费体验了哦,您可以试试充值消费哦')
- dev = Device.get_dev_by_logicalCode(lc) # type: DeviceDict
- phoneNumber = payload.get('phoneNumber')
- dealer = Dealer.get_dealer(dev['ownerId'])
- agent = Agent.objects.get(id = dealer['agentId'])
- status, msg = userMobileVerifySMSProvider.get(phoneNumber = phoneNumber,
- productName = agent.productName,
- vendor = SysParas.get_sms_vendor(request.user.smsVendor))
- if not status:
- return JsonErrorResponse(description = msg)
- else:
- return JsonOkResponse()
- else:
- return JsonErrorResponse(description = u'您已正在领取')
- @permission_required(ROLE.myuser)
- def mobileVerify(request):
- # type: (WSGIRequest)->JsonResponse
- """
- :param request:
- :return:
- """
- payload = json.loads(request.body)
- lc = payload.get('logicalCode')
- onsaleId = payload.get('onsaleId')
- phoneNumber = payload.get('phoneNumber')
- code = payload.get('code')
- userId = str(request.user.id)
- key = '{user}{onsale}-lock'.format(user = userId, onsale = onsaleId)
- with memcache_lock(key = key, value = '1', expire = 60) as acquired:
- if acquired:
- status, msg = userMobileVerifySMSProvider.verify(phoneNumber, code)
- if not status:
- return JsonErrorResponse(description = msg)
- count = OnSaleRecord.objects.filter(onsaleId = onsaleId, userId = str(request.user.id)).count()
- if count > 0:
- return JsonResponse({"result": 0, "description": u'您已经免费体验过了哦,不能再免费体验了哦,您可以试试充值消费哦', "payload": {}})
- try:
- onsale = OnSale.objects.get(id = onsaleId)
- except Exception as e:
- logger.exception(e)
- return JsonResponse({"result": 0, "description": u'推广活动已经下架,无法体验了哦', "payload": {}})
- if onsale.status == 'stop':
- return JsonResponse({"result": 0, "description": u'推广活动已经下架,无法体验了哦', "payload": {}})
- duration = int(onsale.detailDict.get('duration')) * 60
- dev = Device.get_dev_by_logicalCode(lc)
- duration = int(onsale.detailDict.get('duration')) * 60
- dev = Device.get_dev_by_logicalCode(lc) # type: DeviceDict
- box = ActionDeviceBuilder.create_action_device(dev)
- try:
- box.send_dev_runtime(request.user.openId, duration)
- except ServiceException, e:
- return JsonErrorResponse(description = e.result.get('description'))
- except Exception, e:
- return JsonErrorResponse(description = u'系统异常,请您重试')
- # 增加一条活动
- try:
- OnSaleRecord(
- onsaleId = onsaleId,
- userId = str(request.user.id),
- nickName = request.user.nickname,
- addedTime = datetime.datetime.now(),
- onsaleDetail = {'duration': int(onsale.detailDict.get('duration')),
- 'phoneNumber': phoneNumber}
- ).save()
- except Exception as e:
- logger.exception('update record for onsale record error=%s' % (e,))
- return JsonOkResponse(description = u'服务开始啦!您可以体验啦')
- else:
- return JsonErrorResponse(description = u'您已领取福利')
- @error_tolerate(nil = DefaultJsonErrorResponse, logger = logger)
- def test(request):
- return JsonOkResponse()
- @error_tolerate(nil = DefaultJsonErrorResponse, logger = logger)
- def getCurrentOrder(request):
- # type: (WSGIRequest)->JsonResponse
- """
- 获取目前用户目前订单的情况,给予用户下面操作的指示
- :param request:
- :return:
- """
- devNo = request.GET.get('devNo')
- startKey = request.GET.get('startKey')
- if not startKey:
- return JsonErrorResponse(description = u'未找到启动key')
- def get_response(orderProcessing, succeeded, desc = '', record = None):
- record = {} if record is None else record
- return JsonOkResponse(
- payload = {
- 'orderProcessing': orderProcessing,
- 'succeeded': succeeded,
- 'desc': desc,
- 'record': record
- }
- )
- #: 前台还需要发送请求轮询获取数据
- not_yet = get_response(orderProcessing = True, succeeded = None)
- #: 有错误或状态未知,前台可以停止轮询
- stop_polling_unknown = get_response(orderProcessing = False, succeeded = False, desc = u'系统异常')
- #: 确切知道启动成功
- polling_finished_succeeded = lambda desc, record: get_response(orderProcessing = False,
- succeeded = True,
- desc = desc,
- record = record)
- #: 确切知道启动失败
- polling_finished_failed = lambda desc, record: get_response(orderProcessing = False,
- succeeded = False,
- desc = desc,
- record = record)
- record = None
- start_key_status = get_start_key_status(startKey) # type: dict
- if start_key_status:
- logger.debug('getCurrentOrder startKey = %s; status = %s; ts = %s' %
- (startKey, start_key_status,
- timestamp_to_dt(start_key_status['ts']).strftime(
- '%Y-%m-%d %H:%M:%S') if 'ts' in start_key_status else ''))
- state = start_key_status['state']
- if state == START_DEVICE_STATUS.FAILURE or state == START_DEVICE_STATUS.TIMEOUT:
- return polling_finished_failed(desc=start_key_status['reason'], record = None)
- if state == START_DEVICE_STATUS.FINISHED:
- if 'orderId' in start_key_status:
- record = ConsumeRecord.objects(id = str(start_key_status['orderId'])).first() # type: ConsumeRecord
- if not record:
- logger.error('start key cache is not valid. value = {}'.format(str(start_key_status)))
- return stop_polling_unknown
- else:
- logger.debug('start key status is {}'.format(state))
- # 如果查过2分钟还没有结果,直接检查订单
- exp = long(request.GET.get('exp', 0))
- if exp < 2 * 60 * 1000:
- return not_yet
- else:
- logger.debug('too long to get result. try to query record.')
- if not record:
- record = ConsumeRecord.objects(startKey = startKey).first() # type: Optional[ConsumeRecord]
- if not record:
- logger.error('cache and record are null, startKey = {}'.format(startKey))
- return not_yet
- if record.status in [ConsumeRecord.Status.WAITING, ConsumeRecord.Status.CREATED]:
- return not_yet
- dev = Device.get_dev(devNo) # type: DeviceDict
- if not dev:
- logger.error('cannot find device by devNo(%s))' % (devNo,))
- return stop_polling_unknown
- if record.isNormal:
- #: 表明应用服务器并未发现异常,但是还是有可能实际场景失败,比如吃币,所以需要给用户良好的指导和要求其上传证据。并返回币数以便上分
- return polling_finished_succeeded(
- desc = u'您已成功启动设备。如果有疑问,请点击右下角"设备无反应"按钮',
- record = {'coins': record.coin, 'detailLink': record.deail_link(dev), "isIns": record.insId}
- )
- else:
- #: 设备服务器与设备连接失败(超时 etc,.)需要记录失败场景,同时保证用户不扣币,前台则给予提示其重试
- return polling_finished_failed(
- desc = record.errorDesc,
- record = {'coins': record.coin, 'detailLink': record.deail_link(dev)}
- )
- @permission_required(ROLE.myuser)
- def getOrderStatus(request):
- # type: (WSGIRequest)->JsonResponse
- """
- 蓝牙获取订单状态
- :param request:
- :return:
- """
- payload = json.loads(request.body)
- try:
- order_id = str(payload.get('orderId'))
- if OrderCacheMgr(order_id, cls_name = RechargeRecord.__name__).has_done():
- record = RechargeRecord.objects(id = str(payload.get('orderId'))).first() # type: RechargeRecord
- if record.is_success:
- return JsonResponse({'result': 1, 'description': '', 'payload': {'status': 'success'}})
- else:
- return JsonResponse({'result': 1, 'description': '', 'payload': {'status': 'fail'}})
- else:
- return JsonResponse({'result': 1, 'description': '', 'payload': {'status': 'nop'}})
- except Exception as e:
- logger.exception(e)
- return JsonResponse({'result': 1, 'description': '', 'payload': {'status': 'nop'}})
- @permission_required(ROLE.myuser)
- def pressButton(request):
- # type: (WSGIRequest)->JsonResponse
- payload = json.loads(request.body)
- button_name = payload.get('button')
- value = payload.get('value')
- lc = payload.get('logicalCode')
- dev = Device.get_dev_by_logicalCode(lc)
- smartBox = ActionDeviceBuilder.create_action_device(dev)
- try:
- devInfo = smartBox.press_button(button_name, value)
- except ServiceException as e:
- return JsonErrorResponse(description = e.result.get('description'))
- except Exception as e:
- logger.exception('cannot get_port_status, error=%s' % (str(e),))
- return JsonErrorResponse(description = u'未知错误')
- return JsonResponse({"result": 1, "description": '', "payload": devInfo})
- @permission_required(ROLE.myuser)
- def changeVolume(request):
- # type: (WSGIRequest)->JsonResponse
- payload = json.loads(request.body)
- logical_volume = payload.get('logicalCode')
- volume = payload.get('value')
- dev = Device.get_dev_by_logicalCode(logical_volume)
- smart_box = ActionDeviceBuilder.create_action_device(dev)
- try:
- result = smart_box.changeVolume(volume)
- return JsonResponse({"result": 1, "description": '', "payload": result})
- except ServiceException as e:
- return JsonErrorResponse(description = e.result.get('description'))
- except AttributeError as e:
- return JsonErrorResponse(description = u'暂时不支持该功能')
- except Exception as e:
- logger.exception('cannot changeVolume, error=%s' % (str(e),))
- return JsonErrorResponse(description = u'未知错误')
- @record_operation_behavior()
- @permission_required(ROLE.myuser)
- def stopCountDown(request):
- # type: (WSGIRequest)->JsonResponse
- openId = str(request.user.openId)
- payload = json.loads(request.body)
- port = payload.get('chargeIndex', None)
- devNo = Device.get_devNo_by_logicalCode(logicalCode = payload['logicalCode'])
- devCtrInfo = Device.get_dev_control_cache(devNo = devNo)
- orderNo = payload.get("orderNo")
- # 如果设备本身停止后,有停止时间上报,系统会在停止事件中处理退费、通知事宜。这里要做的就是直接停止而已.
- dev = Device.get_dev(devNo = devNo) # type: DeviceDict
- groupId = str(dev.get("groupId"))
- group = Group.get_group(groupId)
- box = ActionDeviceBuilder.create_action_device(dev)
- if box.isHaveStopEvent:
- try:
- if dev.devType["code"] in [Const.DEVICE_TYPE_CODE_CHARGE_WEIFULE_CAR,
- Const.DEVICE_TYPE_CODE_CAR_WEIFULE_CHARGING_DOUB,
- Const.DEVICE_TYPE_CODE_CAR_WEIFULE_21KW,
- Const.DEVICE_TYPE_CODE_CAR_WEIFILE_HOME_JFPG,
- Const.DEVICE_TYPE_CODE_CAR_WEIFILE_HOME_DOUB_JFPG,
- Const.DEVICE_TYPE_CODE_CHANGING_SOCKET,
- Const.DEVICE_TYPE_CODE_WEIFULE_TOUCH_PAD,
- Const.DEVICE_TYPE_CODE_WEIFULE_ANJIAN,
- ] or dev.support_reliable:
- box.stop_by_order(port, orderNo)
- else:
- box.stop(port)
- except ServiceException, e:
- return JsonResponse({'result': 0, 'description': e.result.get('description'), 'payload': {}})
- return JsonResponse({'result': 1, 'description': '', 'payload': {}})
- # 没有停止事件的,需要在这里处理退费事宜
- if port is None:
- for ii in range(10):
- try:
- portInfo = devCtrInfo.get(str(ii + 1), None)
- if portInfo is None:
- continue
- if portInfo.has_key('openId') and portInfo['openId'] == openId and portInfo['status'] in [
- Const.DEV_WORK_STATUS_WORKING, Const.DEV_WORK_STATUS_PAUSE]:
- port = str(ii + 1)
- break
- except Exception, e:
- continue
- with memcache_lock(key = start_device_lock_key(openId = openId), value = '1', expire = 360) as acquired:
- if acquired:
- if port is not None:
- devCtrInfo = devCtrInfo.get(str(port), {})
- totalFee = devCtrInfo.get('coins', None)
- if totalFee is None:
- logger.error('feedback coins error devNo=%s, totalFee=%s' % (devNo, totalFee))
- return JsonResponse({"result": 0, "description": u'获取订购金额失败', "payload": {}})
- totalTime = devCtrInfo.get('needTime', None)
- if totalTime is None:
- for _ in dev['washConfig'].values():
- if totalFee == _['price']:
- totalTime = int(_['time'])
- try:
- devInfo = box.stop(port)
- except ServiceException, e:
- return JsonResponse({'result': 0, 'description': e.result.get('description'), 'payload': {}})
- if 'remainder_time' not in devInfo: # 有些情况,是不需要根据时间退费的,比如云快充的充电桩,会根据事件,直接结算
- return JsonResponse({"result": 1, "description": '', "payload": ''})
- remainderTime = devInfo['remainder_time']
- # 更新内存缓存状态
- if port is None:
- Device.invalid_device_control_cache(devNo)
- else:
- ctrInfo = Device.get_dev_control_cache(devNo)
- ctrInfo.update({str(port): {}})
- Device.update_dev_control_cache(devNo, ctrInfo)
- refundFee = box.calc_stop_back_coins(totalFee, remainderTime, totalTime)
- backCoins = VirtualCoin(refundFee)
- desc = u'共付款:%s元,预定时间为:%s分钟,剩余时间:%s' % (
- totalFee, totalTime, remainderTime)
- # 通知完成
- user = MyUser.objects(openId = openId, groupId = groupId).first()
- task_caller('report_to_user_via_wechat', openId = user.managerialOpenId, dealerId = dev['ownerId'],
- templateName = 'service_complete',
- **{
- 'title': u'订购总时间为:%s分钟,剩余时间:%s分钟' % (
- totalTime,
- remainderTime),
- 'service': u'服务(设备编号:%s,地址:%s)' % (
- payload['logicalCode'], group['address']),
- 'finishTime': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
- 'remark': u'谢谢您的支持'
- })
- # 如果需要退款,计算退款数据.
- if not dev.is_auto_refund:
- ServiceProgress.update_progress_and_consume_rcd(
- dev['ownerId'],
- {'open_id': openId, 'device_imei': devNo, 'isFinished': False},
- {'leftTime': remainderTime,
- 'needTime': u'扫码订购%s分钟' % totalTime,
- 'duration': totalTime - remainderTime}
- )
- else:
- # 扫码退钱, 退到个人账号
- user.incr_balance(backCoins)
- # 添加一条充值记录
- orderNo = str(uuid.uuid4())
- try:
- newRcd = RechargeRecord(orderNo = orderNo,
- coins = backCoins, openId = openId, groupId = str(request.user.groupId),
- devNo = devNo, logicalCode = payload['logicalCode'],
- ownerId = dev['ownerId'],
- groupName = group['groupName'], groupNumber = dev['groupNumber'],
- address = group['address'], wxOrderNo = u'设备退币',
- devTypeName = dev.devTypeName, nickname = '',
- result = 'success', via = 'refund')
- newRcd.save()
- except Exception as e:
- logger.exception('update record for feedback coins error=%s,orderNo=%s' % (e, orderNo))
- ServiceProgress.update_progress_and_consume_rcd(
- dev['ownerId'],
- {'open_id': openId, 'device_imei': devNo, 'isFinished': False},
- {'leftTime': remainderTime,
- 'needTime': u'扫码订购%s分钟' % totalTime,
- 'duration': totalTime - remainderTime}
- )
- task_caller('report_to_user_via_wechat', openId = user.managerialOpenId, dealerId = dev['ownerId'],
- templateName = 'refund_coins',
- **{
- 'title': desc,
- 'backCount': u'金币:%s' % backCoins,
- 'finishTime': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
- })
- return JsonResponse({"result": 1, "description": '', "payload": ''})
- @error_tolerate(nil=JsonErrorResponse(u"获取虚拟卡列表失败"))
- @permission_required(ROLE.myuser)
- def getCardTicketList(request): # type: (WSGIRequest)->JsonResponse
- """
- 获取虚拟卡的列表
- """
- pageIndex = int(request.GET.get('pageIndex', 1))
- pageSize = int(request.GET.get('pageSize', 10))
- invalid = int(request.GET.get("invalid", 0))
- openId = request.user.openId
- now_time = datetime.datetime.now()
- filters = {"openIds": openId}
- if invalid:
- filters.update({"expiredTime__lt": now_time})
- else:
- filters.update({"expiredTime__gte": now_time})
- vCards = UserVirtualCard.objects.filter(**filters)
- total = vCards.count()
- dataList = list()
- for _vcard in vCards.skip((pageIndex - 1) * pageSize).limit(pageSize):
- data = _vcard.to_dict()
- # 检查是否需要续费
- isNeedRenew, days = is_need_renew(_vcard)
- if isNeedRenew:
- data.update({'needRenew': True})
- # 添加是否是卡主
- data.update({"isOwner": _vcard.isOwner(request.user.openId)})
- dataList.append(data)
- return JsonOkResponse(payload={
- 'total': total, 'pageSize': pageSize, 'dataList': dataList
- })
- @error_tolerate(nil=JsonErrorResponse(u"获取虚拟卡详情失败"))
- @permission_required(ROLE.myuser)
- def getCardTicket(request):
- cardId = request.GET.get("cardId")
- try:
- card = UserVirtualCard.objects.get(id=cardId)
- except DoesNotExist:
- return JsonErrorResponse(description=u"获取虚拟卡详情失败")
- payload = card.to_detail()
- isNeedRenew, days = is_need_renew(card)
- if isNeedRenew:
- payload.update({'needRenew': True})
- payload.update({
- "isOwner": card.isOwner(request.user.openId),
- "agentId": request.user.productAgentId
- })
- return JsonOkResponse(payload=payload)
- @error_tolerate(nil = DefaultJsonErrorResponse, logger = logger)
- @permission_required(ROLE.myuser)
- def getUserVirtualCardByGroup(request):
- """
- 通过groupId查询该地址下有没有购买过虚拟卡
- :param request:
- :return:
- """
- groupId = request.GET.get("groupId")
- if not groupId:
- return JsonErrorResponse(u"查询错误")
- # 如果没有通过地址数量的检查 则直接提示不能开卡
- if not Group.check_virtual_card_number(groupId):
- return JsonErrorResponse(description = u"该地址虚拟卡数量已经达到上限,请联系发卡经销商")
- vCards = UserVirtualCard.objects.filter(
- openIds__in = [request.user.openId],
- groupIds__in = ['*', groupId],
- expiredTime__gt = datetime.datetime.now()
- )
- vCardList = [str(vCard.cardNo) for vCard in vCards]
- return JsonOkResponse(payload = {"vCardList": vCardList})
- @permission_required(ROLE.myuser)
- def getCardTicketTypeList(request):
- # type: (WSGIRequest)->JsonResponse
- groupId = request.GET.get('groupId', None)
- if groupId is None:
- return JsonErrorResponse(u'没有找到您的充值地址哦')
- if not Group.check_virtual_card_number(groupId):
- return JsonErrorResponse(description=u"该地址虚拟卡数量已经达到上限,请联系发卡经销商")
- group = Group.get_group(groupId)
- onlineCards = VirtualCard.objects.filter(
- ownerId=group['ownerId'],
- status=1,
- groupIds__in=['*', groupId],
- expiredTime__gt=datetime.datetime.now()
- )
- dataList = []
- for obj in onlineCards:
- data = obj.to_dict()
- if '*' in obj.groupIds:
- groups = [{'groupName': grp['groupName'], 'address': grp['address']} for grp in
- Group.get_groups_by_group_ids(Group.get_group_ids_of_dealer(obj.ownerId)).values()]
- else:
- groups = [{'groupName': grp['groupName'], 'address': grp['address']} for grp in
- Group.get_groups_by_group_ids(obj.groupIds).values()]
- data["groups"] = groups
- dataList.append(data)
- return JsonOkResponse(payload={'dataList': dataList})
- # 分享卡卷的链接
- @permission_required(ROLE.myuser)
- def getShareCardTicket(request):
- # type: (WSGIRequest)->JsonResponse
- vCardId = request.GET.get('cardId', None)
- if vCardId is None:
- return JsonResponse({"result": 0, "description": u'没有找到卡卷,可能该卡卷已经被卡主注销,无法共享', "payload": None})
- try:
- vCard = UserVirtualCard.objects.get(id = vCardId)
- except DoesNotExist as e:
- return JsonResponse({"result": 0, "description": u'没有找到卡卷,可能该卡卷已经被卡主注销,无法共享', "payload": None})
- if len(vCard.openIds) > vCard.userLimit - 1:
- return JsonResponse({"result": 0, "description": u'共享的人数已经达到卡的限制,您无法共享哦', "payload": None})
- agentId = Dealer.get_dealer(vCard.dealerId).get('agentId', None)
- if agentId is None:
- return JsonResponse({"result": 0, "description": u'非法卡,您无法共享哦', "payload": None})
- if request.user.agentId != agentId:
- return JsonResponse({"result": 0, "description": u'非法卡,您无法共享哦', "payload": None})
- if request.user.openId in vCard.openIds:
- return JsonResponse({"result": 0, "description": u'您已经共享了此卡', "payload": None})
- vCard.openIds.append(request.user.openId)
- try:
- vCard.save()
- except Exception as e:
- logger.info('save sharing card error=%s' % e)
- return JsonResponse({"result": 0, "description": u'保存卡的信息异常,请您重试', "payload": None})
- data = vCard.to_detail()
- data.update({
- "isOwner": vCard.isOwner(request.user.openId),
- "agentId": request.user.productAgentId
- })
- return JsonResponse({"result": 1, "description": '', "payload": data})
- @permission_required(ROLE.myuser)
- def removeCardSharedMembers(request):
- # type: (WSGIRequest)->JsonResponse
- payload = json.loads(request.body)
- vCardId = payload.get('cardId')
- openId = payload.get('userId')
- if vCardId is None:
- return JsonResponse({"result": 0, "description": u'没有找到卡卷,可能该卡卷已经被注销,请您刷新页面后再重试', "payload": None})
- try:
- vCard = UserVirtualCard.objects.get(id = vCardId)
- except DoesNotExist:
- return JsonResponse({"result": 0, "description": u'没有找到卡卷,可能该卡卷已经被注销,请您刷新页面后再重试', "payload": None})
- vCard.openIds.remove(openId)
- try:
- vCard.save()
- except Exception as e:
- logger.info('save sharing card error=%s' % e)
- return JsonResponse({"result": 0, "description": u'保存卡的信息异常,请您重试', "payload": None})
- return JsonResponse({"result": 1, "description": '', "payload": None})
- @permission_required(ROLE.myuser)
- def stopService(request):
- # type: (WSGIRequest)->JsonResponse
- payload = json.loads(request.body)
- logicalCode = payload.get('logicalCode')
- port = payload.get('port', None)
- dev = Device.get_dev_by_l(logicalCode)
- box = ActionDeviceBuilder.create_action_device(dev)
- try:
- box.stop(port)
- except ServiceException, e:
- return JsonResponse({'result': 0, 'description': e.result.get('description'), 'payload': {}})
- return JsonResponse({'result': 1, 'description': '', 'payload': {}})
- @permission_required(ROLE.myuser)
- def toggleDeviceStatus(request):
- # type: (WSGIRequest)->JsonResponse
- payload = json.loads(request.body)
- logicalCode = payload.get('logicalCode')
- port = payload.get('chargeIndex', None)
- isContinue = False if payload.get('targetStatus', None) == 'pause' else True
- dev = Device.get_dev_by_l(logicalCode)
- box = ActionDeviceBuilder.create_action_device(dev)
- try:
- result = box.pause(request.user.openId, isContinue, port)
- return JsonResponse({'result': 1, 'description': '', 'payload': result})
- except ServiceException, e:
- return JsonResponse({'result': 0, 'description': e.result.get('description'), 'payload': {}})
- @permission_required(ROLE.myuser)
- def getDeviceSellItems(request):
- payload = json.loads(request.body)
- logicalCode = payload.get('logicalCode')
- objs = Cell.objects.filter(logicalCode = logicalCode, itemStatus = 'full')
- dataList = [{
- 'cellNo': obj.cellNo, 'boardNo': obj.boardNo,
- 'lockNo': obj.lockNo, 'itemTitle': obj.itemTitle,
- 'itemDesc': obj.itemDesc, 'itemPicUrl': obj.itemPicUrl,
- 'itemPrice': obj.itemPrice
- } for obj in objs]
- return JsonResponse({'result': 1, 'description': '', 'payload': {'dataList': dataList}})
- @permission_required(ROLE.myuser)
- def getDeviceCells(request):
- logicalCode = request.GET.get('logicalCode')
- objs = Cell.objects.filter(logicalCode = logicalCode)
- dev = Device.get_dev_by_logicalCode(logicalCode)
- box = ActionDeviceBuilder.create_action_device(dev)
- lockStatusDict = box.get_all_lock_status()
- dataList = [{'id': str(obj.id), 'cellNo': obj.cellNo, 'boardNo': obj.boardNo,
- 'lockNo': obj.lockNo, 'itemTitle': obj.itemTitle,
- 'itemDesc': obj.itemDesc, 'itemPicUrl': obj.itemPicUrl,
- 'itemPrice': round(obj.itemPrice / 100.0, 2), 'lockStatus': lockStatusDict.get(obj.cellNo, 'close')}
- for obj in objs if (lockStatusDict.get(obj.cellNo, 'close') == 'close' and obj.itemStatus != 'empty')]
- return JsonResponse({'result': 1, 'description': '', 'payload': {'dataList': dataList}})
- @permission_required(ROLE.myuser)
- def updateUserActiveInfo(request):
- """
- 安骑换电用户 的身份信息上传接口
- 需要信息 手机验证码 手机号码 身份验证信息 推荐人信息(非必须)
- 推荐人
- # 新添加了字段 phoneNumber
- """
- user = request.user # type: MyUser
- if user.is_product_user():
- return JsonErrorResponse(u"请先扫描设备")
- active_info = MyUser.get_active_info(user.openId, agentId = user.agentId)
- if active_info and active_info.get("isMember"):
- return JsonErrorResponse(u"您已经完成实名认证,请勿重复")
- payload = json.loads(request.body)
- code = payload.get("code", "")
- phoneNumber = payload.get("phoneNumber", "")
- imgList = payload.get("imgList", [])
- recommender = payload.get("recommender", "")
- if phoneNumber:
- if MyUser.objects.filter(
- Q(phoneNumber = phoneNumber),
- Q(agentId = request.user.agentId) | Q(productAgentId = request.user.productAgentId)
- ):
- return JsonErrorResponse(description = u"手机号码已经被注册!")
- # 推荐人如果填写必须有效 并且非本人 并且激活
- if recommender:
- if not MyUser.objects.filter(
- Q(phoneNumber = recommender),
- Q(agentId = request.user.agentId) | Q(productAgentId = request.user.productAgentId)
- ) or recommender == phoneNumber:
- return JsonErrorResponse(u"无效的推荐人")
- status, msg = userMobileVerifySMSProvider.verify(phoneNumber, code)
- if not status:
- return JsonErrorResponse(msg)
- MyUser.set_active_info(
- {"phoneNumber": phoneNumber,
- "imgList": imgList,
- "recommender": recommender,
- "status": 1,
- "createdTime": datetime.datetime.strftime(datetime.datetime.now(), "%Y-%m-%d %H:%M:%S")
- },
- openId = user.openId,
- agentId = user.agentId,
- groupId = user.groupId
- )
- return JsonOkResponse()
- @permission_required(ROLE.myuser)
- def getUserActiveInfo(request):
- user = request.user
- active_info = MyUser.get_active_info(user.openId, agentId = user.agentId)
- status = active_info.get("status", "")
- payload = {
- "id": user.id,
- "identifyUrl": active_info.get("identifyUrl", ""),
- "recommender": active_info.get("recommender", ""),
- "phoneNumber": active_info.get("phoneNumber", ""),
- "status": status if status else 0,
- "remarks": active_info.get("remarks", "")
- }
- return JsonResponse({"result": 1, "description": '', "payload": payload})
- @permission_required(ROLE.myuser)
- def getTelVerifyInfo(request):
- user = request.user
- status = 1 if user.phone else 0
- return JsonResponse({"result": 1, "description": "", "payload": {"status": status}})
- @permission_required(ROLE.myuser)
- def updateTelVerifyInfo(request):
- """
- 绑定手机号码. 手机号码只是做为属性, 谁能获取验证码, 手机号码就是谁的
- """
- user = request.user
- jsonData = json.loads(request.body)
- phoneNumber = jsonData.get("phoneNumber", "")
- code = jsonData.get("code", "")
- # 首先校验 短信验证码
- status, msg = userMobileVerifySMSProvider.verify(phoneNumber, code)
- if not status:
- return JsonErrorResponse(msg)
- try:
- user.phone = phoneNumber
- except Exception as e:
- logger.exception(e)
- return JsonErrorResponse(description=u"手机号码绑定失败,请刷新重试")
- return JsonOkResponse(description=u"绑定成功")
- @permission_required(ROLE.myuser)
- def sendActiveSmsCode(request):
- """
- 安骑换电用户 获取手机验证码 手机号码
- """
- user = request.user
- payload = json.loads(request.body)
- phoneNumber = payload.get("phoneNumber", "")
- # phoneNumber 唯一
- checkUser = MyUser.objects.filter(
- Q(phoneNumber = phoneNumber),
- Q(agentId = request.user.agentId) | Q(productAgentId = request.user.productAgentId)
- ).first()
- if checkUser and checkUser.gateway == user.gateway:
- return JsonErrorResponse(u"该号码已经被注册")
- agent = Agent.objects.get(id = user.agentId)
- status, msg = userMobileVerifySMSProvider.get(phoneNumber = phoneNumber,
- productName = agent.productName,
- vendor = SysParas.get_sms_vendor(request.user.smsVendor),
- openId = user.openId)
- if not status:
- return JsonErrorResponse(description = msg)
- else:
- return JsonOkResponse()
- @error_tolerate(logger = logger, nil = JsonErrorResponse(u'上传身份文件图片存储失败,请重新试试'))
- @permission_required(ROLE.myuser)
- def UploadIdentify(request):
- """
- 用户上传身份验证
- """
- files = request.FILES.getlist('file')
- if not len(files):
- return JsonResponse({'result': 0, 'description': u'未知的身份文件信息,请重新试试', 'payload': {}})
- uploader = AliOssFileUploader(inputFile = request.FILES.getlist('file')[0], uploadType = 'identify')
- logger.info('[uploadItemPic] %s is being used' % (repr(uploader),))
- try:
- outputUrl = uploader.upload()
- return JsonResponse({'result': 1, 'description': '', 'payload': outputUrl})
- except InvalidFileSize, e:
- logger.info(
- '%s(id=%s)\'s uploaded file reached limit' % (request.user.__class__.__name__, str(request.user.id),))
- return JsonResponse({'result': 0, 'description': e.message, 'payload': {}})
- except InvalidFileName, e:
- logger.info(
- '%s(id=%s)\'s uploaded file name is not legal' % (request.user.__class__.__name__, str(request.user.id),))
- return JsonResponse({'result': 0, 'description': e.message, 'payload': {}})
- @permission_required(ROLE.myuser)
- def UserActiveIntercepter(request):
- """
- 安骑用户 拦截器 身份认证未通过的用户
- """
- user = request.user
- active_info = MyUser.get_active_info(openId = user.openId, agentId = user.agentId)
- isMember = active_info.get("isMember", False)
- return JsonOkResponse(payload = {"isMember": int(isMember)})
- @permission_required(ROLE.myuser)
- def DeviceTrack(request):
- """
- 电池电压、位置信息 存在位置信息
- """
- # TODO 数据库分库整改
- # 获取用户的最后一次serverProcess 从中获取用户电池的IMEI
- # API查询电池信息
- # 返回信息
- user = request.user
- active_info = MyUser.get_active_info(openId = user.openId, agentId = user.agentId)
- status = active_info.get("status", 0)
- if status != 2: # 完成身份认证的用户状态是2
- return JsonErrorResponse(u"请先完成身份认证信息")
- # 找出换电柜的使用记录 并且拿到的电池的编号不为-1
- record = ConsumeRecord.objects.filter(
- openId = user.openId,
- servicedInfo__newBatteryImei__exists = True,
- servicedInfo__newBatteryImei__ne = "-1"
- ).order_by("-dateTimeAdded").first()
- if not record:
- return JsonErrorResponse(u"未获取到有效电池信息")
- battery = record.servicedInfo.get("newBatteryImei")
- try:
- result = batteryInfo(battery)
- except Exception as e:
- logger.info("get battery info error ,reason is : %s" % e)
- return JsonErrorResponse(u"网络故障,获取电池信息失败")
- batInfo = result.get(battery)
- if not batInfo:
- return JsonErrorResponse(u"电池编号错误")
- lng = batInfo.get("lng")
- lat = batInfo.get("lat")
- lng, lat = coordinateHandler(lng, lat)
- payload = {
- "total": 1,
- "items": [
- {
- "lng": lng,
- "lat": lat,
- "remarks": u"当前电池电压信息是%s" % batInfo.get("voltage"),
- }
- ]
- }
- return JsonOkResponse(payload = payload)
- @error_tolerate(logger=logger)
- @permission_required(ROLE.myuser)
- # @ServerSwitch.payment_switch('系统维护升级中,请稍后重试')
- def payGateway(request):
- # type: (WSGIRequest)->HttpResponse
- """
- 用户请求充值
- 两层机制保证订单不被重复处理。
- 1、用户订单创建后,在cache塞一个值为0的key;在收到回调或者查询到状态后,对这个key加1。如果返回新值为2则代表已经有处理过。
- 2、如果cache失效,那么返回值为None。这个时候需要判断RechargeRecord的update结果,如果有修改,则代表没处理;否则已经处理过
- :param request:
- :return:
- """
- from apps.web.common.transaction.pay import PayPullUpFactoryIntf
- class PayPullUpFactory(PayPullUpFactoryIntf):
- @classmethod
- def create_by_alipay(cls, payment_gateway, payParam, record):
- current_user = payParam.curUser
- open_id = current_user.get_bound_pay_openid(payment_gateway.bound_openid_key)
- pull_up_cls = PayManager().get_pull_up(payment_gateway.pay_app_type)
- return pull_up_cls(open_id, payment_gateway, record, **{
- 'showAd': payParam.showAd,
- 'notifyUrl': PAY_NOTIFY_URL.ALI_PAY_BACK
- })
- @classmethod
- def create_by_wechat(cls, payment_gateway, payParam, record):
- current_user = payParam.curUser
- open_id = current_user.get_bound_pay_openid(payment_gateway.bound_openid_key)
- pull_up_cls = PayManager().get_pull_up(payment_gateway.pay_app_type)
- return pull_up_cls(open_id, payment_gateway, record, **{
- 'showAd': payParam.showAd,
- 'notifyUrl': PAY_NOTIFY_URL.WECHAT_PAY_BACK
- })
- @classmethod
- def create(cls, payment_gateway, record, **payload):
- payParam = payload.get('payParam')
- if payment_gateway.pay_app_type == PayAppType.ALIPAY:
- return cls.create_by_alipay(payment_gateway, payParam, record)
- elif payment_gateway.pay_app_type == PayAppType.WECHAT:
- return cls.create_by_wechat(payment_gateway, payParam, record)
- else:
- raise UserServerException(u'不支持的支付方式')
- try:
- logger.info('----{user} unified order----'.format(user=repr(request.user)))
- payParam = PayParam(request) # type: PayParam
- payParam.call_check()
- payment_gateway = payParam.payGateway
- if not payment_gateway:
- raise UserServerException(u'第三方支付配置错误,请联系平台客服(1001)')
- record = BUILDER_MAP.get(payParam.recordBuilderKey)(payParam) # type: RechargeRecord
- from apps.web.common.transaction.pay import PayPullUp
- pull_up = PayPullUp.create(PayPullUpFactory, payment_gateway, record, **{'payParam': payParam})
- response = pull_up.do()
- if 'startKey' in payParam.attachParas:
- set_start_key_status(payParam.attachParas['startKey'], START_DEVICE_STATUS.PAYING)
- return response
- except InterceptException as e:
- logger.debug(e.redirect)
- return JsonResponse({
- 'result': ErrorCode.LOGIN_VERIFY,
- 'payload': {
- 'redirect': e.redirect
- }
- })
- except ServiceException as e:
- logger.error(str(e))
- return JsonResponse(e.result)
- except UserServerException as e:
- logger.error(e.message)
- return JsonErrorResponse(e.message)
- except AliException as e:
- logger.error(str(e))
- return JsonErrorResponse(description=e.message)
- except Exception as e:
- logger.exception(e)
- return JsonErrorResponse(description=u'系统错误,请重试')
- finally:
- logger.info('----{user} unified order over----'.format(user=repr(request.user)))
- @error_tolerate(logger = logger)
- @permission_required(ROLE.myuser)
- def setMyUserDetail(request):
- user = request.user # type: MyUser
- payload = json.loads(request.body)
- ownerId = payload.pop('ownerId')
- MyUserDetail.objects(openId = str(user.openId), dealerId = str(ownerId)).upsert_one(
- openId = str(user.openId), dealerId = str(ownerId),
- userName = payload.get('userName'), userPhone = payload.get('userPhone'),
- userUnit = payload.get('userUnit'), userFloor = payload.get('userFloor'),
- userRoom = payload.get('userRoom'))
- return JsonResponse({'result': 1, 'description': 'SUCCESS', 'payload': {}})
- @error_tolerate(logger = logger)
- def payNotify(request, pay_app_type):
- # type: (WSGIRequest, str)->JsonResponse
- if pay_app_type == PayAppType.ALIPAY:
- payload = request.POST.dict()
- if 'refund_fee' in payload and 'gmt_refund' in payload:
- notifier_cls = RefundManager().get_notifier(pay_app_type)
- return notifier_cls(request, lambda filter: RefundMoneyRecord.get_record(**filter)).do(refund_post_pay)
- recharge_cls_factory = lambda order_no: RechargeRecord
- notifier_cls = PayManager().get_notifier(pay_app_type = pay_app_type)
- return notifier_cls(request, recharge_cls_factory).do(post_pay)
- @permission_required(ROLE.myuser)
- def getFavoriteDevice(request):
- pageIndex = int(request.GET.get('pageIndex', 1))
- pageSize = int(request.GET.get('pageSize', 10))
- devNoList = request.user.collectedDeviceList
- devs = Device.get_dev_by_nos(devNoList, verbose = True)
- dataList = []
- for dev in devs.values():
- dev.update({'type': dev['devType'].get('name', '')})
- dataList.append(dev)
- return JsonOkResponse(
- payload = {'total': len(dataList), 'items': dataList[(pageIndex - 1) * pageSize:pageIndex * pageSize]})
- @permission_required(ROLE.myuser)
- def deleteFavoriteDevice(request):
- payload = json.loads(request.body)
- lcCodes = payload['logicalCodeList']
- removeList = set()
- for lcCode in lcCodes:
- devNo = Device.get_devNo_by_logicalCode(lcCode)
- removeList.add(devNo)
- devNolist = set(request.user.collectedDeviceList)
- request.user.collectedDeviceList = list(devNolist - removeList)
- return JsonOkResponse()
- @permission_required(ROLE.myuser)
- def addFavoriteDevice(request):
- payload = json.loads(request.body)
- isFavorite = payload['favorite']
- lcCode = payload['logicalCode']
- devNo = Device.get_devNo_by_logicalCode(lcCode)
- collectedDeviceList = request.user.collectedDeviceList
- if isFavorite:
- if devNo not in collectedDeviceList:
- collectedDeviceList.append(devNo)
- request.user.collectedDeviceList = collectedDeviceList
- else:
- return JsonOkResponse(description = u'该设备已经收藏啦')
- else:
- if devNo in collectedDeviceList:
- collectedDeviceList.remove(devNo)
- request.user.collectedDeviceList = collectedDeviceList
- else:
- return JsonOkResponse(description = u'该设备已经取消收藏啦')
- return JsonOkResponse()
- # 检查是否需要弹出加粉界面。1、需要获取监督号的openId。2、检查是否需要弹出加粉界面
- # 监督号的入口也需要调用此函数,目的是找到客户应该登录的agentId。
- @permission_required(ROLE.myuser)
- def moniUserAccess(request):
- logger.info('receive moniUserAccess')
- # 目前只支持微信加粉
- try:
- href = request.GET.get('redirect')
- moniAppId = request.GET.get('moniAppId', None)
- if moniAppId is None:
- agent = Agent.objects.get(id = request.user.agentId)
- moniApp = agent.get_online_moni_app()
- if not moniApp:
- return ErrorResponseRedirect(error = cn(u'请您刷新下页面,重新点击试试'))
- else:
- try:
- moniApp = MoniApp.get_collection().find({'appId': moniAppId})[0]
- except Exception, e:
- return ErrorResponseRedirect(error = cn(u'建议您从扫码页面关注公众号,这样才可以使用此公众号的服务哦'))
- # 返回跳转页面
- state = MoniUserAuthState(appId = moniApp['appId'], openId = request.user.openId, href = href)
- wechatApp = WechatAuthApp(appid = moniApp['appId'], secret = moniApp['secret'])
- bridge = WechatAuthBridge(wechatApp)
- return ExternalResponseRedirect(
- bridge.generate_auth_url_base_scope(redirect_uri = USER_AUTH_REDIRECT_URL.MONI_BASE,
- payload = state.encode()))
- except Exception, e:
- logger.exception(e)
- return ErrorResponseRedirect(error = cn(u'系统开小差了~~~,请您刷新下页面,重新点击试试'))
- @permission_required(ROLE.myuser)
- def checkPoint(request):
- logger.info('checkPoint,receive,user openId=%s' % request.user.openId)
- # 目前只支持微信加粉
- if (not detect_wechat_client(request)):
- logger.info('checkPoint,it is not wechat client')
- return JsonOkResponse(payload = {'addFans': False, 'qrCode': ''})
- try:
- point = request.GET.get('point')
- logicalCode = request.GET.get('logicalCode')
- dev = Device.get_dev_by_logicalCode(logicalCode)
- dealer = Dealer.objects(id = dev['ownerId']).get()
- logger.info('checkPoint,user openId=%s,logicalCode=%s' % (request.user.openId, logicalCode))
- # 检查经销商和代理商的开关
- if dealer.moniAppCheckPointDict.has_key(point) and (not dealer.moniAppCheckPointDict[point]):
- logger.info('checkPoint,moniappcheck point dealer is off,point')
- return JsonOkResponse(payload = {'addFans': False, 'qrCode': ''})
- agent = Agent.objects(id = dealer.agentId).get()
- if agent.moniAppCheckPointDict.has_key(point) and (not agent.moniAppCheckPointDict[point]):
- logger.info('checkPoint,moniappcheck point agent is off')
- return JsonOkResponse(payload = {'addFans': False, 'qrCode': ''})
- moniApp = agent.get_online_moni_app()
- if not moniApp:
- return JsonOkResponse(payload = {'addFans': False, 'qrCode': ''})
- rcds = MoniUser.objects.filter(openId = request.user.openId, moniAppId = moniApp['appId'])
- if rcds.count() == 0: # 一条记录都没有是,说明没有拿到对应数据
- logger.info('checkPoint,can not find moniuser')
- return JsonOkResponse(payload = {'addFans': False, 'qrCode': ''})
- else:
- moniUser = rcds.first()
- if moniUser.isSubscribe:
- return JsonOkResponse(payload = {'addFans': False, 'qrCode': ''})
- else: # 如果没关注,可能存在用户通过其他手段提前关注了,要多重检查下
- app = WechatAuthApp(appid = moniApp['appId'], secret = moniApp['secret'])
- proxy = WechatClientProxy(app)
- isSubGzh = proxy.is_subscribe_gzh(moniUser['moniOpenId'])
- if isSubGzh:
- moniUser.isSubscribe = True
- moniUser.subPoint = point
- moniUser.subLogicalCode = logicalCode
- moniUser.subDealerId = str(dealer.id)
- moniUser.subAgentId = str(agent.id)
- moniUser.save()
- return JsonOkResponse(payload = {'addFans': False, 'qrCode': ''})
- else:
- moniUser.subPoint = point
- moniUser.subLogicalCode = logicalCode
- moniUser.subDealerId = str(dealer.id)
- moniUser.subAgentId = str(agent.id)
- moniUser.save()
- return JsonOkResponse(
- payload = {'addFans': True, 'qrCode': moniApp['qrCode'], 'title': moniApp['title'],
- 'desc': moniApp['desc']})
- except Exception, e:
- return JsonOkResponse(payload = {'addFans': False, 'qrCode': ''})
- @permission_required(ROLE.myuser)
- def isNeedAccessMoniApp(request):
- logger.info('receive isNeedAccessMoniApp')
- if (not detect_wechat_client(request)):
- return JsonOkResponse(payload = {'isNeed': False})
- try:
- agent = Agent.objects(id = request.user.agentId).get()
- # 如果代理商支持强制关注公众号,而且用户一天内才创建进来,为了体验好一点,这次就不要弹窗了
- if agent.forceFollowGzh and (datetime.datetime.now() - request.user.dateTimeAdded).total_seconds() < 24 * 60 * 60:
- return JsonOkResponse(payload = {'isNeed': False})
- # 如果这个用户已经订阅了某个监督号,就直接返回
- moniApp = agent.get_online_moni_app()
- if not moniApp:
- return JsonOkResponse(payload = {'isNeed': False})
- moniUserCount = MoniUser.objects.filter(openId = request.user.openId, moniAppId = moniApp['appId']).count()
- if moniUserCount == 0:
- return JsonOkResponse(payload = {'isNeed': True})
- return JsonOkResponse(payload = {'isNeed': False})
- except Exception, e:
- return JsonOkResponse(payload = {'isNeed': False})
- @permission_required(ROLE.myuser)
- def getComplaintList(request):
- pageIndex = int(request.GET.get('pageIndex', 1))
- pageSize = int(request.GET.get('pageSize', 10))
- objs = Complaint.objects.filter(openId = request.user.openId)
- dataList = []
- total = objs.count()
- for obj in objs.paginate(pageIndex = pageIndex, pageSize = pageSize):
- dataList.append({
- 'id': str(obj.id),
- 'logicalCode': obj.logicalCode,
- 'createdTime': obj.dateTimeAdded.strftime(Const.DATETIME_FMT),
- 'handledTime': obj.handledTime.strftime(Const.DATETIME_FMT),
- 'handledStatus': obj.handledStatus,
- 'groupName': obj.groupName,
- 'reason': obj.reason
- })
- return JsonOkResponse(payload = {'total': total, 'dataList': dataList})
- def submitComplaint(request):
- payload = json.loads(request.body)
- # 首先产生一条投诉记录
- logicalCode = payload.get('logicalCode')
- orderNo = payload.get('orderNo')
- reason = payload.get('reason')
- order = ConsumeRecord.objects.get(orderNo = orderNo)
- if order.logicalCode != logicalCode:
- return JsonErrorResponse(description = u'设备的编码填写错误,请您检查下哦')
- if Complaint.objects.filter(orderNo = orderNo).count() > 0:
- return JsonErrorResponse(description = u'该订单已经投诉成功,不需要您重复投诉了哦')
- newObj = Complaint(
- openId = request.user.openId,
- logicalCode = logicalCode,
- groupName = order.groupName,
- orderNo = orderNo,
- reason = reason
- )
- newObj.save()
- # 然后通知经销商
- newMsg = DealerMessage(
- ownerId = order.ownerId,
- fromUser = u'系统平台',
- messageType = 'complaint',
- title = u'客户投诉',
- desc = u'平台收到客户的投诉,请您尽快处理,如果收到投诉过多,系统会提醒设备用户,甚至禁用此设备。地址:%s,设备:%s,投诉原因:%s' % (
- order.groupName, logicalCode, reason),
- relatedInfo = {'complaintId': str(newObj.id)}
- )
- newMsg.save()
- return JsonOkResponse()
- @permission_required(ROLE.myuser)
- @request_limit_by_user(operation='queryServicePhone', limit=10, period=2 * 60 * 60, logger=None)
- def queryServicePhone(request):
- """
- 根据订单查询客服电话
- :param request:
- :return:
- """
- logicalCode = request.GET.get('logicalCode')
- dealerIds = MyUser.get_dealer_ids(openId = request.user.openId, productAgentId = request.user.productAgentId)
- device = Device.get_dev_by_logicalCode(logicalCode) # type: DeviceDict
- if not device or device.ownerId not in dealerIds:
- return JsonOkResponse(payload={})
- if not device.owner:
- logger.error('dealer<id={}> not exists.'.format(device.ownerId))
- return JsonOkResponse(payload={})
- return JsonOkResponse(payload=({'phone': device.owner.service_phone}))
- @error_tolerate(nil = JsonErrorResponse(description = u'系统错误'), logger = logger)
- @permission_required(ROLE.myuser)
- def getAllFeature(request):
- agent = Agent.objects.get(id = request.user.agentId)
- if agent is None:
- return JsonErrorResponse(description = u'代理商不存在')
- else:
- return JsonOkResponse(payload = {_: True for _ in agent.features})
- @error_tolerate(nil = JsonErrorResponse(description = u'系统错误'), logger = logger)
- @permission_required(ROLE.myuser)
- def queryCardNo(request):
- logicalCode = request.GET.get('logicalCode')
- devNo = Device.get_devNo_by_logicalCode(logicalCode)
- if devNo is None:
- return JsonErrorResponse(description = u'未识别的设备编号')
- cardNo = Card.get_dev_card_no(devNo)
- if cardNo is None:
- return JsonOkResponse(payload = {'cardNo': ''})
- return JsonOkResponse(payload = {'cardNo': cardNo})
- @error_tolerate(nil = JsonErrorResponse(description = u'系统错误'), logger = logger)
- @permission_required(ROLE.myuser)
- def prepareScanCard(request):
- logicalCode = request.GET.get('logicalCode')
- devNo = Device.get_devNo_by_logicalCode(logicalCode)
- if devNo is None:
- return JsonErrorResponse(description = u'未识别的设备编号')
- Card.clear_dev_card_no(devNo)
- return JsonOkResponse()
- @error_tolerate(nil = JsonErrorResponse("系统错误"), logger = logger)
- @permission_required(ROLE.myuser)
- def checkUserConsumeOrder(request):
- logicalCode = request.GET.get("logicalCode")
- dev = Device.get_dev_by_logicalCode(logicalCode)
- if not dev:
- return JsonErrorResponse(u"未找到设备,请扫码重试")
- box = ActionDeviceBuilder.create_action_device(dev)
- if not hasattr(box, "check_user_consume_order"):
- return JsonOkResponse()
- status = box.check_user_consume_order()
- return JsonResponse({"result": status})
- @error_tolerate(nil = JsonErrorResponse("系统错误"), logger = logger)
- @permission_required(ROLE.myuser)
- def preJudgment(request):
- """
- 这个接口 无论如何不能抛出异常 前台规定
- :param request:
- :return:
- """
- logicalCode = request.GET.get("logicalCode")
- dev = Device.get_dev_by_logicalCode(logicalCode)
- if not dev:
- return JsonErrorResponse(u"该设备不存在")
- order = get_user_not_complete_order(request.user, dev.owner)
- # 正常结果下的返回
- if not order:
- return JsonOkResponse()
- if order.status == order.Status.RUNNING:
- return JsonResponse({"result": ErrorCode.ORDER_RUNNING, "description": u"您有一笔正在进行的订单",
- "payload": {'ownerId': order.ownerId, "orderId": str(order.id)}})
- elif not order.isPaid:
- return JsonResponse({"result": ErrorCode.ORDER_NEED_PAY, "description": u"你有一笔尚未支付的订单,请先完成支付,然后在使用设备",
- "payload": {'ownerId': order.ownerId, "orderId": str(order.id)}})
- # elif order.is_waitPay():
- # return JsonResponse({"result": ErrorCode.ORDER_PAYING, "description": u"正在检查支付结果,请稍后",
- # "payload": {'ownerId': order.ownerId, "orderId": str(order.id)}})
- else:
- return JsonResponse({"result": "2", "description": u"系统错误,请您稍后重试"})
- @error_tolerate(nil = JsonErrorResponse("系统错误"), logger = logger)
- @permission_required(ROLE.myuser)
- def getCardBindUserStatus(request):
- user = request.user
- status = 1 if user.extra.get('campus_user_num', '') else 0
- return JsonResponse({"result": 1, "description": "", "payload": {"status": status}})
- @error_tolerate(nil = JsonErrorResponse("系统错误"), logger = logger)
- @permission_required(ROLE.myuser)
- def updateCardBindUserInfo(request):
- user = request.user
- jsonData = json.loads(request.body)
- phoneNumber = str(jsonData.get("phoneNumber", "").strip())
- code = jsonData.get("code", "")
- campus_user_num = str(jsonData.get('userNo').strip())
- userName = str(jsonData.get('userName').strip())
- from apps.web.eventer.caiyi import config_dic
- # 测试白名单
- test_card = serviceCache.get('yc-num-{}'.format(campus_user_num))
- if test_card:
- userName = 'test'
- campus_user_num = 'test001'
- logger.debug('yc_test_card,to reg card!!!')
- res = {'factoryFixId': '757996699'}
- else:
- # TODO 去服务器验证人员编号和手机号是否吻合
- yc = YuChuanApi(**config_dic)
- try:
- res = yc.sql_get_user_info(campus_user_num)
- user_phone = base64.encodestring(phoneNumber + '.00').strip()
- if res['mobilePhone'] != user_phone or res['userName'] != userName:
- return JsonErrorResponse(description = u'一卡通信息填写错误~,请您检查下哦')
- except Exception as e:
- return JsonErrorResponse(description = u'一卡通信息填写错误!!!,请您检查下哦')
- card_no = str(res.get('factoryFixId')).replace('L', '')
- if not card_no:
- raise UserServerException(u'一卡通信息填写错误!!')
- status, msg = userMobileVerifySMSProvider.verify(phoneNumber, code)
- if not status:
- return JsonErrorResponse(msg)
- dic = {
- "card_dealer": "宇川智能平台一卡通",
- "campus_user_num": campus_user_num,
- }
- card = Card.objects.filter(cardNo = card_no, cardType = 'YuChuanCard').first() or Card.objects.create(
- cardNo = card_no, agentId = user.agentId, phone = phoneNumber, remarks = '宇川一卡通',
- productAgentId = user.productAgentId, cardName = userName, attachParas = dic, cardType = 'YuChuanCard',
- nickName = user.nickname, openId = user.openId)
- if card.openId == card_no or card.openId != user.openId: # 判断是否为刷卡注册入库,或则换微信绑定
- card.openId = user.openId
- card.nickName = user.nickname
- card.phone = phoneNumber
- card.save()
- dic['card_no'] = card_no
- user.phoneNumber = phoneNumber
- user.extra = dic
- user.save()
- return JsonResponse({"result": 1, "description": "", "payload": {"status": 1}})
- @error_tolerate(logger = logger, nil = JsonErrorResponse(description = u"获取卡金额失败"))
- @permission_required(ROLE.myuser)
- def getRemoteCardBalance(request):
- """
- 获取远程充值卡的金额
- :param request:
- :return:
- """
- logicalCode = request.GET.get("logicalCode")
- dev = Device.get_dev_by_l(logicalCode)
- if not dev:
- return JsonErrorResponse(description = u"请先扫描设备")
- box = ActionDeviceBuilder.create_action_device(dev)
- if not hasattr(box, "get_remote_card_balance"):
- return JsonErrorResponse(description = u"当前设备暂不支持充值卡")
- try:
- result = box.get_remote_card_balance()
- except ServiceException as e:
- return JsonErrorResponse(description = e.message.get("description"))
- res = result.get("res")
- if res == "02":
- return JsonErrorResponse(description = u"请先将卡片置于设备上")
- # 这个地方将用户的信息塞入进去
- user = request.user
- result.update({
- "avatarUrl": user.avatar,
- "openId": user.openId
- })
- # 然后再次塞入设备信息
- result.update({
- "devNo": dev.devNo,
- "groupId": dev.groupId
- })
- packages = dev.get("washConfig", dict())
- newPackages = list()
- for _id, item in packages.items():
- switch = item.get("switch", True)
- if not switch:
- continue
- newPackages.append({
- "id": _id,
- "payAmount": item.get("price"),
- "coins": item.get("coins")
- })
- result.update({"packages": newPackages})
- return JsonOkResponse(payload = result)
- @error_tolerate(logger = logger, nil = JsonOkResponse())
- @permission_required(ROLE.myuser)
- def getUserDisclaimer(request):
- """
- 获取用户的免责声明
- 用户 用户进入系统第一次的时候需要阅读此协议并且 明确表示阅读 否则展示界面给用户
- :param request:
- :return:
- """
- productAgentId = request.user.productAgentId
- disclaimer = Agent.get_disclaimer(productAgentId)
- # 当用户阅读的声明版本与当前免责代理商的版本不一致 并且代理商的免责声明内容不为空的时候 前台需要展示免责声明
- payload = {
- "version": disclaimer.version,
- "content": disclaimer.content
- }
- if not disclaimer.content:
- payload = {}
- return JsonOkResponse(payload = payload)
- @error_tolerate(logger = logger, nil = JsonOkResponse())
- @permission_required(ROLE.myuser)
- def pauseUsingDevice(request):
- payload = json.loads(request.body)
- logicalCode = payload.get('logicalCode', '')
- if logicalCode == '':
- return JsonErrorResponse(description = u'参数错误(没有逻辑码)')
- port = payload.get('chargeIndex', '')
- if port == '':
- return JsonErrorResponse(description = u'参数错误(没有端口号)')
- dev = Device.get_dev_by_l(logicalCode)
- portCache = Device.get_dev_control_cache(dev['devNo'])[str(port)]
- if dev['devType']['code'] in ['1002121', '1002122']:
- if portCache.get('pausePort', False) is True:
- oper = '01'
- else:
- oper = '02'
- else:
- oper = '00'
- smartBox = ActionDeviceBuilder.create_action_device(dev)
- try:
- smartBox.pauseToUseDevice(port, oper)
- except Exception as e:
- return JsonErrorResponse(description = u'操作失败')
- return JsonOkResponse()
- @error_tolerate(logger = logger, nil = ErrorResponseRedirect(error = u'微信授权失败,请刷新后重试'))
- @permission_required(ROLE.myuser)
- def gatewayEntry(request):
- """
- 再发起支付之前 获取一次用户的 payOpenId 然后重定向到用户的支付详情页面 并直接访问payGateway
- :param request:
- :return:
- """
- def get_pay_gateway_redirect(pp, adLink):
- redirect = pp._request.GET.get("redirect")
- info = {
- 'params': pp._request.GET.get("params"),
- 'goodsInfo': json.dumps(pp.goodsInfo)
- }
- if adLink:
- info.update({'adLink': adLink})
- url = before_frag_add_query(redirect, info)
- logger.debug('redirect to client url is: {}'.format(url))
- return FrontEndResponseRedirect(url)
- def get_auth_redirect(pp, bridge, adLink):
- authCode = pp._request.GET.get(bridge.auth_code_key)
- if not authCode:
- redirect_uri = concat_server_end_url(
- uri = add_query('/user/pay/gatewayEntry', {
- 'params': pp._request.GET.get("params"),
- 'redirect': pp._request.GET.get("redirect")
- })
- )
- logger.debug('base scope auth url is:{}'.format(redirect_uri))
- return ExternalResponseRedirect(
- bridge.generate_auth_url_base_scope(
- redirect_uri = redirect_uri,
- payload = {}
- )
- )
- else:
- userPayOpenId = bridge.authorize(authCode)
- if not userPayOpenId:
- return ErrorResponseRedirect(error = u'微信授权失败,请刷新后重试')
- else:
- pp.curUser.set_bound_pay_openid(bridge.bound_openid_key, openId = userPayOpenId)
- pp.curUser.save()
- return get_pay_gateway_redirect(pp, adLink)
- def RCU_process(payParam):
- code = request.GET.get('code')
- if not code:
- redirect = payParam._request.GET.get("redirect")
- redirect_uri = concat_server_end_url(
- uri = add_query('/user/pay/gatewayEntry', {
- 'params': payParam._request.GET.get("params"),
- 'redirect': redirect
- })
- )
- url = add_query(pay_gateway.app.authCodeUrl, {'authCallBackUrl': redirect_uri})
- logger.debug('base scope auth url is:{}'.format(redirect_uri))
- return FrontEndResponseRedirect(url)
- else:
- redirect = payParam._request.GET.get("redirect")
- info = {
- 'params': payParam._request.GET.get("params"),
- 'code': code,
- 'goodsInfo': json.dumps(payParam.goodsInfo),
- }
- if adLink:
- info.update({'adLink': adLink})
- url = before_frag_add_query(redirect, info)
- logger.debug('redirect to client url is: {}'.format(url))
- return FrontEndResponseRedirect(url)
- payParam = PayParam(request)
- curUser = payParam.curUser
- pay_gateway = payParam.payGateway
- adLink = request.GET.get('adLink', None)
- # 首先判断登录的平台 只有微信扫码的需要获取其支付的openId
- if detect_wechat_client(request):
- if pay_gateway.pay_app_type == PayAppType.WECHAT:
- authBridge = WechatAuthBridge(pay_gateway.app)
- payOpenId = curUser.get_bound_pay_openid(authBridge.bound_openid_key)
- if payOpenId:
- return get_pay_gateway_redirect(payParam, adLink)
- else:
- return get_auth_redirect(payParam, authBridge, adLink)
- else:
- return JsonErrorResponse(description = u"平台配置错误,请稍后再试")
- # 支付宝平台登录
- elif detect_alipay_client(request):
- return get_pay_gateway_redirect(payParam, adLink)
- # 其他平台暂时不支持
- else:
- return NotSupportedPlatformResponseRedirect()
- @error_tolerate(logger = logger, nil = JsonErrorResponse(u"套餐获取失败"))
- @permission_required(ROLE.myuser)
- def getMonthlyPackage(request):
- """
- 获取包月的套餐
- :param request:
- :return:
- """
- devNo = Device.get_dev_no_from_request(request)
- cardNo = request.GET.get("cardNo")
- device = Device.get_dev(devNo)
- card = Card.objects.filter(cardNo = cardNo, openId = request.user.openId,
- productAgentId = request.user.productAgentId).first()
- if device:
- group = Group.get_dealer_group(dealerId = device.ownerId, id = device.groupId)
- elif card:
- group = Group.get_dealer_group(dealerId = card.dealerId, id = card.groupId)
- else:
- return JsonErrorResponse(description = u"获取套餐失败(1000),请刷新重试")
- if not group:
- return JsonErrorResponse(description = u"套餐获取失败(1001),请刷新重试")
- monthPackage = group.monthlyRule
- if not monthPackage:
- return JsonOkResponse()
- return JsonOkResponse(payload = {"dataList": [monthPackage.to_dict()]})
- @error_tolerate(nil = JsonErrorResponse(u"续费失败,请重新尝试"), logger = logger)
- @permission_required(ROLE.myuser)
- def checkVirtualCardRenew(request):
- """
- 检查当前的虚拟卡是否可以续费
- :param request:
- :return:
- """
- cardId = request.GET.get("cardId")
- if not cardId:
- return JsonErrorResponse(description = u"未找到相应虚拟卡,请重试")
- vCard = UserVirtualCard.objects.get(id = cardId)
- if not Group.check_virtual_card_number(groupId = vCard.groupId):
- return JsonErrorResponse(description = u"该地址虚拟卡数量已经达到上限,请联系发卡经销商")
- return JsonOkResponse()
- @error_tolerate(nil = JsonErrorResponse(u"获取失败,请重试"), logger = logger)
- @permission_required(ROLE.myuser)
- def getUserMonthlyPackage(request):
- """
- 获取用户的 包月套餐
- :param request:
- :return:
- """
- openId = request.user.openId
- monthlyPackages = MonthlyPackage.get_user_all(openId)
- dataList = [_package.to_dict() for _package in monthlyPackages]
- return JsonOkResponse(payload = {"dataList": dataList})
- @error_tolerate(nil = JsonErrorResponse(u"获取失败,请重试"), logger = logger)
- @permission_required(ROLE.myuser)
- def getMonthlyPackageUseDetail(request):
- """
- 获取 用户的使用详情
- :param request:
- :return:
- """
- monthlyPackageId = request.GET.get("monthlyPackageId")
- pageIndex = int(request.GET.get("pageIndex", 1))
- pageSize = int(request.GET.get("pageSize", 10))
- monthlyPackage = MonthlyPackage.objects.get(id = monthlyPackageId)
- useDetail = monthlyPackage.get_used_detail()
- # 获取使用的总的数量 添加上订单的ID 方便前台跳转
- total = len(useDetail)
- result = useDetail[pageSize * (pageIndex - 1): pageSize * pageIndex]
- orderNos = [_item.get("orderNo") for _item in result]
- consumeRecords = ConsumeRecord.objects.filter(openId = request.user.openId, orderNo__in = orderNos).only("openId",
- "orderNo",
- "id",
- "dateTimeAdded")
- dataList = [
- {"id": consume.id, "orderNo": consume.orderNo, "orderTime": consume.dateTimeAdded.strftime("%Y-%m-%d %H:%M:%S")}
- for consume in consumeRecords
- ]
- return JsonOkResponse(payload = {"total": total, "dataList": dataList})
- @error_tolerate(nil = JsonErrorResponse(u"获取失败,请重试"), logger = logger)
- @permission_required(ROLE.myuser)
- def supportPayment(request):
- def get_dealer(request):
- logicalCode = request.GET.get('logicalCode', None)
- if logicalCode:
- device = Device.get_dev_by_logicalCode(logicalCode)
- if not device:
- logger.info('can not find device. logicalCode={}'.format(logicalCode))
- return None
- else:
- return device.owner
- else:
- groupId = request.GET.get('groupId', None)
- if not groupId:
- logger.info('can not find group. groupId={}'.format(groupId))
- return None
- else:
- group = Group.get_group(groupId) # type: GroupDict
- if not group:
- logger.info('can not find group. groupId={}'.format(groupId))
- return None
- else:
- return group.owner
- dealer = get_dealer(request)
- if dealer is None:
- return JsonErrorResponse(description = u'该设备未注册,暂时无法使用支付宝或者微信支付, 请投币(1013)')
- return JsonOkResponse(description = u'无商户配置')
- @permission_required(ROLE.myuser)
- def getAlipayAd(request):
- """
- 领取红包福利任务
- :param request:
- :return:
- """
- try:
- user = request.user # type: MyUser
- logicalCode = request.GET.get('logicalCode', '')
- pageIndex = int(request.GET.get('pageIndex', 0))
- pageSize = int(request.GET.get('pageSize', 10))
- chargeIndex = request.GET.get('chargeIndex', '')
- dev = Device.get_dev_by_l(logicalCode) # Type:DeviceDict
- from apps.web.core.models import SystemSettings
- if user.gateway != AppPlatformType.ALIPAY:
- return JsonOkResponse(payload = {})
- if not dev:
- return JsonOkResponse(payload = {})
- if not Redpack.can_use(dealer = dev.owner, devTypeCode = dev.devTypeCode):
- return JsonOkResponse(payload = {})
- if not DevRegToAli.objects.filter(logicalCode = logicalCode).first():
- reg_result = DevRegToAli.reg_to_aliyun_v3(dev)
- if not reg_result:
- return JsonOkResponse()
- if 'disable_alipay_ruhui' in dev.owner.features:
- ruhui = {}
- elif SystemSettings.disable_alipay_ruhui():
- ruhui = {}
- else:
- # 判断是否为蓝牙. 蓝牙为老流程 串口充电桩为新流程
- if dev.channelType == DeviceChannelType.Channel_BT:
- showType = 'pop'
- else:
- # 1 确认显示方式
- showType = 'footerTopRedpack'
- group = dev.group
- if group.get('beforeCharge'):
- showType = 'pop'
- if 'show_pop_ruhui' in dev.owner.features:
- showType = 'pop'
- elif 'show_top_ruhui' in dev.owner.features:
- showType = 'top'
- elif 'show_buttun_ruhui' in dev.owner.features:
- showType = 'buttun'
- # 2 请求 请求权益 创建红报
- ruhui = RedpackBuilder.get_alipay_cpa_by_ruhui_v3(openId = user.openId, logicalCode = logicalCode,
- chargeIndex = chargeIndex, showType = showType)
- if ruhui:
- # 地址组启动强制充值, 后面的页面需要弹窗 比较复杂直接改为弹窗流程
- group = dev.group
- if group.get('beforeCharge'):
- ruhui = {'url': ruhui['url'], 'money': ruhui['money'], 'showType': ruhui['showType'],
- 'urlId': ruhui['urlId']}
- else:
- pass
- if 'disable_alipay_laxin' in dev.owner.features:
- laxin = {}
- elif SystemSettings.disable_alipay_laxin():
- laxin = {}
- else:
- # 拉新
- dataList = RedpackBuilder.get_alipay_cpa_by_laxin(openId = user.openId)
- total = len(dataList)
- if dataList:
- dataList = dataList[(pageIndex - 1) * pageSize: pageIndex * pageSize]
- laxin = {'dataList': dataList, 'total': total}
- return JsonOkResponse(payload = {'laxin': laxin, 'ruhui': ruhui})
- except Exception as e:
- logger.exception(e)
- return JsonOkResponse()
- @error_tolerate(u"获取权益失败", logger=logger)
- @permission_required(ROLE.myuser)
- def getAlipayAdResult(request):
- """
- 领取红包福利任务
- :param request:
- :return:
- """
- alipayOpenId = request.GET.get('alipayOpenId')
- taskId = request.GET.get('taskId')
- taskType = request.GET.get('taskType')
- openId = request.GET.get('alipayOpenId')
- logicalCode = request.GET.get('logicalCode')
- dev = Device.get_dev_by_logicalCode(logicalCode)
- # 拉新结果处理
- if taskId and alipayOpenId:
- if RedpackBuilder.query_cpa_laxin_task_status(taskId, alipayOpenId):
- redpack = RedpackBuilder.create_cpa_laxin_redpack(dev, taskId, openId, taskType)
- if redpack:
- return JsonOkResponse(payload={'showAmount': redpack.money.mongo_amount})
- # 入会结果处理
- redpackInfo = RedpackBuilder._pop_alipay_key(request.user.openId)
- if redpackInfo:
- showType = redpackInfo.get('showType')
- if showType == 'pop':
- return JsonOkResponse(payload={'showAmount': redpackInfo.get('money')})
- return JsonResponse({'payload': {}})
- @error_tolerate(u"获取权益失败", logger=logger)
- @permission_required(ROLE.myuser)
- def getMyRedpackList(request):
- user = request.user # type: MyUser
- pageIndex = int(request.GET.get('pageIndex', 0))
- pageSize = int(request.GET.get('pageSize', 10))
- dataList = Redpack.show_redpack(openId=user.openId)
- total = len(dataList)
- dataList = dataList[(pageIndex-1) * pageSize: pageIndex * pageSize]
- return JsonOkResponse(payload={'dataList':dataList, 'total':total})
- @error_tolerate(nil = JsonErrorResponse(description = u'显示用户信息错误'), logger = logger)
- @permission_required(ROLE.myuser)
- def getCurrentFeePara(request):
- devNo = request.GET.get('devNo', None)
- devObj = Device.objects.get(devNo = devNo)
-
- feeMode = devObj.otherConf.get('feeMode',{})
- timeRateList = []
- shiduan = feeMode.get('shiduan','000000000000000000000000000000000000000000000000')
- nowTime = datetime.datetime.now().strftime('%H:%M')
- curFeeIndex = 0
- for ii in range(48):
- startHour = 0 + ii/2
- startMin = '00' if ii%2==0 else '30'
- endHour = startHour if ii%2==0 else startHour + 1
- endMin = '30' if ii%2==0 else '00'
- startTime = '%02d:%s' % (startHour,startMin)
- endTime = '%02d:%s' % (endHour,endMin)
- timeRateList.append({'startTime':startTime,'endTime':endTime,'rate':shiduan[ii]})
- if nowTime >= startTime and nowTime <= endTime:
- curFeeIndex = shiduan[ii]
-
- result = {'top_price_rate':feeMode.get('jianFee',0),
- 'top_price_service_rate':feeMode.get('jianServe',0),
- 'peak_price_rate':feeMode.get('fengFee',0),
- 'peak_price_service_rate':feeMode.get('fengServe',0),
- 'normal_price_rate':feeMode.get('pingFee',0),
- 'normal_price_service_rate':feeMode.get('pingServe',0),
- 'valley_price_rate':feeMode.get('guFee',0),
- 'valley_price_service_rate':feeMode.get('guServe',0),
- 'jishunScale':feeMode.get('jishunScale',0),
- 'timeRateList':timeRateList,
- 'curFeeIndex':curFeeIndex}
-
- return JsonOkResponse( payload = result )
- @permission_required(ROLE.myuser)
- def getNearbyCarStation(request):
- # type: (WSGIRequest)->JsonResponse
- try:
- lng = float(request.GET.get('lng'))
- lat = float(request.GET.get('lat'))
- pageIndex = int(request.GET.get('pageIndex',1))
- pageSize = int(request.GET.get('pageSize',10))
- maxDistance = int(request.GET.get('distance', 5000))
- logger.debug('now location. lat = %s; lng = %s' % (lat, lng))
- if maxDistance > Const.NEAR_BY_MAX_DISTANCE:
- maxDistance = Const.NEAR_BY_MAX_DISTANCE
- if lng == 360 or lat == 360 or isnan(lng) or isnan(lat):
- return JsonResponse({'result': 0, 'description': u'定位失败,请打开位置权限,刷新后重试'})
- payload = getNearbyGroupsFromDB(lng, lat, pageIndex, pageSize, maxDistance, request.user.agentId,
- request.GET.get('chargeType', 0))
- return JsonResponse({'result': 1, 'description': '', 'payload': payload})
- except Exception as e:
- logger.exception(e)
- return JsonResponse({'result': 0, 'description': u'获取附近设备失败'})
- def getNearbyGroupsFromDB(lng, lat, pageIndex, pageSize, maxDistance, agentId, chargeType):
- def hav(theta):
- s = sin(theta / 2)
- return s * s
- def get_distance_hav(lat0, lng0, lat1, lng1):
- if lat1 == 360 or lng1 == 360:
- return -1
- EARTH_RADIUS = 6371000
- lat0 = radians(lat0)
- lat1 = radians(lat1)
- lng0 = radians(lng0)
- lng1 = radians(lng1)
- dlng = fabs(lng0 - lng1)
- dlat = fabs(lat0 - lat1)
- h = hav(dlat) + cos(lat0) * cos(lat1) * hav(dlng)
- return int(2 * EARTH_RADIUS * asin(sqrt(h)))
-
- if not agentId:
- logger.error('agent is null.')
- return {
- 'total': 0,
- 'items': []
- }
- dealers = Dealer.get_dealers(agentId)
- if not dealers:
- return {
- 'total': 0,
- 'items': []
- }
- queryDict = {
- 'ownerId': {'$in': dealers},
- 'StationStatus':50,# 站点状态必须是正常使用中的
- 'location': {
- '$near': {'$geometry': {'type': 'Point', 'coordinates': [lng, lat]},
- '$maxDistance': maxDistance}}}
-
- if chargeType != '0':
- queryDict.update({'chargeType':int(chargeType)})
-
- groups = SwapGroup.get_collection().find(queryDict)
-
- items = []
- for swapInfo in groups[(pageIndex - 1) * pageSize:pageIndex * pageSize]:
- groupId = swapInfo['groupId']
- group = Group.get_group(groupId)
- if group is None:
- continue
- swaplng = float(swapInfo['location']['coordinates'][0])
- swaplat = float(swapInfo['location']['coordinates'][1])
- distance = get_distance_hav(lat, lng, swaplat, swaplng)
- curFee = SwapGroup.get_cur_fee(swapInfo['PriceChargingInfo'])
- if curFee is None:
- continue
- # 统计交流、直流端口的情况
- statsDict = SwapGroup.get_stats(groupId)
- info = {
- 'lng': swaplng,
- 'lat': swaplat,
- 'Pictures':[{'IsCover':pic['IsCover'],'PicID':pic['PicID'],'Url':pic['Url'],'Title':pic['Title']} for pic in swapInfo.get('Pictures',[])],
- 'PriceChargingInfo':[{'FeeTime':info['FeeTime'],'ElectricityFee':info['ElectricityFee'],'ServiceFee':info['ServiceFee']} for info in swapInfo['PriceChargingInfo']],
- 'StationName':group['groupName'] if u'充电站' in group['groupName'] else u'%s充电站' % group['groupName'],
- 'Address':group['address'],
- 'Distance':distance,
- 'BusineHours':swapInfo['BusineHours'],
- 'acPortsSum':{'allPorts':statsDict['acAllPorts'],'usedPorts':statsDict['acUsedPorts'],'usePorts':statsDict['acUsePorts']},
- 'dcPortsSum':{'allPorts':statsDict['dcAllPorts'],'usedPorts':statsDict['dcUsedPorts'],'usePorts':statsDict['dcUsePorts']},
- 'exceptSum':{'offline':statsDict['offline'],'fault':statsDict['fault']},
- 'curFee':{"curElecFee": curFee['curElecFee'], "curServiceFee": curFee['curServiceFee']},
- 'ParkFee':swapInfo['ParkFee'],
- 'tagDescList':SwapGroup.get_tag_desc_list_for_dict(swapInfo)
- }
- items.append(info)
- payload = {
- 'total': groups.count(),
- 'items': items
- }
- return payload
- @error_tolerate(logger = logger)
- def refundOrderNotifier(request, pay_app_type):
- """
- 退款回调接口.
- 微信和京东聚合单独指定回调
- 支付宝支付和退款回调是一个
- :param request:
- :param pay_app_type:
- :return:
- """
- assert pay_app_type in PayAppType.choices(), 'not support this pay app type({})'.format(pay_app_type)
- notifier_cls = RefundManager().get_notifier(pay_app_type)
- response = notifier_cls(request, lambda filter: RefundMoneyRecord.get_record(**filter)).do(refund_post_pay)
- return response
- @error_tolerate(logger=logger)
- @permission_required(ROLE.myuser)
- def cancelWaitPay(request):
- """
- 后支付用户拉起支付后, 没有输入密码 点击恢复到end状态 用于再次支付
- """
- payload = json.loads(request.body)
- ownerId = payload.get('ownerId')
- consumeRecordId = payload.get('consumeRecordId')
- if not ownerId or not consumeRecordId:
- return JsonErrorResponse(description='参数缺失, 请刷新后重试..')
- order = ConsumeRecord.objects.filter(
- id=consumeRecordId,
- ownerId=ownerId
- ).first() # type: ConsumeRecord
- if not order:
- return JsonErrorResponse(description='没有找到该订单')
- try:
- if order.status == order.Status.WAIT_PAY and not order.isPaid:
- order.status = order.Status.END
- order.save()
- except Exception as e:
- logger.exception("[cancelWaitPay] error = {}".format(e))
- return JsonErrorResponse(description='参数错误')
- return JsonOkResponse(payload={})
- @permission_required(ROLE.myuser)
- def cancelRechargeRecord(request):
- """
- 用户取消订单
- """
- try:
- payload = json.loads(request.body)
- orderNo = payload.get('orderNo')
- record = RechargeRecord.objects(orderNo = orderNo).first() # type: RechargeRecord
- if not record:
- logger.warning('has no recharge record<orderNo={}>'.format(orderNo))
- else:
- record.cancel()
- except Exception as e:
- logger.exception(e)
- finally:
- return JsonOkResponse()
|